1、docker容器命令 | 生命周期管理

1、命令总览

命令 作用
docker run [OPTIONS] IMAGE 创建并启动容器(常用选项:-d后台运行、-it交互式终端、--name命名、-p端口映射)
docker create [OPTIONS] IMAGE 创建容器但不启动(类似run但不启动)
docker start [CONTAINER] 启动已停止的容器
docker stop [CONTAINER] 优雅停止容器(发送SIGTERM信号)
docker stop $(docker ps -q) 停止所有运行中的容器
docker restart [CONTAINER] 重启容器
docker pause/unpause [CONTAINER] 暂停/恢复容器进程
docker kill [CONTAINER] 强制停止容器(发送SIGKILL信号)
docker rm [CONTAINER] 删除已停止的容器(-f强制删除运行中的容器)
docker rm $(docker ps -aq) 删除所有容器(包括运行中的需加-f
docker container prune 删除所有停止的容器

2、docker run

复制代码
# 基础运行容器(前台运行)
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

docker run ubuntu:22.04
# 注释:运行 Ubuntu 22.04 镜像的容器

# 运行容器并进入交互模式
docker run -it ubuntu:22.04 /bin/bash
#   -i 保持标准输入打开
#   -t 分配伪终端
#   /bin/bash 启动 Bash shell

# 后台运行容器(守护态)
docker run -d --name my_nginx nginx:latest
#   -d 后台运行
#   --name 指定容器名称

# 端口映射(宿主机端口:容器端口)
docker run -d -p 8080:80 nginx
# 注释:将宿主机的 8080 端口映射到容器的 80 端口

# 挂载数据卷(宿主机目录:容器目录)
docker run -v /host/data:/container/data ubuntu
# 注释:将宿主机的 /host/data 目录挂载到容器的 /container/data

# 设置环境变量
docker run -e "ENV_VAR=value" node:18
# 注释:设置环境变量 ENV_VAR 的值为 value

# 使用自定义网络
docker run --net=mynetwork --net-alias=app1 nginx
#   --net=mynetwork:将容器连接到名为 mynetwork 的自定义网络。
#   --net-alias=app1:为容器在 mynetwork 网络中设置别名 app1,其他容器可以通过 app1 访问它

# 资源限制
docker run --cpus=1.5 --memory=512m python:3.9
#   --cpus 限制 CPU 核数
#   --memory 限制内存使用

# 自动删除容器(退出后清理)
docker run --rm alpine echo "Hello"
# 注释:容器退出后自动删除

# 文件挂载(临时目录)
docker run --mount type=bind,source=/host/path,target=/container/path nginx
# 注释:更灵活的挂载方式(推荐替代 -v)
# --mount:指定挂载配置,支持更详细的参数定义。
# type=bind:表示使用绑定挂载(Bind Mount),将宿主机的文件或目录挂载到容器内。
# source=/host/path:宿主机上的路径(绝对路径),需要提前存在。
# target=/container/path:容器内的目标路径,容器启动时会自动创建该目录。
# 挂载(Mount)是指将宿主机的文件或目录与容器内的文件系统进行绑定,使得容器可以直接访问宿主机的文或目录。宿主机的文件修改会立即反映到容器中。容器内对挂载目录的修改也会同到宿主机。

# 传递环境变量文件
docker run --env-file .env mysql
# 注释:从 .env 文件读取环境变量

# 设置容器工作目录
docker run -w /app python:3.9 python script.py
#   -w /app 设置工作目录为 /app

# 连接其他容器
docker run -d --name web --link db:database nginx
# 注释:将 web 容器连接到 db 容器(database 为别名)
# --link已被弃用,推荐使用自定义网络
docker network create my-network
# 启动数据库容器
docker run -d --name db --network my-network mysql
# 启动 Web 容器并加入同一网络
docker run -d --name web --network my-network nginx

# 重启策略
docker run --restart=always redis
#   always: 退出时自动重启
#   on-failure: 非0退出时重启
#   unless-stopped: 除非手动停止

运行MySQL

复制代码
# 运行 MySQL 容器(最完整示例)
docker run -d \
  --name mysql8 \                        # 容器名
  --restart unless-stopped \             # 宿主机重启后自动拉起
  -p 3306:3306 \                         # 宿主 3306 → 容器 3306
  -e MYSQL_ROOT_PASSWORD=Root@123456 \   # root 密码(必须)
  -e MYSQL_DATABASE=appdb \              # 初始化数据库(可选)
  -e MYSQL_USER=appuser \                # 新建业务用户(可选)
  -e MYSQL_PASSWORD=App@123456 \         # 业务用户密码(可选)
  -v mysql-data:/var/lib/mysql \         # 数据持久化(命名卷)
  -v /etc/localtime:/etc/localtime:ro \  # 同步宿主机时区
  -v /my/custom:/etc/mysql/conf.d \      # 挂载自定义 *.cnf(可选)
  mysql:8.0 \
  --character-set-server=utf8mb4 \       # 容器级默认字符集
  --collation-server=utf8mb4_unicode_ci  # 容器级排序规则


# 运行版
docker run -d \
  --name mysql8 \
  --restart unless-stopped \
  -p 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=Root@123456 \
  -e MYSQL_DATABASE=appdb \
  -e MYSQL_USER=appuser \
  -e MYSQL_PASSWORD=App@123456 \
  -v mysql-data:/var/lib/mysql \
  -v /etc/localtime:/etc/localtime:ro \
  -v /my/custom:/etc/mysql/conf.d \
  mysql:8.0 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci


# 进入容器
docker exec -it mysql8 bash
# mysql:8.0 镜像中 /bin 在 $PATH 里,bash是相对路径(依赖 $PATH 环境变量),会启动 /bin/bash

# 连接 MySQL
mysql -uroot -pRoot@123456
# -u 选项允许有空格或无空格;-p 后面如果紧跟密码,就不能有空格

# 查看字符集
SHOW VARIABLES LIKE 'character_set_%';

docker stop mysql8 && docker rm -v mysql8

3、docker create

复制代码
# 1. 最简单启动:后台运行 nginx,容器名 my-nginx
docker run -d --name my-nginx nginx

# 2. 端口映射:把宿主 8080 → 容器 80
docker run -d --name web -p 8080:80 nginx

# 3. 目录挂载:把当前目录挂载到容器 /usr/share/nginx/html
docker run -d --name web \
  -p 8080:80 \
  -v "$(pwd)":/usr/share/nginx/html \
  nginx

# 4. 只读挂载 + 临时文件系统(安全、无状态)
docker run -d --name web-ro \
  -p 8080:80 \
  -v "$(pwd)":/usr/share/nginx/html:ro \   # 代码目录只读
  --tmpfs /tmp \                           # 内存盘,重启即丢
  nginx

# 5. 环境变量:启动 MySQL,设置 root 密码
docker run -d --name mysql \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -p 3306:3306 \
  mysql:8

# 6. 覆盖默认 CMD:让容器启动后立即执行 bash
docker run -it --name debug-ubuntu ubuntu bash

# 7. 自动删除:--rm,容器退出即自动清理(常用于一次性任务)
docker run --rm alpine echo "一次性任务"

# 8. 资源限制:最多 1 CPU、512 MB 内存
docker run -d --name app \
  --cpus="1" \
  --memory="512m" \
  myapp:latest

# 9. 网络:加入已存在的自定义网络 mynet
docker network create mynet
docker run -d --name api --network mynet myapi:latest

# 10. 特权模式 + 设备直通(例如用摄像头)
docker run -it --rm --privileged --device=/dev/video0 ubuntu bash

# 11. 只读根文件系统 + 指定用户(最小权限)
docker run -d --name secure-app \
  --read-only \
  --user 1000:1000 \
  myapp:latest

# 12. 健康检查:每 30 秒访问 /health,失败 3 次视为不健康
docker run -d --name health-app \
  --health-cmd="curl -f http://localhost/health || exit 1" \
  --health-interval=30s \
  --health-retries=3 \
  myapp:latest

# 13. 时区同步:把宿主机时区挂进去
docker run -d --name web-tz \
  -v /etc/localtime:/etc/localtime:ro \
  -v /etc/timezone:/etc/timezone:ro \
  nginx

# 14. GPU 支持(宿主机需安装 nvidia-docker)
docker run -it --rm --gpus all nvidia/cuda:12.2-base nvidia-smi

# 15. 多端口映射:一次映射 80、443
docker run -d --name lb \
  -p 80:80 \
  -p 443:443 \
  nginx

创建常用镜像

复制代码
# 创建一个完整的Nginx web服务器容器
docker create \
  --name my_nginx \                    # 容器名称
  -p 80:80 \                           # 端口映射(主机:容器)
  -p 443:443 \                         # HTTPS端口映射
  -v /path/to/html:/usr/share/nginx/html \  # 挂载网站文件
  -v /path/to/nginx.conf:/etc/nginx/nginx.conf \  # 挂载自定义配置
  -v /path/to/certs:/etc/nginx/certs \ # 挂载SSL证书
  -e "TZ=Asia/Shanghai" \              # 设置时区
  --memory 512m \                      # 内存限制
  --cpus 1 \                           # CPU限制
  --restart unless-stopped \           # 自动重启策略
  --network bridge \                   # 使用桥接网络
  nginx:1.23-alpine                    # 使用轻量级Nginx镜像


# 创建一个MySQL数据库容器
docker create \
  --name mysql_db \                    # 容器名称
  -p 3306:3306 \                       # 端口映射
  -v /data/mysql:/var/lib/mysql \      # 数据持久化
  -e MYSQL_ROOT_PASSWORD=my-secret-pw \ # 设置root密码
  -e MYSQL_DATABASE=myapp \            # 创建默认数据库
  -e MYSQL_USER=user \                 # 创建默认用户
  -e MYSQL_PASSWORD=password \         # 设置用户密码
  --memory 2g \                        # 内存限制
  --cpus 2 \                           # CPU限制
  --restart always \                   # 总是自动重启
  mysql:8.0 \                          # 使用MySQL 8.0镜像


# 创建一个Node.js应用容器
docker create \
  --name node_app \                    # 容器名称
  -p 3000:3000 \                       # 端口映射
  -v /app/code:/usr/src/app \          # 挂载应用代码
  -v /app/node_modules:/usr/src/app/node_modules \ # 挂载node_modules
  -e NODE_ENV=production \             # 设置环境变量
  -e PORT=3000 \                       # 应用监听端口
  --memory 1g \                        # 内存限制
  --cpus 1.5 \                         # CPU限制
  --restart on-failure \               # 失败时重启
  --network my_app_network \           # 使用自定义网络
  node:18-alpine                       # 使用Node.js 18 Alpine镜像


# 创建一个Redis缓存服务容器
docker create \
  --name redis_cache \                 # 容器名称
  -p 6379:6379 \                       # 端口映射
  -v /data/redis:/data \               # 数据持久化
  -e REDIS_PASSWORD=secret \           # 设置Redis密码
  --memory 512m \                      # 内存限制
  --cpus 1 \                           # CPU限制
  --restart unless-stopped \           # 自动重启策略
  redis:7-alpine \                     # 使用Redis 7 Alpine镜像
  redis-server --appendonly yes        # 启用持久化

# 在Linux终端中,多行命令需要使用反斜杠 \ 来连接,确保每行结尾的反斜杠后面没有空格
docker create \
--name node_app \
-p 3000:3000 \
-v /app/code:/usr/src/app \
-v /app/node_modules:/usr/src/app/node_modules \
-e NODE_ENV=production \
-e PORT=3000 \
--memory 1g \
--cpus 1.5 \
--restart on-failure \
--network my_app_network \
node:18-alpine

4、docker start

启动一个或多个已经创建(docker create 或 docker run 退出)但当前处于停止(Exited / Created)状态的容器

复制代码
# 1. 启动单个容器(最常用)
docker start mysql

# 2. 启动多个容器(空格分隔)
docker start redis nginx mysql

# 3. 启动并实时查看日志(-a = attach,-i = interactive)
docker start -ai mysql        # 相当于把 docker logs -f 和 attach 一次做完

# 4. 启动后自动重启(--restart 策略只在 start/run 时生效)
# 如果容器创建时没加 --restart,现在想补加,只能重新 run/create
# 不能通过 start 改,但可以 docker update
docker update --restart unless-stopped mysql
docker start mysql

# 5. 启动所有处于退出状态的容器(一行命令)
docker start $(docker ps -aq -f status=exited)

# 6. 启动指定前缀的容器(批量脚本)
docker start $(docker ps -aq --filter "name=api_*")

# 7. 只启动最近一次创建的容器
docker start $(docker ps -alq)

# 8. 查看启动结果(返回容器名/ID,或报错信息)
docker start mysql && echo "mysql started OK" || echo "failed to start"

5、 docker stop

复制代码
# 1. 停止单个容器(最常用,10 秒宽限)
docker stop nginx

# 2. 停止多个容器(空格分隔)
docker stop web mysql redis

# 3. 指定宽限时间(-t 秒数)
docker stop -t 30 mysql      # 给 MySQL 30 秒做 flush & 关闭

# 4. 强制立即停止(等价于 docker kill)
docker stop -t 0 mysql       # 宽限 0 秒,等同直接 kill

# 5. 停止所有正在运行的容器(一行命令)
docker stop $(docker ps -q)

# 6. 按名称通配符批量停止
docker stop $(docker ps -q --filter "name=api_*")

# 7. 停止并自动删除(常用于一次性容器)
docker stop tmp-container && docker rm tmp-container

# 8. 优雅重启脚本:先停后启
docker stop web && docker start web

6、docker restart

docker restart = docker stopdocker start 的快捷命令,用于重启一个或多个运行中或已停止的容器

复制代码
# 1. 重启单个容器(默认 10 秒优雅停止)
docker restart nginx

# 2. 重启多个容器(空格分隔)
docker restart web mysql redis

# 3. 自定义优雅停止时间(-t 秒)
docker restart -t 30 mysql      # 给 MySQL 30 秒完成 flush & 关闭

# 4. 重启所有正在运行的容器(一行命令)
docker restart $(docker ps -q)

# 5. 按名称通配符批量重启
docker restart $(docker ps -q --filter "name=api_*")

# 6. 重启并实时查看日志(先停再 attach)
docker restart nginx && docker logs -f nginx

# 7. 重启后验证状态
docker restart web && docker ps -f name=web

# 8. 结合健康检查:等健康状态为 healthy 再往下走
docker restart api
while [ "$(docker inspect -f '{{.State.Health.Status}}' api)" != "healthy" ]; do
  sleep 2
done
echo "API 已重启并健康"

7、docker pause/unpause

正在运行 的容器内所有进程 一次性挂起 / 恢复,底层利用 Linux cgroups freezer。

复制代码
# 1. 挂起单个容器
docker pause web

# 2. 挂起多个容器
docker pause web mysql redis

# 3. 查看哪些容器被挂起
docker ps -a --filter "status=paused"

# 4. 恢复单个容器
docker unpause web

# 5. 恢复所有被挂起的容器(一行命令)
docker unpause $(docker ps -aq --filter "status=paused")

# 6. 脚本示例:临时冻结 10 秒后恢复
docker pause api
sleep 10
docker unpause api && echo "API 已恢复调度"

8、docker kill

docker kill 用于立即强制终止一个或多个正在运行的容器。

复制代码
# 1. 强制杀死单个容器(默认 SIGKILL)
docker kill nginx

# 2. 强制杀死多个容器(空格分隔)
docker kill web mysql redis

# 3. 指定自定义信号(例如 HUP 让 nginx 重载配置)
docker kill --signal=HUP nginx

# 4. 杀死所有正在运行的容器(一行命令)
docker kill $(docker ps -q)

# 5. 按名称通配符批量杀死
docker kill $(docker ps -q --filter "name=api_*")

# 6. 杀死并自动删除容器(常用于一次性容器)
docker kill tmp-container && docker rm tmp-container

# 7. 杀死容器后检查退出码
docker kill web
docker inspect --format='{{.State.ExitCode}}' web   # 输出 137 表示被 SIGKILL

9、docker rm

docker rm 用于删除一个或多个已经处于 Exited 状态的容器 ,彻底从宿主机磁盘抹除其读写层、日志、元数据。

⚠️ 运行中的容器默认不能删,需加 -f 强制先 kill 再删。

复制代码
# 1. 删除单个已停止的容器
docker rm web

# 2. 强制删除正在运行的容器(先 kill 再 rm)
docker rm -f web

# 3. 删除多个容器(空格分隔)
docker rm web mysql redis

# 4. 删除所有已退出的容器(经典清理)
docker container prune      # 交互式确认
# 或一行命令
docker rm $(docker ps -aq -f status=exited)

# 5. 删除时同时删除匿名卷(避免垃圾卷堆积)
docker rm -fv web

# 6. 按名称通配符批量删除
docker rm $(docker ps -aq --filter "name=api_*")

# 7. 删除失败自动忽略不存在容器
docker rm -f web || true

# 8. 删除并回收磁盘(包括日志、挂载卷)
docker rm -f -v --link web

10、docker container prune

复制代码
# 交互式确认删除所有已停止或已创建但未启动的容器
docker container prune

# 输出示例
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
4f5e6b7c1234
a1b2c3d4e5f6
Total reclaimed space: 1.2 GB


# 场景 1:CI/CD 末尾强制清理
docker container prune -f

# 场景 2:删除 24 小时之前退出的容器(保留当天调试现场)
docker container prune --force --filter "until=24h"

# 场景 3:删除所有 label=temporary 的已停止容器
docker container prune -f --filter "label=temporary"