Docker 基础:镜像拉取、代码执行、常见问题与代理配置

Docker 基础笔记:拉取、执行与常见配置/问题

1. Docker 拉取与执行流程

核心概念: 使用预先配置好的环境(镜像)来运行代码。

基本流程:

  1. 拉取镜像 (docker pull): 从 Docker Hub 等仓库下载一个包含操作系统、运行时和依赖的环境模板。
    # 示例:拉取轻量级 Python 3.9 镜像
    docker pull python:3.9-slim
    
  2. 运行容器 (docker run): 基于镜像创建一个可运行的实例(容器)。
    • 交互式运行 (进入容器 Shell):
      # -it: 交互式终端, --rm: 容器退出后自动删除, bash: 在容器内执行的命令
      docker run -it --rm python:3.9-slim bash
      
      进入容器后,可执行命令如 python --version,用 exit 退出。
    • 运行本地代码: 需将本地目录挂载到容器内。
      # 创建本地脚本 hello.py
      # echo "print('Hello from my local script!')" > hello.py
      
      # -v $(pwd):/app: 将当前目录挂载到容器的 /app 目录
      # -w /app: 设置容器内的工作目录为 /app
      docker run -it --rm -v $(pwd):/app -w /app python:3.9-slim python hello.py
      
  3. 代码执行:
    • 运行镜像内置的程序。
    • 运行通过卷挂载进来的本地代码。

关键术语:

  • 镜像 (Image): 只读模板,定义了环境。
  • 容器 (Container): 镜像的运行实例。
  • 卷 (Volume): -v 参数,用于主机与容器间共享目录/数据。
  • 端口映射 (Port Mapping): -p 参数,将容器端口暴露给主机(例如 -p 8080:80)。

为什么使用 Docker?

  • 环境一致性: 保证开发、测试、生产环境相同。
  • 快速部署: 无需手动配置依赖。
  • 隔离性: 应用运行在独立环境中,不影响主机。

2. 故障排除:Permission Denied (docker.sock)

错误信息示例:
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock...

原因: 当前用户无权访问 Docker 守护进程。

解决方法:

  1. 使用 sudo (临时):
    sudo docker pull python:3.9-slim
    
  2. 将用户加入 docker 组 (推荐, 永久):
    # 1. 将当前用户添加到 docker 组
    sudo usermod -aG docker $USER
    # 2. 重新登录或重启使组生效 (或临时用 newgrp docker)
    # 3. 验证 (无需 sudo)
    docker ps
    

3. 故障排除: “executable file not found” (例如 zsh)

错误信息示例:
OCI runtime create failed: ...: exec: "zsh": executable file not found in $PATH: unknown

原因: 容器镜像(特别是 slimalpine 版)未安装该命令。

解决方法:

  1. 使用镜像自带命令: 如 bashsh
    sudo docker run -it --rm python:3.9-slim bash
    
  2. 使用功能更全的镜像: 如标准版 python:3.9
    sudo docker run -it --rm python:3.9 bash
    
  3. 构建自定义镜像: 使用 Dockerfile 添加所需工具。
    # Dockerfile
    FROM python:3.9-slim
    RUN apt-get update && apt-get install -y zsh && rm -rf /var/lib/apt/lists/*
    
    # 构建并运行
    sudo docker build -t my-python-with-zsh .
    sudo docker run -it --rm my-python-with-zsh zsh
    

4. 配置容器网络代理

场景: 容器内应用(如 pip, apt-get, curl)需要通过主机上运行的代理服务器访问外部网络。

问题: 直接在容器内使用 127.0.0.1:<proxy_port> 会失败 (Connection refused),因为容器网络隔离,127.0.0.1 指向容器自身而非主机。

解决方案: 使用特殊 DNS 名 host.docker.internal 指向主机,并设置代理环境变量。

命令示例 (假设主机代理在 7897 端口):

sudo docker run -it --rm \
  --add-host=host.docker.internal:host-gateway \
  -e HTTP_PROXY=http://host.docker.internal:7897 \
  -e HTTPS_PROXY=http://host.docker.internal:7897 \
  -e NO_PROXY=localhost,127.0.0.1 \
  python:3.9-slim bash

关键参数解释:

  • --add-host=host.docker.internal:host-gateway:
    • 重要: 在 Linux Docker 环境中,此参数将 host.docker.internal 映射到主机的网关 IP,使其可用。
    • Docker Desktop (Mac/Windows) 通常内置此映射,此参数可确保跨平台兼容性。
  • -e HTTP_PROXY=http://host.docker.internal:7897: 设置 HTTP 代理环境变量,指向主机代理。
  • -e HTTPS_PROXY=http://host.docker.internal:7897: 设置 HTTPS 代理环境变量。
  • -e NO_PROXY=localhost,127.0.0.1: 指定哪些地址不走代理(例如容器内部通信)。

验证:

在容器内运行需要联网的命令,如:

pip install requests
curl https://ifconfig.me # 应显示代理服务器 IP

持久化配置:

可以将 ENV 指令添加到 Dockerfile 中,以便构建的镜像默认带有代理配置(注意 host.docker.internal 需要在 docker run 时通过 --add-host 才能在 Linux 上正确解析)。

FROM python:3.9-slim
ENV HTTP_PROXY=http://host.docker.internal:7897
ENV HTTPS_PROXY=http://host.docker.internal:7897
ENV NO_PROXY=localhost,127.0.0.1
# ... 其他指令 ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值