跳至内容

Docker 常用命令

镜像、容器、网络与数据卷的常用操作速查。

  • Docker
  • 容器
  • 命令行

【…】 为待替换参数,【容器】 可填容器名或 ID,【镜像:标签】 例如 nginx:alpine。各条命令按需使用,路径或参数含空格时加引号。

1. 环境与连接

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
docker version                                 # 客户端与服务端版本
docker info                                    # Docker Engine 配置、资源和存储信息
docker context ls                              # 已配置的连接环境
docker context show                            # 当前 context 名称
docker context use 【context名】                # 切换默认连接环境
docker compose version                         # Compose 版本
docker run --help                              # 查看某条命令的参数

# 仅本次连接指定环境,查询容器
docker --context 【context名】 ps

docker context ls 输出示例,* 表示当前连接环境:

运行结果 Text
1
2
3
# NAME        DESCRIPTION                               DOCKER ENDPOINT
# default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
# dev         Development server                        ssh://user@dev.example.com

2. 镜像查询与拉取

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
docker images                                # 本地镜像,等同于 docker image ls
docker images --digests                      # 同时显示镜像摘要
docker search 【关键词】                       # 搜索 Docker Hub,不是搜索本地镜像
docker pull 【镜像:标签】                      # 拉取指定镜像
docker image inspect 【镜像:标签】             # 镜像配置、架构等详情
docker history 【镜像:标签】                   # 镜像各层的历史信息

# 按仓库名和标签筛选本地镜像
docker images --filter 'reference=nginx:*'
# 用摘要指定镜像内容
docker pull 【镜像仓库】@sha256:【摘要】

docker images 输出示例:

运行结果 Text
1
2
3
# REPOSITORY   TAG      IMAGE ID       CREATED      SIZE
# nginx        alpine   a1b2c3d4e5f6   5 days ago   52MB
# demo-web     1.0      b2c3d4e5f6a7   2 hours ago  53MB

省略标签时默认使用 latest,但它不保证是最新版本。pull 只下载镜像;更新已有容器需要用新镜像重建。

3. 创建并运行容器

代码块 Shell
1
2
3
4
5
# 基本形式:Docker 参数在镜像之前,容器内命令及参数在镜像之后
docker run 【Docker参数】 【镜像:标签】 【容器内命令及参数】

# 新建临时容器并进入 Shell,退出后自动删除
docker run --rm -it alpine:3 sh

示例:用 Nginx 运行一个静态站点。 在连接本机 Docker 的 Bash / Zsh 终端中,进入一个空目录执行;容器名 web、网络名 app-net 和端口 8080 需未被占用。

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 准备页面和容器网络
mkdir html
printf '%s\n' '<h1>Hello Docker</h1>' > html/index.html
docker network create app-net

docker run -d \
  --name web \
  --restart unless-stopped \
  --network app-net \
  -p 127.0.0.1:8080:80 \
  -v "$PWD/html:/usr/share/nginx/html:ro" \
  --cpus=1 \
  --memory=256m \
  nginx:alpine

打开 http://127.0.0.1:8080,应看到 Hello Docker。网页文件保存在当前目录的 html 中,容器只读访问;修改 html/index.html 后刷新页面即可看到变化。行末 \ 用于续行,后面不要再加空格或注释。

参数含义
-d后台运行
--name web指定容器名,不能与已有容器重名
--restart unless-stopped自动重启;手工停止后保持停止,包括 Docker 重启后
--network app-net加入已创建的 app-net 网络
-p 127.0.0.1:8080:80将本机 TCP 8080 端口映射到容器 80 端口
-v 主机路径:容器路径:ro挂载目录,ro 表示容器只读
--cpus=1 / --memory=256mCPU / 内存上限
-i / -t保持标准输入打开 / 分配伪终端,交互式 Shell 常组合为 -it
--rm容器退出时删除容器及其匿名卷,保留命名卷
-e KEY=value / --env-file .env传入环境变量 / 从文件读取环境变量
-w /app指定容器内工作目录

run 新建容器,start 启动已有容器。 主进程退出后容器会停止,-d 不改变这一点;--rm 与 --restart 不能同时使用。

4. 容器列表与启停

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
docker ps                                      # 运行中的容器
docker ps -a                                   # 所有容器,包含已停止的
docker ps -q                                   # 只输出运行中容器的 ID
docker ps -a --filter status=exited            # 筛选已退出容器
docker ps --filter name=web                    # 按名称匹配,可能匹配多个容器
docker start 【容器】                           # 启动已有的停止状态容器
docker stop --timeout 30 【容器】               # 请求停止,最多等待 30 秒后强制结束
docker restart 【容器】                         # 重启已有容器
docker rename 【容器】 【新名称】                 # 修改容器名
docker pause 【容器】                           # 暂停容器进程
docker unpause 【容器】                         # 恢复容器进程

只保留名称、镜像和状态列,便于查看:

代码块 Shell
1
docker ps -a --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
运行结果 Text
1
2
3
4
# NAMES   IMAGE          STATUS
# web     nginx:alpine   Up 5 minutes
# job     alpine:3       Exited (0) 2 minutes ago
# api     demo-api:1.0   Restarting (1) 10 seconds ago

Up 表示运行中;Exited (0) 表示正常退出;Restarting (1) 表示以退出码 1 结束后正在重启,需查看日志。

start 和 restart 沿用容器原配置,不会换镜像或修改端口映射。

5. 容器日志

代码块 Shell
1
2
3
4
5
6
7
8
docker logs 【容器】                           # 已保留的容器日志
docker logs --tail 100 【容器】                # 最后 100 行
docker logs -f --tail 100 【容器】             # 持续跟踪,Ctrl+C 结束查看
docker logs --since 10m 【容器】               # 最近 10 分钟
docker logs --timestamps 【容器】              # 增加时间戳

# 合并标准输出与标准错误,再筛选关键词
docker logs --since 1h 【容器】 2>&1 | grep -F '【关键词】'

Nginx 配置错误的日志示例:

运行结果 Text
1
# nginx: [emerg] unknown directive "invalid_directive" in /etc/nginx/nginx.conf:12

logs 查看容器的标准输出和标准错误,不会自动读取应用的日志文件。Ctrl+C 只结束日志跟踪,不停止容器。

6. 进入容器与复制文件

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
docker exec -it 【容器】 sh                     # 在运行中的容器里启动交互式 Shell
docker exec -it 【容器】 bash                   # 镜像中安装了 Bash 时可用
docker exec 【容器】 【命令及参数】               # 执行单条命令
docker exec -u root -it 【容器】 sh             # 以容器内 root 身份执行

# 管道由容器内的 Shell 解释,单引号避免本地 Shell 提前处理
docker exec 【容器】 sh -c 'ls /etc | head -n 5'
# 本机 → 容器
docker cp 【本地文件】 【容器】:【容器路径】
# 容器 → 本机
docker cp 【容器】:【容器文件】 【本地路径】

exec 要求容器正在运行,且镜像中有对应程序。cp 也可操作已停止的容器,目标父目录需存在,可能覆盖同名文件。

attach 与 exec 的区别:

代码块 Shell
1
docker attach 【容器】                         # 连接已有主进程的输入、输出和错误流

exec 新开进程,attach 连接已有主进程;在 attach 中按 Ctrl+C 可能使容器停止。以 -it 启动的容器可依次按 Ctrl+P、Ctrl+Q 分离。

7. 详情与资源用量

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
docker inspect 【容器】                         # 完整配置和状态,默认 JSON
docker top 【容器】                             # 容器中的进程
docker stats                                   # 持续显示运行中容器的资源用量
docker stats --no-stream 【容器】               # 只采样一次

# 主进程状态、退出码、是否被 OOM 杀死
docker inspect --format '{{.State.Status}} {{.State.ExitCode}} {{.State.OOMKilled}}' 【容器】
# 挂载信息、端口映射、重启策略
docker inspect --format '{{json .Mounts}}' 【容器】
docker inspect --format '{{json .NetworkSettings.Ports}}' 【容器】
docker inspect --format '{{json .HostConfig.RestartPolicy}}' 【容器】
# 修改已有容器的重启策略
docker update --restart unless-stopped 【容器】

状态查询的输出示例:

运行结果 Text
1
# exited 137 true

三项依次是状态、退出码和 OOM(内存不足)标记。这里 OOMKilled=true;仅凭退出码 137 不能断定内存不足。

资源用量输出示例(节选):

运行结果 Text
1
2
# NAME   CPU %   MEM USAGE / LIMIT   MEM %   NET I/O         BLOCK I/O
# web    0.25%   18MiB / 256MiB      7.03%   2.4MB / 1.1MB   0B / 8.2kB

MEM USAGE / LIMIT 是内存用量 / 上限;NET I/O 是累计接收 / 发送量,BLOCK I/O 是累计读取 / 写入量,不是每秒速率。

8. 端口与网络

代码块 Shell
1
2
3
4
5
6
7
8
9
docker port 【容器】                           # 已发布的端口映射
docker network ls                             # 网络列表
docker network inspect 【网络名】               # 网络配置及连接的容器
docker network create 【网络名】                # 默认创建自定义 bridge 网络
docker network connect 【网络名】 【容器】        # 将已有容器接入网络
docker network disconnect 【网络名】 【容器】     # 断开连接,会影响通信

# 新建容器时指定已存在的网络
docker run -d --name 【容器名】 --network 【网络名】 【镜像:标签】

对第 3 节的 web 执行 docker port web,输出示例:

运行结果 Text
1
# 80/tcp -> 127.0.0.1:8080

-p 左边是主机端口,右边是容器端口。 -p 8080:80 默认发布到主机所有地址;加 127.0.0.1 则绑定回环地址。镜像中的 EXPOSE 不会自动发布端口。

同一自定义 bridge 网络中的容器可以通过容器名解析地址,默认 bridge 网络不提供同样的自动解析。

api 和 db 都接入 app-net 后,api 可通过 db:3306 访问监听 3306 端口的数据库,不需要额外设置 -p。

9. 数据卷与目录挂载

代码块 Shell
1
2
3
4
5
6
7
8
docker volume ls                              # 数据卷列表
docker volume create 【卷名】                  # 创建命名卷
docker volume inspect 【卷名】                 # 驱动、挂载位置等信息

# 使用命名卷,Docker 管理实际存储位置
docker run -d --name 【容器名】 --mount type=volume,src=【卷名】,dst=/data 【镜像:标签】
# 绑定主机目录,只读挂入容器;源目录需预先存在
docker run -d --name 【容器名】 --mount type=bind,src=【主机绝对路径】,dst=/data,readonly 【镜像:标签】
写法类型与用途
-v app-data:/data命名卷,适合让数据独立于容器保留
-v /srv/app/data:/data绑定主机目录,直接使用指定路径下的文件
-v /srv/app/config:/config:ro只读绑定,容器不能通过这个挂载修改源文件
-v /data匿名卷,Docker 自动分配名称,后续复用时不如命名卷直观

绑定挂载的源路径不存在时,--mount 默认报错,-v 会自动创建目录。

删除容器不删除命名卷。 需要保留的数据应写入挂载目录;仅写在容器可写层中的文件会随容器删除。

10. 构建、标记与推送镜像

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 在项目目录执行,默认读取当前目录的 Dockerfile
docker build -t 【镜像名】:【标签】 .
# 指定 Dockerfile,最后的点仍表示当前目录作为构建上下文
docker build -f 【Dockerfile路径】 -t 【镜像名】:【标签】 .
# 尝试更新基础镜像,并且不复用构建缓存
docker build --pull --no-cache -t 【镜像名】:【标签】 .

# 为同一镜像增加一个远程仓库标签
docker tag 【本地镜像:标签】 【仓库地址】/【命名空间】/【镜像名】:【标签】
docker login 【仓库地址】                      # 按提示完成认证
docker push 【仓库地址】/【命名空间】/【镜像名】:【标签】
docker logout 【仓库地址】                     # 移除本地保存的登录凭据

build 最后的路径是构建上下文,Dockerfile 用 -f 指定。 --no-cache 不会更新基础镜像,需要时加 --pull。

仓库地址不带 https://。推送 Docker Hub 时用 【用户名】/【镜像名】:【标签】,登录时省略仓库地址。

指定 linux/amd64 平台并载入本地镜像库,需构建器支持该平台或模拟运行:

代码块 Shell
1
docker buildx build --platform linux/amd64 --load -t 【镜像名】:【标签】 .

11. 镜像归档与容器导出

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 镜像 → tar 文件;把文件复制到另一台机器后,用 load 恢复
docker save -o 【镜像归档.tar】 【镜像:标签】
docker load -i 【镜像归档.tar】

# 容器文件系统 → tar 文件;import 从文件系统归档创建新镜像
docker export -o 【文件系统.tar】 【容器】
docker import 【文件系统.tar】 【新镜像:标签】

# 将容器文件改动保存为新镜像,适合临时留存调试现场
docker commit 【容器】 【新镜像:标签】

docker load 输出示例:

运行结果 Text
1
# Loaded image: demo-web:1.0
需求命令与保留内容
离线搬运镜像save / load,保存并恢复镜像层、配置和标签
导出容器文件系统export / import,得到文件系统快照;不保留原镜像的分层历史和完整运行配置
临时保存容器改动commit,生成新镜像;可复现的构建仍应写入 Dockerfile

以上命令都不备份挂载卷的数据。 save 也不包含容器运行后写入可写层的文件。

12. Docker Compose

在含有 compose.yaml 的项目目录执行。【服务名】 取自配置中的 services,不一定等于容器名。

代码块 Shell
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
docker compose config                         # 解析、合并配置,检查格式
docker compose config --services              # 列出服务名
docker compose up -d                          # 创建或更新服务,后台运行
docker compose up -d --build                  # 先构建镜像,再启动或更新
docker compose ps                             # 当前项目的容器状态
docker compose ps -a                          # 包含已停止的容器
docker compose logs -f --tail 100 【服务名】    # 跟踪指定服务日志
docker compose exec 【服务名】 sh               # 在运行中的服务容器里启动 Shell
docker compose stop                           # 停止服务,保留容器
docker compose start                          # 启动已有的停止状态容器
docker compose restart 【服务名】               # 重启指定服务
docker compose pull                           # 拉取服务镜像,不重建容器
docker compose down                           # 停止并删除项目容器及相关网络

# 显式指定配置文件和项目名,后续操作也使用相同参数
docker compose -f 【配置文件.yaml】 -p 【项目名】 up -d

docker compose ps 输出示例(节选):

运行结果 Text
1
2
3
# NAME          IMAGE          SERVICE   STATUS         PORTS
# demo-web-1    nginx:alpine   web       Up 2 minutes   127.0.0.1:8080->80/tcp
# demo-redis-1  redis:7        redis     Up 2 minutes   6379/tcp

改配置后用 up -d 应用,restart 不会应用修改。 更新远端镜像先 pull,再 up -d。

down 默认保留卷;down -v 会删除配置声明的命名卷及关联匿名卷,external 卷除外。

13. 删除与清理

代码块 Shell
1
2
3
4
5
6
docker system df                             # 镜像、容器、卷和构建缓存占用
docker system df -v                          # 展开占用详情
docker rm 【容器】                            # 删除已停止的容器
docker rmi 【镜像:标签】                       # 删除本地镜像引用,等同于 docker image rm
docker network rm 【网络名】                  # 删除没有容器连接的网络
docker volume rm 【卷名】                     # 删除未被容器引用的卷及其中数据

运行中的容器先 stop 再 rm;rm -f 会强制结束并删除。docker kill 【容器】 默认发送 SIGKILL,只停止、不删除容器。

rmi 只删本地镜像引用,不删除远端镜像。下表中的“未被引用”要求运行中和已停止的容器都没有引用该资源。

命令删除范围
docker container prune所有已停止的容器及其可写层
docker image prunedangling 镜像,即未打标签且未被容器引用的镜像
docker image prune -a所有未被容器引用的镜像,包括有标签的镜像
docker network prune未被容器使用的自定义网络
docker builder prune清理构建缓存,默认清理 dangling 缓存;-a 扩大到所有未使用缓存
docker volume prune未被容器引用的匿名本地卷
docker volume prune -a未被容器引用的匿名卷和命名卷,要求 API 1.42+
docker system prune已停止容器、未使用网络、dangling 镜像和未使用构建缓存,默认不删卷

system prune -a 包括所有未被容器引用的镜像;--volumes 额外清理未使用的匿名卷,不含命名卷。prune -f 只跳过确认提示。

评论

使用 GitHub 登录后参与讨论,评论将公开保存在 GitHub。

阅读到这里时加载评论。