本文用于记录一些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
2sudo 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 指令(如
CMD、ENV、EXPOSE等),可以多次使用该选项添加多个指令 - 例如:
-c "EXPOSE 8080" -c "CMD ['nginx']"
- 在提交时为新镜像添加 Dockerfile 指令(如
-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
2docker images
# 会看到 myubuntu-nginx:1.0 这个新镜像基于新镜像创建容器:
1
2docker 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:限制容器使用的最大内存(如1g、512m)- 示例:
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-file、syslog等)