Docker: docker run启动容器

最后更新:2026-08-26

docker run 是使用频率最高的 Docker 命令——它创建并启动一个容器,掌握它的参数就掌握了容器运行的核心。

1. 你将学到


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. 端口映射

容器内部的服务端口默认外部无法访问,端口映射将容器端口暴露到主机。

100%
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. 容器生命周期与状态转换

100%
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 个(本课已覆盖),其余按需查阅。

📖 小节


📝 作业

  1. 基础题(难度⭐):启动一个 Nginx 容器映射到本机 8080 端口,用浏览器访问确认页面正常显示。
  2. 进阶题(难度⭐⭐):交互式启动 Ubuntu 容器,在容器内执行 apt update && apt install -y curl,然后用 curl 访问一个网页。
  3. 挑战题(难度⭐⭐⭐):限制容器内存为 256MB,运行一个压力测试工具(如 progrium/stress),观察当内存超限时容器是否被 OOM Kill(提示:docker events --filter event=oom)。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏