Docker: docker run启动容器
最后更新:2026-08-26
docker run 是使用频率最高的 Docker 命令——它创建并启动一个容器,掌握它的参数就掌握了容器运行的核心。
1. 你将学到
- docker run 的核心参数
- 前台 vs 后台运行模式
- 端口映射机制
- 容器命名与自动清理
- 资源限制(CPU/内存)
2. 一个后端开发者的真实故事
(1) 痛点:多版本数据库冲突
Alice 要同时在本地跑三个版本的 PostgreSQL 用于测试兼容性:v15、v14 和 v13。传统安装方式只能装一个版本,版本切换要卸载重装,每次耗时 30 分钟。更糟的是,不同版本的配置文件和数据目录还可能冲突。
(2) Docker 多容器并行的解法
用 Docker 一行命令就启动了三个 PostgreSQL instance,分别映射到不同端口。
BASH
# Run three PostgreSQL versions side by side
docker run -d --name pg15 -e POSTGRES_PASSWORD=secret -p 5432:5432 postgres:15
docker run -d --name pg14 -e POSTGRES_PASSWORD=secret -p 5433:5432 postgres:14
docker run -d --name pg13 -e POSTGRES_PASSWORD=secret -p 5434:5432 postgres:13
(3) 收益:多版本并行零冲突
三个 PostgreSQL 实例并行运行,互不干扰,Alice 在 5 分钟内完成了跨版本兼容性测试——传统方式需要 2 小时。
3. docker run 语法与核心参数
(1) 基本语法
BASH
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
| 组成部分 | 说明 | 示例 |
|---|---|---|
OPTIONS |
运行参数(端口/环境/资源等) | -d -p 8080:80 --name web |
IMAGE |
镜像名称:标签 | nginx:latest / postgres:15 |
COMMAND |
覆盖镜像默认启动命令 | bash / sleep 3600 |
ARG |
传给 COMMAND 的参数 | -c "echo hello" |
(2) 常用参数速查表
| 参数 | 作用 | 示例 |
|---|---|---|
-d |
后台运行(detached) | docker run -d nginx |
-it |
交互式终端 | docker run -it ubuntu bash |
-p |
端口映射(host:container) | -p 8080:80 |
-P |
随机端口映射 | docker run -P nginx |
--name |
容器命名 | --name my-app |
--rm |
退出后自动删除 | docker run --rm alpine echo hi |
-e |
设置环境变量 | -e MYSQL_ROOT_PASSWORD=secret |
-v |
挂载卷(host:container) | -v /data:/var/lib/mysql |
--restart |
重启策略 | --restart=always |
--cpus |
CPU 限制 | --cpus=1.5 |
--memory |
内存限制 | --memory=256m |
--network |
指定网络 | --network=my-net |
-w |
工作目录 | -w /app |
--user |
运行用户 | --user 1000:1000 |
4. 前台 vs 后台运行
容器有两种运行模式:前台(foreground)和后台(detached),用 -it 和 -d 控制。
(1) 运行模式对比
| 维度 | 前台模式 -it |
后台模式 -d |
|---|---|---|
| 终端占用 | 占用当前终端 | 释放终端 |
| 输出显示 | 直接输出到终端 | 用 docker logs 查看 |
| 适用场景 | 交互操作、调试 | 服务类应用(Web/DB) |
| 退出方式 | Ctrl+C 或 exit | docker stop |
| 示例 | docker run -it ubuntu bash |
docker run -d nginx |
▶ 示例:后台启动 Nginx 服务(难度⭐)
BASH
# Run Nginx in detached mode
docker run -d -p 8080:80 --name web nginx:latest
# View logs from the background container
docker logs web
💻 输出:
TEXT
📖 仅展示
a1b2c3d4e5f6... (container ID)
/docker-entrypoint.sh: Launching nginx...
▶ 示例:交互式启动 Ubuntu 容器(难度⭐⭐)
BASH
# Run Ubuntu with interactive terminal
docker run -it ubuntu:22.04 bash
# Inside the container: check OS info
cat /etc/os-release
# Exit the container
exit
💻 输出:
TEXT
📖 仅展示
root@a1b2c3d4e5f6:/# cat /etc/os-release
NAME="Ubuntu"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
...
root@a1b2c3d4e5f6:/# exit
⚠️ 注意:
exit 会停止容器。如果想脱离容器但保持运行,按 Ctrl+P 然后 Ctrl+Q(detach 快捷键)。
5. 端口映射
容器内部的服务端口默认外部无法访问,端口映射将容器端口暴露到主机。
graph LR
A["Host<br/>Port 8080"] -->|"-p 8080:80"| B["Container<br/>Port 80"]
C["Host<br/>Port 5432"] -->|"-p 5432:5432"| D["Container<br/>Port 5432"]
(1) 端口映射策略
| 方式 | syntax | 说明 | 示例 |
|---|---|---|---|
| 指定端口 | -p host:container |
主机端口→容器端口 | -p 8080:80 |
| 指定地址 | -p ip:host:container |
绑定特定 IP | -p 127.0.0.1:8080:80 |
| 随机端口 | -P |
自动映射到主机随机端口 | -P |
| 范围映射 | -p 8080-8090:80-90 |
映射端口范围 | 仅限 Linux |
▶ 示例:多端口映射 PostgreSQL(难度⭐⭐)
BASH
# Run PostgreSQL with port mapping and environment variables
docker run -d \
--name pg15 \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
postgres:15
# Connect to PostgreSQL
docker exec -it pg15 psql -U postgres -d myapp
💻 输出:
TEXT
📖 仅展示
myapp=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype
-----------+----------+----------+------------+------------
myapp | postgres | UTF8 | en_US.utf8 | en_US.utf8
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8
6. 自动清理与重启策略
(1) --rm 临时容器
--rm 让容器退出后自动删除,适合一次性任务。
▶ 示例:用 --rm 运行临时任务(难度⭐)
BASH
# Run a one-off command, container auto-removes after exit
docker run --rm alpine:latest echo "Hello from Alpine!"
# Verify: container is gone
docker ps -a
💻 输出:
TEXT
📖 仅展示
Hello from Alpine!
💡 提示:
--rm 特别适合 CI/CD 中的构建任务和临时测试,避免容器堆积。
(2) 重启策略
重启策略决定容器退出后是否自动重启。
| 策略 | 行为 | 适用场景 |
|---|---|---|
no(默认) |
不重启 | 临时任务 |
on-failure[:max] |
非零退出时重启(可限次数) | 可能偶发崩溃的服务 |
always |
总是重启(包括手动 stop 后 daemon 重启时) | 核心服务(Web/DB) |
unless-stopped |
类似 always,但手动 stop 后不会重启 | 需要手动控制的服务 |
▶ 示例:配置自动重启(难度⭐⭐)
BASH
# Run Nginx with restart policy
docker run -d --name web --restart=always -p 8080:80 nginx:latest
# Simulate crash: kill the container process
docker kill web
# Wait a few seconds, check: it restarted automatically
docker ps
💻 输出:
TEXT
📖 仅展示
CONTAINER ID IMAGE STATUS PORTS NAMES
b2c3d4e5f6a7 nginx:latest Up 3 seconds (healthy) 0.0.0.0:8080->80/tcp web
7. 资源限制
Docker 可以限制容器使用的 CPU 和内存,防止单个容器耗尽主机资源。
(1) 资源限制参数
| 资源 | 参数 | 说明 | 示例 |
|---|---|---|---|
| CPU 核数 | --cpus |
最多使用的 CPU 核数 | --cpus=1.5 |
| CPU 权重 | --cpu-shares |
相对权重(默认 1024) | --cpu-shares=512 |
| 内存上限 | --memory / -m |
最大内存 | --memory=256m |
| Swap | --memory-swap |
内存 + Swap 上限 | --memory-swap=512m |
▶ 示例:限制容器内存为 256MB(难度⭐⭐)
BASH
# Run a container with 256 MB memory limit
docker run -d --name limited-app --memory=256m nginx:latest
# Verify the memory limit
docker inspect limited-app --format='{{.HostConfig.Memory}}'
💻 输出:
TEXT
📖 仅展示
268435456
⚠️ 注意: 268435456 bytes = 256 MB。超过内存限制的容器会被 OOM Killer 杀掉(exit code 137)。
8. 容器生命周期与状态转换
stateDiagram-v2
[*] --> Created : docker create / docker run
Created --> Running : docker start / docker run
Running --> Paused : docker pause
Paused --> Running : docker unpause
Running --> Stopped : docker stop / docker kill
Stopped --> Running : docker start
Running --> Restarting : crash + restart policy
Restarting --> Running : restart succeeds
Stopped --> Deleted : docker rm
Running --> Deleted : docker rm -f
Deleted --> [*]
9. 完整示例:启动带环境变量的 PostgreSQL 容器
BASH
# ============================================
# Complete walkthrough: Run PostgreSQL with Docker
# Covers: -d, -e, -p, --name, --restart, --memory
# ============================================
# 1. Run PostgreSQL 15 with full configuration
docker run -d \
--name pg15 \
-e POSTGRES_USER=appuser \
-e POSTGRES_PASSWORD=secret123 \
-e POSTGRES_DB=appdb \
-p 5432:5432 \
--restart=unless-stopped \
--memory=512m \
postgres:15
# 2. Verify the container is running
docker ps
# 3. Connect via psql client inside the container
docker exec -it pg15 psql -U appuser -d appdb
# 4. Inside psql: create a test table
# CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(100));
# INSERT INTO users (name) VALUES ('Alice'), ('Bob');
# SELECT * FROM users;
# 5. Check container resource usage
docker stats pg15 --no-stream
# 6. View container configuration
docker inspect pg15 --format='Memory: {{.HostConfig.Memory}}, RestartPolicy: {{.HostConfig.RestartPolicy.Name}}'
💻 输出(节选):
TEXT
📖 仅展示
# docker ps
CONTAINER ID IMAGE STATUS PORTS NAMES
a1b2c3d4e5f6 postgres:15 Up 30 seconds 0.0.0.0:5432->5432/tcp pg15
# docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
a1b2c3d4e5f6 pg15 0.02% 38.5MiB / 512MiB 7.52%
# docker inspect --format
Memory: 536870912, RestartPolicy: unless-stopped
❓ 常见问题
Q
-d 和 -it 能一起用吗?A 不能。
-d 是后台运行,-it 是交互式终端,两者互斥。需要后台运行+偶尔进入容器时,用 -d 启动,然后用 docker exec -it 进入。Q 容器退出后数据会丢吗?
A 如果没用
-v 挂载卷,容器删除后数据就丢失了。容器停止(stop)后数据仍在,但删除(rm)后数据消失。持久化数据必须用 Volume 或 Bind Mount。Q
--rm 什么时候用?A 一次性任务:运行测试、执行脚本、检查工具版本。不适合需要持久化数据的服务。CI/CD 管道中几乎所有步骤都该加
--rm,避免构建节点容器堆积。Q
-p 8080:80 两个端口号谁是谁?A 左边 8080 是主机端口,右边 80 是容器端口。记忆口诀:"左主机右容器"。访问
主机IP:8080 就能到达容器内的 80 端口服务。Q 容器占多少硬盘空间?
A 每个容器的可写层(修改部分)通常只占几 KB 到几十 MB。容器本身不复制镜像,而是共享镜像的只读层。总体占用 = 镜像大小 + 容器可写层。用
docker system df 查看详细占用。Q 如何查看 docker run 的所有参数?
A
docker run --help 列出所有参数。最常用的约 15 个(本课已覆盖),其余按需查阅。📖 小节
docker run= 创建 + 启动容器,是最核心的 Docker 命令-d后台运行服务,-it交互式操作调试,两者互斥- 端口映射
-p host:container暴露容器服务到主机 --rm用于临时任务自动清理,--restart用于服务自动恢复--memory/--cpus限制资源防止单容器占满主机- 容器有完整的状态生命周期:Created → Running → Paused → Stopped → Deleted
📝 作业
- 基础题(难度⭐):启动一个 Nginx 容器映射到本机 8080 端口,用浏览器访问确认页面正常显示。
- 进阶题(难度⭐⭐):交互式启动 Ubuntu 容器,在容器内执行
apt update && apt install -y curl,然后用 curl 访问一个网页。 - 挑战题(难度⭐⭐⭐):限制容器内存为 256MB,运行一个压力测试工具(如
progrium/stress),观察当内存超限时容器是否被 OOM Kill(提示:docker events --filter event=oom)。