Docker——Docker使用笔记

本文用于记录一些Docker使用过程中的经验,最新添加的一些部分包含 AI 辅助创作


整体说明

  • Docker 是一个开源的容器化平台,可以让开发者将应用程序及其依赖项打包到一个可移植的容器中,然后发布到任何支持 Docker 的环境中
  • Docker 的核心基本概念
    • 镜像(Image) :包含运行应用所需的代码、库、环境变量和配置文件的模板,占用硬盘物理存储
    • 容器(Container) :镜像的运行实例 ,可以被创建、启动、停止、删除
      • 一个镜像可以启动多个容器,启动的容器会占用内存,就像一个虚拟系统
    • 仓库(Repository) :存储和分发 Docker 镜像的地方(如 Docker Hub)

Docker 常用命令

镜像(Image)相关 Docker 命令

  • 镜像相关 Docker 命令示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 搜索镜像
    docker search [镜像名]

    # 拉取镜像
    docker pull [镜像名]:[标签] # 不指定标签默认latest

    # 查看本地镜像
    docker images

    # 删除镜像
    docker rmi [镜像ID或镜像名]

容器(Container)相关 Docker 命令

  • 创建和启动容器

    1
    2
    3
    4
    5
    # 创建并启动容器,docker run = docker create + docker start
    docker run [选项] 镜像名 [命令]

    # 示例: 创建并启动一个nginx容器
    docker run -d -p 8080:80 --name mynginx nginx
    • 常用选项包括
      • -d: 后台运行
      • -p 主机端口:容器端口:端口映射
      • -v 主机目录:容器目录: 目录挂载,可多次使用 -v 参数挂在多个目录
      • --name 容器名:指定容器名称
      • -it:组合选项,-i 保持标准输入打开,-t 分配伪终端(终端交互模式)
      • 更多详细选项见附录
  • 容器相关常用操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 查看运行中的容器
    docker ps

    # 查看所有容器(包括停止的,刚启动的也算是停止的)
    docker ps -a

    # 创建容器,参数和 docker run 几乎一致
    docker create xxx

    # 启动/停止/重启容器
    docker start [容器ID/容器名]
    docker stop [容器ID/容器名]
    docker restart [容器ID/容器名]

    # 进入容器内部,不影响启动中的 docker 并与之交互
    docker exec -it [容器ID/容器名] /bin/bash

    # 删除容器
    docker rm [容器ID/容器名]

    # 查看容器日志
    docker logs [容器ID/容器名]

其他重要命令

  • 查看Docker系统信息

    1
    docker info
  • 清理无用的容器、镜像等

    1
    2
    # 清空所有悬空(dangling)镜像
    docker system prune

创建自定义镜像及构建

  • 创建 Dockerfile 文件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 基础镜像
    FROM ubuntu:20.04

    # 维护者信息
    MAINTAINER Your Name <your@email.com>

    # 安装依赖
    RUN apt-get update && apt-get install -y python3

    # 复制文件到容器
    COPY ./app /app

    # 工作目录
    WORKDIR /app

    # 暴露端口
    EXPOSE 8000

    # 容器启动命令
    CMD ["python3", "app.py"]
  • 基于上述的 dockerfile 文件构建镜像:

    1
    2
    # . 表示在当前目录下读取 dockerfile 文件以构建镜像
    docker build -t myapp:1.0 .
    • -t, --tag 指定标签
    • -f, --file 指定 Dockerfile 文件,默认在当前目录下搜索 Dockerfile 文件
    • 命令最后的这里的 . 表示 “当前工作目录”,即你在终端中执行 docker build 命令时所在的目录,也称为构建上下文
      • 这是指 Docker 引擎在构建镜像时可以访问的文件目录
      • 当执行 docker build 时,Docker 会将这个目录下的所有文件(除了 .dockerignore 中排除的文件)打包发送给 Docker 引擎,供 Dockerfile 中的指令(如 COPY、ADD)使用
      • 通常这个目录下包含一些配置文件或代码等必须的东西
  • 运行自定义镜像:

    1
    docker run -d -p 8000:8000 myapp:1.0

Docker 服务相关操作

  • 服务相关的常见操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 查看服务是否启动
    systemctl status docker

    # 启动Docker服务
    sudo systemctl start docker

    # 停止Docker服务
    sudo systemctl stop docker

    # 重启Docker服务
    sudo systemctl restart docker

    # 设置开机启动
    sudo systemctl enable docker
  • 在修改镜像源等操作后,经常还可能涉及到 docker 后台进程的重新加载,再重启 docker 服务,使得修改生效

    1
    2
    sudo systemctl daemon-reload
    sudo systemctl restart docker

高阶用法:多容器 Docker Compose

  • 对于多容器应用,可以使用 Docker Compose 管理:
    • 第一步:创建 docker-compose.yml 文件
    • 第二步:使用 docker-compose 命令启动所有服务
  • 详情待补充

高阶用法:修改镜像并提交

整体说明

  • Docker 中,提交(commit) 是指将容器的当前状态保存为一个新的镜像的操作
  • 当你对一个运行中的容器做了修改(比如安装了软件、配置了环境、添加了文件等),可以通过 docker commit 命令将这些修改固化为一个新的镜像 ,以便后续可以基于这个新镜像创建出具有相同状态的容器
  • 提交操作包含如下含义:
    • 保存容器的修改:当你在容器内做了一系列配置后,不需要重新编写 Dockerfile 就能将这些修改保存为新镜像
    • 快速创建自定义镜像:对于简单的环境定制,commit 比编写 Dockerfile 更快捷
    • 临时保存工作状态:可以作为开发过程中的临时快照

docker commit 命令的基本用法

  • 用法示例:

    1
    2
    3
    4
    5
    6
    7
    8
    # 用法模版
    docker commit [选项] 容器ID/容器名 新镜像名[:标签]

    # 提交容器时指定作者、描述信息,并添加暴露端口的指令
    docker commit -a "JoeZJH joezjh@gmail.com>" \
    -m "download and install Node.js" \
    -c "EXPOSE 3000" \
    mycontainer mynodeapp:1.0
  • 可用的选项(options)主要用于设置新镜像的元数据信息,常用选项如下:

    • -a--author
      • 指定新镜像的作者信息,格式通常为 姓名 <邮箱>
      • 例如:-a "JoeZJH <joezjh@gmail.com>"
    • -c--change
      • 在提交时为新镜像添加 Dockerfile 指令(如 CMDENVEXPOSE 等),可以多次使用该选项添加多个指令
      • 例如:-c "EXPOSE 8080" -c "CMD ['nginx']"
    • -m--message
      • 为本次提交添加描述信息(类似 Git 的 commit 消息)
      • 例如:-m "添加了 Python 环境和自定义配置"
    • -p--pause
      • 提交时是否暂停容器(默认值为 true,即自动暂停容器以保证数据一致性)
      • 若需在容器运行中提交,可指定 -p false,但可能导致数据不一致

完整示例

  • 第一步:先启动一个基础容器并进行修改:

    1
    2
    3
    4
    5
    6
    7
    8
    # 启动一个ubuntu容器并进入
    docker run -it --name myubuntu ubuntu:20.04 /bin/bash

    # 在容器内安装nginx(模拟修改操作)
    apt-get update && apt-get install -y nginx

    # 退出容器
    exit
  • 第二步:将修改后的容器提交为新镜像:

    1
    docker commit myubuntu myubuntu-nginx:1.0
  • 第三步:查看新创建的镜像:

    1
    2
    docker images
    # 会看到 myubuntu-nginx:1.0 这个新镜像
  • 基于新镜像创建容器:

    1
    2
    docker run -it myubuntu-nginx:1.0 /bin/bash
    # 此时容器内已经预装了nginx

docker commit 注意事项

  • docker commit 与 Dockerfile 的区别:
    • commit 是通过容器修改生成镜像(黑箱操作,不清楚具体做了哪些修改)
    • Dockerfile 是通过明文指令构建镜像(可追溯、可重复、易维护)
    • 推荐使用 Dockerfile 而非 docker commit 来管理镜像 ,尤其是在生产环境
  • 频繁 commit 会导致镜像体积增大(因为每次提交都会增加新的层,可能会包含不必要的临时文件或缓存)
  • 可以通过 -a(作者)和 -m(提交信息)选项添加元数据:
    1
    docker commit -a "Your Name" -m "Install nginx" myubuntu myubuntu-nginx:1.0

附录:docker run 选项详解

  • 注:可以通过 docker run --help 查看所有选项的完整说明

容器标识与命名

  • --name <容器名>:为容器指定一个自定义名称,而非随机生成
    • 示例:docker run --name myapp nginx
  • --hostname <主机名>:设置容器内的主机名(/etc/hostname
    • 示例:docker run --hostname container-host nginx
  • --network-alias <别名>:为容器在网络中设置别名(便于同一网络内的容器通过别名访问)

运行模式与交互

  • -d--detach:后台运行容器(守护进程模式),不占用终端
    • 示例:docker run -d nginx
  • -it:组合选项,-i 保持标准输入打开,-t 分配伪终端(终端交互模式)
    • 示例:docker run -it ubuntu /bin/bash(进入容器交互界面)
  • --rm:容器停止后自动删除(适合临时任务,避免残留容器)
    • 示例:docker run --rm -it alpine ping baidu.com

资源限制

  • --memory <内存大小>-m:限制容器使用的最大内存(如 1g512m
    • 示例:docker run -m 1g nginx
  • --cpus <核心数>:限制容器使用的 CPU 核心数(如 0.5 表示半核,2 表示双核)
    • 示例:docker run --cpus 2 redis
  • --gpus <参数>:分配 GPU 资源(需主机支持 NVIDIA Docker)
    • 示例:docker run --gpus all nvidia/cuda:11.0-base nvidia-smi(使用所有 GPU)

IPC 进程间通信设置

  • --ipc
    • IPC(Inter-Process Communication,进程间通信)设置
    • --ipc=host 表示容器将使用主机的 IPC 命名空间
    • 作用:允许容器内的进程与主机系统或其他共享相同 IPC 命名空间的容器进行通信,常用于需要共享内存的场景(如多进程训练)
  • --shm-size
    • shm/dev/shm 的缩写,即共享内存 tmpfs(临时文件系统),属于容器内进程间通信(IPC)的一部分,用于进程间快速共享数据
    • --shm-size=512m 设置容器内共享内存的大小为 512MB
    • 作用:某些应用(如 PyTorch 的数据加载器 DataLoader、数据库、浏览器等)会使用 /dev/shm 作为临时缓存或共享内存区域
    • 默认大小通常为容器内存的 1/2(但不超过 64MB),如果应用需要更大的共享内存空间,需手动指定(如 --shm-size=512m
      • 避免因默认共享内存不足导致的错误

端口映射

  • -p <主机端口>:<容器端口>--publish:将容器内的端口映射到主机端口,实现外部访问
    • 格式:[主机IP:]主机端口:容器端口(主机IP可选,默认绑定所有IP)
      • 示例:
        • docker run -p 8080:80 nginx(主机8080端口映射到容器80端口)
        • docker run -p 127.0.0.1:8080:80 nginx(仅本地可访问)
  • -P--publish-all:自动映射容器暴露的所有端口(随机映射到主机的高位端口)

数据持久化

  • -v <主机路径>:<容器路径>--volume:挂载主机目录或数据卷到容器,实现数据持久化
    • 格式:主机路径:容器路径[:权限](权限如 ro 表示只读)
    • 示例:
      • docker run -v /host/data:/container/data nginx(主机目录挂载)
      • docker run -v myvolume:/container/data nginx(数据卷挂载,myvolume 为卷名)
  • --mount:更灵活的挂载方式(支持更多参数,如 type=bind 绑定目录、type=volume 数据卷等)
    • 示例:docker run --mount type=bind,source=/host/data,target=/container/data nginx

环境变量与配置

  • -e <键=值>--env:设置容器内的环境变量
    • 示例:docker run -e "DB_HOST=localhost" -e "DB_PORT=3306" mysql
  • --env-file <文件路径>:从文件中读取环境变量(每行一个 键=值
    • 示例:docker run --env-file .env nginx.env 为环境变量文件)
  • --config <文件路径>:指定容器的配置文件(较少用)

网络配置

  • --network <网络名>:指定容器加入的网络(默认使用 bridge 网络)
    • 示例:docker run --network mynet nginx(加入自定义网络 mynet
  • --dns <DNS地址>:设置容器的 DNS 服务器
    • 示例:docker run --dns 8.8.8.8 --dns 8.8.4.4 ubuntu
  • --add-host <主机名:IP>:在容器的 /etc/hosts 中添加主机映射
    • 示例:docker run --add-host "test:192.168.1.100" ubuntu

容器生命周期与依赖

  • --restart <策略>:设置容器退出后的重启策略(常用于服务型容器)
    • 可选策略包括
      • no:不重启(默认)
      • always:总是重启
      • on-failure[:次数]:失败时重启(可指定最大次数)
      • unless-stopped:除非手动停止,否则总是重启
    • 示例:docker run --restart always nginx
  • --link <容器名:别名>:链接到另一个容器(已过时,推荐用网络替代)

其他常用选项

  • --entrypoint <命令>:覆盖容器的默认入口命令(ENTRYPOINT
    • 示例:docker run --entrypoint /bin/bash nginx(用 bash 替代默认的 nginx 启动命令)
  • -u <用户>--user:指定容器内的运行用户(避免以 root 运行)
    • 示例:docker run -u 1000:1000 ubuntu(用 UID 1000、GID 1000 的用户运行)
  • --log-driver <驱动>:设置容器日志的驱动(如 json-filesyslog 等)