Docker 是现代软件开发和部署的核心工具,特别是在深度学习领域。它能够解决"在我电脑上能运行"的经典问题,让你的深度学习环境在任何地方都能一致运行。本文将从零开始,详细介绍 Docker 的基础知识和实际应用。

一、Docker 基础概念

1. 什么是 Docker?

Docker 是一个开源的容器化平台,用于开发、发布和运行应用程序。

核心理念

  • 📦 打包:将应用及其依赖打包成一个标准单元
  • 🚀 运行:在任何支持 Docker 的环境中运行
  • 🔄 一致性:开发、测试、生产环境完全一致

2. 为什么需要 Docker?

传统问题

开发:Python 3.8 + CUDA 11.4 + PyTorch 1.9
测试:Python 3.9 + CUDA 11.8 + PyTorch 2.0
生产:Python 3.7 + CUDA 10.2 + PyTorch 1.8
结果:到处都是依赖问题!😱

Docker 解决方案

Docker 容器:
  ├── Python 3.8
  ├── CUDA 11.4
  ├── PyTorch 1.9
  ├── 所有依赖库
  └── 你的代码

在任何地方运行,效果完全一致!✅

3. Docker vs 虚拟机

虚拟机架构:                    Docker 架构:
┌─────────────┐                ┌─────────────┐
│   应用 A    │                │   应用 A    │
├─────────────┤                ├─────────────┤
│  Guest OS   │                │  依赖库     │
├─────────────┤                ├─────────────┤
│ Hypervisor  │                │   Docker    │
├─────────────┤                ├─────────────┤
│  Host OS    │                │  Host OS    │
├─────────────┤                ├─────────────┤
│  硬件       │                │  硬件       │
└─────────────┘                └─────────────┘
特性虚拟机Docker 容器
启动速度分钟级秒级
资源占用GB 级MB 级
性能损耗较大很小
隔离级别完全隔离进程级隔离
系统要求需要完整 OS共享宿主机内核

4. Docker 核心概念

Docker 生态系统:

┌──────────────┐
│ Dockerfile   │ → 定义如何构建镜像
└──────┬───────┘
       │ docker build
       ↓
┌──────────────┐
│   镜像       │ → 只读模板(类似"程序")
│   (Image)    │
└──────┬───────┘
       │ docker run
       ↓
┌──────────────┐
│   容器       │ → 运行中的实例(类似"进程")
│  (Container) │
└──────────────┘

四大核心概念

  1. 镜像(Image)

    • 只读模板,包含运行应用所需的一切
    • 类比:类(Class)、程序安装包
  2. 容器(Container)

    • 镜像的运行实例
    • 类比:对象(Object)、正在运行的程序
  3. 仓库(Registry)

    • 存储和分发镜像的地方
    • Docker Hub:官方公共仓库
  4. Dockerfile

    • 定义如何构建镜像的脚本
    • 类比:Makefile、配方

二、Docker 安装

1. Ubuntu/Debian 安装

# 更新包索引
sudo apt update

# 安装依赖
sudo apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 设置稳定版仓库
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

# 验证安装
sudo docker --version
sudo docker run hello-world

2. CentOS/RHEL 安装

# 安装依赖
sudo yum install -y yum-utils

# 添加 Docker 仓库
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

# 安装 Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io

# 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker

# 验证安装
sudo docker --version
sudo docker run hello-world

3. 配置非 root 用户使用 Docker

# 创建 docker 组
sudo groupadd docker

# 将当前用户添加到 docker 组
sudo usermod -aG docker $USER

# 刷新组成员(或重新登录)
newgrp docker

# 验证(不需要 sudo)
docker run hello-world

4. 配置 Docker 镜像加速

# 创建或编辑 daemon.json
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://registry.docker-cn.com"
  ]
}
EOF

# 重启 Docker
sudo systemctl daemon-reload
sudo systemctl restart docker

三、Docker 镜像操作

1. 搜索镜像

# 在 Docker Hub 搜索镜像
docker search ubuntu
docker search pytorch

# 在浏览器访问 Docker Hub
# https://hub.docker.com

2. 拉取镜像

# 拉取最新版本
docker pull ubuntu

# 拉取特定版本
docker pull ubuntu:20.04
docker pull python:3.8

# 拉取深度学习镜像
docker pull pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime
docker pull tensorflow/tensorflow:2.6.0-gpu

镜像命名规则

仓库名/镜像名:标签
registry/repository:tag

例如:
docker.io/ubuntu:20.04
pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime

3. 查看本地镜像

# 列出所有镜像
docker images

# 或
docker image ls

# 输出示例:
# REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
# ubuntu        20.04     1318b700e415   2 weeks ago    72.8MB
# pytorch       latest    a12b3c4d5e6f   1 month ago    5.18GB

4. 删除镜像

# 删除指定镜像
docker rmi ubuntu:20.04

# 或使用 IMAGE ID
docker rmi 1318b700e415

# 强制删除
docker rmi -f ubuntu:20.04

# 删除所有未使用的镜像
docker image prune

# 删除所有镜像(危险!)
docker rmi $(docker images -q)

5. 查看镜像详细信息

# 查看镜像详情
docker inspect ubuntu:20.04

# 查看镜像历史(构建层)
docker history ubuntu:20.04

四、Docker 容器操作

1. 运行容器

基本语法

docker run [选项] 镜像名 [命令]

基础示例

# 运行 Ubuntu 容器
docker run ubuntu:20.04

# 运行并进入交互式 shell
docker run -it ubuntu:20.04 /bin/bash

# 后台运行
docker run -d ubuntu:20.04 sleep 3600

# 指定容器名称
docker run --name my-ubuntu -it ubuntu:20.04 /bin/bash

# 运行并自动删除(退出后删除容器)
docker run --rm -it ubuntu:20.04 /bin/bash

常用选项

-i          # 交互模式(interactive)
-t          # 分配伪终端(tty)
-d          # 后台运行(detach)
--name      # 指定容器名称
--rm        # 退出后自动删除容器
-p          # 端口映射:-p 宿主机端口:容器端口
-v          # 挂载卷:-v 宿主机路径:容器路径
-e          # 设置环境变量
--gpus      # 使用 GPU

2. 查看容器

# 查看运行中的容器
docker ps

# 查看所有容器(包括已停止的)
docker ps -a

# 只显示容器 ID
docker ps -q

# 查看最近创建的容器
docker ps -l

# 输出示例:
# CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
# a1b2c3d4e5f6   ubuntu:20.04   "/bin/bash"   5 minutes ago   Up 5 minutes             my-ubuntu

3. 容器生命周期管理

# 启动已停止的容器
docker start container_name

# 停止运行中的容器
docker stop container_name

# 重启容器
docker restart container_name

# 暂停容器
docker pause container_name

# 恢复暂停的容器
docker unpause container_name

# 杀死容器(强制停止)
docker kill container_name

# 删除容器
docker rm container_name

# 强制删除运行中的容器
docker rm -f container_name

# 删除所有已停止的容器
docker container prune

# 删除所有容器(危险!)
docker rm -f $(docker ps -aq)

4. 进入运行中的容器

# 方法 1:exec(推荐)- 进入容器并执行命令
docker exec -it container_name /bin/bash

# 方法 2:attach - 附加到容器的主进程
docker attach container_name

# exec vs attach 的区别:
# exec:创建新进程,退出不会停止容器
# attach:附加到主进程,退出会停止容器

5. 容器与宿主机之间的文件传输

# 从容器复制到宿主机
docker cp container_name:/path/in/container /path/on/host

# 从宿主机复制到容器
docker cp /path/on/host container_name:/path/in/container

# 示例
docker cp my-container:/app/model.pth ./models/
docker cp ./data.txt my-container:/workspace/

6. 查看容器日志

# 查看容器日志
docker logs container_name

# 实时查看日志(类似 tail -f)
docker logs -f container_name

# 显示最后 100 行
docker logs --tail 100 container_name

# 显示时间戳
docker logs -t container_name

7. 查看容器资源使用

# 查看容器资源使用统计
docker stats

# 查看特定容器
docker stats container_name

# 只显示一次(不持续刷新)
docker stats --no-stream

五、端口映射和卷挂载

1. 端口映射(-p)

基本语法

docker run -p 宿主机端口:容器端口 镜像名

示例

# 映射单个端口
docker run -d -p 8080:80 nginx
# 访问 http://localhost:8080 → 容器的 80 端口

# 映射多个端口
docker run -d -p 8080:80 -p 8443:443 nginx

# 映射到随机端口
docker run -d -p 80 nginx
# 使用 docker ps 查看映射的端口

# 指定 IP
docker run -d -p 127.0.0.1:8080:80 nginx

# 查看端口映射
docker port container_name

深度学习应用示例

# Jupyter Notebook
docker run -d -p 8888:8888 pytorch/pytorch jupyter notebook --ip=0.0.0.0

# TensorBoard
docker run -d -p 6006:6006 tensorflow/tensorflow tensorboard --logdir=/logs

# Flask API
docker run -d -p 5000:5000 my-ml-api

2. 卷挂载(-v)

基本语法

docker run -v 宿主机路径:容器路径 镜像名

三种挂载方式

方式 1:绑定挂载(Bind Mount)
# 挂载宿主机目录
docker run -v /home/user/data:/data ubuntu

# 只读挂载
docker run -v /home/user/data:/data:ro ubuntu

# 挂载当前目录
docker run -v $(pwd):/workspace ubuntu
方式 2:命名卷(Named Volume)
# 创建命名卷
docker volume create my-volume

# 使用命名卷
docker run -v my-volume:/data ubuntu

# 查看所有卷
docker volume ls

# 删除卷
docker volume rm my-volume

# 删除未使用的卷
docker volume prune
方式 3:临时文件系统(tmpfs)
# 在内存中创建临时存储
docker run --tmpfs /tmp ubuntu

深度学习应用示例

# 挂载数据集
docker run -v /data/imagenet:/datasets/imagenet pytorch/pytorch

# 挂载代码目录
docker run -v $(pwd):/workspace -w /workspace pytorch/pytorch python train.py

# 挂载多个目录
docker run \
  -v /data:/data \
  -v $(pwd)/code:/code \
  -v $(pwd)/models:/models \
  pytorch/pytorch

六、Dockerfile 编写

1. Dockerfile 基础

Dockerfile 是定义如何构建 Docker 镜像的脚本文件。

基本结构

# 基础镜像
FROM base_image:tag

# 维护者信息
LABEL maintainer="your@email.com"

# 工作目录
WORKDIR /app

# 复制文件
COPY source destination

# 运行命令
RUN command

# 环境变量
ENV KEY=value

# 暴露端口
EXPOSE port

# 启动命令
CMD ["executable", "param1", "param2"]

2. Dockerfile 指令详解

FROM - 基础镜像
# 使用官方 Python 镜像
FROM python:3.8

# 使用 Ubuntu
FROM ubuntu:20.04

# 使用 PyTorch
FROM pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime

# 多阶段构建
FROM python:3.8 AS builder
WORKDIR - 工作目录
# 设置工作目录(如果不存在会自动创建)
WORKDIR /app

# 后续的 RUN、CMD、COPY 等命令都在此目录下执行
COPY - 复制文件
# 复制文件
COPY file.txt /app/

# 复制目录
COPY ./src /app/src

# 复制所有内容
COPY . /app/

# 使用通配符
COPY *.py /app/
ADD - 添加文件(功能比 COPY 强大)
# ADD 可以:
# 1. 自动解压缩 tar 文件
ADD archive.tar.gz /app/

# 2. 从 URL 下载
ADD https://example.com/file.tar.gz /app/

# 推荐:普通复制用 COPY,特殊需求用 ADD
RUN - 执行命令
# 安装软件包
RUN apt-get update && apt-get install -y \
    git \
    vim \
    wget

# 安装 Python 包
RUN pip install --no-cache-dir \
    numpy \
    pandas \
    torch

# 多行命令(推荐格式)
RUN apt-get update && \
    apt-get install -y python3 && \
    rm -rf /var/lib/apt/lists/*
ENV - 环境变量
# 设置环境变量
ENV PYTHONUNBUFFERED=1
ENV CUDA_HOME=/usr/local/cuda
ENV PATH=$CUDA_HOME/bin:$PATH

# 多个变量
ENV MODEL_DIR=/models \
    DATA_DIR=/data \
    OUTPUT_DIR=/outputs
EXPOSE - 暴露端口
# 声明容器监听的端口(仅声明,不实际映射)
EXPOSE 8080
EXPOSE 6006 8888
CMD - 默认命令
# exec 格式(推荐)
CMD ["python", "app.py"]

# shell 格式
CMD python app.py

# 注意:CMD 可以被 docker run 的命令覆盖
ENTRYPOINT - 入口点
# ENTRYPOINT 定义容器启动时执行的命令
ENTRYPOINT ["python"]

# 与 CMD 配合使用
ENTRYPOINT ["python"]
CMD ["app.py"]

# docker run 时可以覆盖 CMD,但不能覆盖 ENTRYPOINT
ARG - 构建参数
# 定义构建时的参数
ARG PYTHON_VERSION=3.8
FROM python:${PYTHON_VERSION}

ARG MODEL_NAME
RUN echo "Building for model: ${MODEL_NAME}"

# 使用:docker build --build-arg PYTHON_VERSION=3.9 .

3. 深度学习 Dockerfile 示例

示例 1:基础 PyTorch 环境
# Dockerfile
FROM pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime

# 设置工作目录
WORKDIR /workspace

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    git \
    vim \
    wget \
    && rm -rf /var/lib/apt/lists/*

# 安装 Python 包
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 复制代码
COPY . .

# 设置环境变量
ENV PYTHONUNBUFFERED=1

# 暴露端口
EXPOSE 8888 6006

# 默认启动 Jupyter
CMD ["jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]

requirements.txt

numpy==1.21.0
pandas==1.3.0
matplotlib==3.4.2
scikit-learn==0.24.2
tensorboard==2.6.0
示例 2:完整训练环境
FROM nvidia/cuda:11.4.0-cudnn8-devel-ubuntu20.04

# 避免交互式提示
ENV DEBIAN_FRONTEND=noninteractive

# 安装 Python 和基础工具
RUN apt-get update && apt-get install -y \
    python3.8 \
    python3-pip \
    git \
    vim \
    wget \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 创建软链接
RUN ln -s /usr/bin/python3 /usr/bin/python

# 升级 pip
RUN pip install --upgrade pip

# 安装深度学习框架
RUN pip install --no-cache-dir \
    torch==1.9.0+cu111 \
    torchvision==0.10.0+cu111 \
    -f https://download.pytorch.org/whl/torch_stable.html

# 安装其他依赖
RUN pip install --no-cache-dir \
    numpy \
    pandas \
    matplotlib \
    scikit-learn \
    tensorboard \
    opencv-python \
    albumentations \
    timm

# 设置工作目录
WORKDIR /workspace

# 复制项目文件
COPY . /workspace/

# 设置环境变量
ENV PYTHONUNBUFFERED=1 \
    CUDA_HOME=/usr/local/cuda \
    PATH=/usr/local/cuda/bin:$PATH \
    LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

# 暴露端口
EXPOSE 8888 6006

# 启动命令
CMD ["/bin/bash"]
示例 3:多阶段构建(优化镜像大小)
# 第一阶段:构建
FROM python:3.8 AS builder

WORKDIR /build

# 安装构建依赖
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# 第二阶段:运行
FROM python:3.8-slim

WORKDIR /app

# 从构建阶段复制安装的包
COPY --from=builder /root/.local /root/.local

# 复制应用代码
COPY . .

# 设置 PATH
ENV PATH=/root/.local/bin:$PATH

CMD ["python", "app.py"]

4. 构建镜像

# 基本构建
docker build -t my-image:tag .

# 指定 Dockerfile
docker build -f Dockerfile.dev -t my-image:dev .

# 使用构建参数
docker build --build-arg PYTHON_VERSION=3.9 -t my-image .

# 不使用缓存
docker build --no-cache -t my-image .

# 查看构建过程
docker build -t my-image . --progress=plain

示例

# 构建深度学习镜像
docker build -t my-pytorch:latest .

# 运行
docker run --gpus all -it -v $(pwd):/workspace my-pytorch:latest

七、GPU 支持配置

1. 安装 NVIDIA Docker

# 添加仓库
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

# 安装 nvidia-docker2
sudo apt-get update
sudo apt-get install -y nvidia-docker2

# 重启 Docker
sudo systemctl restart docker

# 验证
docker run --rm --gpus all nvidia/cuda:11.4.0-base nvidia-smi

2. 使用 GPU

# 使用所有 GPU
docker run --gpus all pytorch/pytorch

# 使用特定 GPU
docker run --gpus '"device=0"' pytorch/pytorch

# 使用多个 GPU
docker run --gpus '"device=0,1"' pytorch/pytorch

# 使用指定数量的 GPU
docker run --gpus 2 pytorch/pytorch

3. GPU 训练示例

# 运行训练脚本
docker run --gpus all \
  -v $(pwd):/workspace \
  -v /data:/data \
  -w /workspace \
  --name my-training \
  pytorch/pytorch:1.9.0-cuda11.1-cudnn8-runtime \
  python train.py --gpu 0 --epochs 100

八、Docker Compose(多容器管理)

1. 什么是 Docker Compose?

Docker Compose 用于定义和运行多容器 Docker 应用。

安装

# Ubuntu
sudo apt install docker-compose

# 或使用 pip
pip install docker-compose

# 验证
docker-compose --version

2. docker-compose.yml 示例

示例 1:Jupyter + TensorBoard
# docker-compose.yml
version: '3.8'

services:
  jupyter:
    image: pytorch/pytorch:latest
    ports:
      - "8888:8888"
    volumes:
      - ./notebooks:/workspace
      - ./data:/data
    command: jupyter notebook --ip=0.0.0.0 --allow-root
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: all
              capabilities: [gpu]

  tensorboard:
    image: tensorflow/tensorflow:latest
    ports:
      - "6006:6006"
    volumes:
      - ./logs:/logs
    command: tensorboard --logdir=/logs --host=0.0.0.0

使用

# 启动所有服务
docker-compose up

# 后台启动
docker-compose up -d

# 停止
docker-compose down

# 查看日志
docker-compose logs -f
示例 2:训练 + 数据库 + API
version: '3.8'

services:
  # 训练服务
  trainer:
    build: ./trainer
    volumes:
      - ./data:/data
      - ./models:/models
    environment:
      - CUDA_VISIBLE_DEVICES=0
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]

  # 数据库
  postgres:
    image: postgres:13
    environment:
      POSTGRES_DB: mlops
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  # API 服务
  api:
    build: ./api
    ports:
      - "5000:5000"
    depends_on:
      - postgres
    environment:
      DATABASE_URL: postgresql://user:password@postgres:5432/mlops

volumes:
  postgres_data:

九、实用技巧和最佳实践

1. 减小镜像大小

# ❌ 不好
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y python3
RUN apt-get install -y pip

# ✅ 好:合并 RUN 命令
FROM ubuntu:20.04
RUN apt-get update && \
    apt-get install -y python3 pip && \
    rm -rf /var/lib/apt/lists/*

# ✅ 更好:使用更小的基础镜像
FROM python:3.8-slim

2. 使用 .dockerignore

# .dockerignore
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
*.so
*.egg
*.egg-info/
dist/
build/
.git/
.gitignore
README.md
.DS_Store
.vscode/
.idea/
*.swp
*.swo
data/
outputs/
logs/
checkpoints/
*.pth
*.pt

3. 清理 Docker 资源

# 删除停止的容器
docker container prune

# 删除未使用的镜像
docker image prune

# 删除未使用的卷
docker volume prune

# 删除所有未使用的资源
docker system prune

# 删除所有资源(包括未使用的镜像)
docker system prune -a

# 查看 Docker 占用的空间
docker system df

4. 查看容器内部

# 进入容器
docker exec -it container_name /bin/bash

# 查看容器进程
docker top container_name

# 查看容器详细信息
docker inspect container_name

# 查看容器文件系统变化
docker diff container_
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐