安装 Docker
Mac / Windows:Docker Desktop
前往 https://www.docker.com/products/docker-desktop 下载对应平台安装包。安装后启动 Docker Desktop 应用,等待状态栏图标变为运行状态。
Apple Silicon(M1/M2/M3) — 下载 Apple Silicon 版本,Docker Desktop 内置了 Rosetta 2 兼容层,可以运行 x86 镜像(性能略低)。原生 ARM 镜像性能最佳。
Linux(Ubuntu):Docker Engine
# 卸载旧版本(如有)
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
# 添加 Docker 官方 GPG Key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 添加 Docker apt 源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list
# 安装 Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 允许当前用户使用 Docker(无需 sudo)
sudo usermod -aG docker $USER
newgrp docker
验证安装
# 查看 Docker 客户端和服务端版本
docker version
# 查看系统详细信息(容器数、镜像数、存储驱动等)
docker info
# 运行第一个容器(Hello World)
docker run hello-world
docker run hello-world 会自动从 Docker Hub 拉取 hello-world 镜像并运行,输出一段欢迎消息——这证明 Docker 安装成功且网络正常。
镜像命令
拉取镜像
# 拉取最新版(实际是 latest 标签,不推荐生产使用)
docker pull nginx
# 拉取指定版本(推荐)
docker pull nginx:1.25
# 拉取 Alpine 变体(更小)
docker pull node:18-alpine
镜像标签格式:仓库名:标签。官方镜像只有仓库名(如 nginx),第三方镜像格式为 用户名/仓库名:标签(如 mysql/mysql-server:8.0)。
查看本地镜像
# 两种等价写法
docker images
docker image ls
# 查看镜像 ID(短格式)
docker images -q
# 查看指定镜像
docker images nginx
删除镜像
# 删除指定镜像(两种等价写法)
docker image rm nginx:1.25
docker rmi nginx:1.25
# 通过镜像 ID 删除
docker rmi abc123def456
# 强制删除(即使有容器在使用)
docker rmi -f nginx:1.25
# 清理悬空镜像(无标签的中间层镜像)
docker image prune
# 清理所有未使用镜像
docker image prune -a
悬空镜像(Dangling Image) — 当你重新构建同名镜像时,旧镜像失去标签但仍占用磁盘空间,显示为 <none>:<none>。定期用 docker image prune 清理。
容器生命周期
容器在其生命周期中有多种状态:
docker create
│
▼
Created ──── docker start ────▶ Running
│ │
docker pause docker stop / docker kill
│ │
▼ ▼
Paused Stopped/Exited
│ │
docker unpause docker start
│
▼
docker rm ──▶ Removed
docker run 常用参数详解
docker run \
-d \ # 后台运行(detached mode)
-p 8080:80 \ # 端口映射:宿主机8080 → 容器80
-v /host/path:/container/path \ # 绑定挂载
--name my-nginx \ # 为容器指定名称
--rm \ # 容器退出后自动删除
-e MYSQL_ROOT_PASSWORD=secret \ # 设置环境变量
-it \ # 交互模式 + 伪终端(配合 bash 使用)
--network my-network \ # 加入指定网络
--memory "512m" \ # 限制内存
--cpus "0.5" \ # 限制 CPU(0.5 = 半个核心)
nginx:1.25 # 镜像名:标签
| 参数 | 说明 | 示例 |
|---|---|---|
-d | 后台运行,返回容器 ID | docker run -d nginx |
-p | 端口映射,宿主机:容器 | -p 3000:3000 |
-v | 卷挂载(命名卷或绑定挂载) | -v mydata:/var/lib/mysql |
--name | 指定容器名(不指定则随机) | --name web |
--rm | 退出后自动删除容器 | 适合一次性任务 |
-e | 设置环境变量 | -e NODE_ENV=production |
-it | 保持标准输入 + 分配伪终端 | docker run -it ubuntu bash |
容器启停命令
# 停止容器(发送 SIGTERM,给15秒优雅退出,超时发 SIGKILL)
docker stop my-nginx
# 强制停止(立即发送 SIGKILL)
docker kill my-nginx
# 启动已停止的容器
docker start my-nginx
# 重启容器
docker restart my-nginx
# 暂停 / 恢复容器(冻结进程,不终止)
docker pause my-nginx
docker unpause my-nginx
# 删除已停止的容器
docker rm my-nginx
# 强制删除运行中的容器(等同于 stop + rm)
docker rm -f my-nginx
# 删除所有停止的容器
docker container prune
容器交互与调试
进入运行中的容器
# 在运行中的容器内执行命令
docker exec -it my-nginx bash
# 如果没有 bash,用 sh
docker exec -it my-nginx sh
# 执行单条命令
docker exec my-nginx nginx -t # 检查 nginx 配置
查看日志
# 查看所有日志
docker logs my-nginx
# 实时跟踪日志(-f = follow)
docker logs -f my-nginx
# 查看最近 50 行
docker logs --tail 50 my-nginx
# 带时间戳
docker logs -t my-nginx
查看容器详情与资源
# 查看容器详细 JSON 信息(IP、挂载、环境变量等)
docker inspect my-nginx
# 提取特定字段(IP 地址)
docker inspect --format '{{.NetworkSettings.IPAddress}}' my-nginx
# 实时资源监控(CPU/内存/IO/网络)
docker stats
# 查看所有容器(包括已停止的)
docker ps -a
# 查看容器进程
docker top my-nginx
实战:运行 Nginx 容器
通过一个完整的实战,串联以上命令:
# 1. 后台运行 Nginx,映射端口 8080
docker run -d -p 8080:80 --name my-nginx nginx:1.25
# 2. 验证运行中
docker ps
# 3. 访问页面(应显示 nginx 欢迎页)
curl http://localhost:8080
# 4. 查看实时日志
docker logs -f my-nginx
# 5. 进入容器,修改 nginx 默认页面
docker exec -it my-nginx bash
# 在容器内执行:
# echo "Hello Docker!" > /usr/share/nginx/html/index.html
# exit
# 6. 再次访问,看到修改后的页面
curl http://localhost:8080
# 7. 停止并删除容器
docker stop my-nginx
docker rm my-nginx
注意 — 在容器内修改的文件在容器删除后就消失了。这正是 Volume(数据卷)的用途,我们将在第6章详细介绍。
容器退出码含义
理解容器退出码有助于快速诊断问题:
| 退出码 | 含义 | 常见原因 |
|---|---|---|
0 | 正常退出 | 任务完成,容器自行退出(如批处理任务) |
1 | 通用错误 | 应用程序异常退出 |
137 | SIGKILL (128+9) | OOM Kill(内存超限)或 docker kill |
139 | SIGSEGV (128+11) | 段错误(内存访问违规) |
143 | SIGTERM (128+15) | docker stop 正常停止 |
# 查看容器退出码
docker inspect --format '{{.State.ExitCode}}' my-container
# 查看 OOMKilled 状态(内存不足被杀)
docker inspect --format '{{.State.OOMKilled}}' my-container
常见命令误区
docker run 每次都创建新容器 — 很多新手会重复运行 docker run nginx,每次都会创建一个新的容器,导致多个同名或无名容器堆积。如果容器已经停止,用 docker start <名称> 重启,而不是重新 run。
-p 参数绑定所有接口的安全风险 — -p 3306:3306 会将 MySQL 端口暴露到宿主机的所有网络接口(0.0.0.0),包括外网 IP。如果服务器没有防火墙,数据库会被暴露到互联网。开发环境应使用 -p 127.0.0.1:3306:3306 只绑定本地回环接口。
docker exec 在已停止容器上无效 — docker exec 只能在运行中的容器上执行,已停止的容器无法 exec。如需调试停止的容器,可以用 docker commit 将其保存为镜像,再启动一个新容器进行调试。
Docker CLI 上下文与多环境管理
# 查看所有 context(默认、远程服务器等)
docker context ls
# 创建指向远程 Docker 服务器的 context
docker context create production \
--docker "host=ssh://user@prod-server.example.com"
# 切换到生产环境 context
docker context use production
# 在特定 context 上运行命令(不切换默认)
docker --context production ps
# 切换回默认本地 context
docker context use default
本章小结 — 掌握 Docker 日常操作的核心命令:docker pull/push/images 管理镜像,docker run/start/stop/rm 管理容器生命周期,docker exec/logs/inspect/stats 进行调试。记住退出码含义(137=OOM,143=正常停止),避免 -p 暴露端口到外网,使用 context 管理多环境。