Docker 使用指南
# Docker 使用指南
Docker 是一个开源的容器化平台,让开发者可以打包应用及其依赖到一个可移植的容器中,实现"一次构建,到处运行"。
# 📖 1. 快速开始
# 什么是 Docker?
Docker 是一个用于开发、部署和运行应用的容器化平台。它解决了"在我机器上能运行"的问题。
核心优势:
- ✅ 环境一致性:开发、测试、生产环境完全一致
- ✅ 快速部署:秒级启动,远快于虚拟机
- ✅ 资源高效:共享内核,占用资源少
- ✅ 易于迁移:一次构建,到处运行
- ✅ 版本管理:镜像版本化,易于回滚
- ✅ 隔离性好:应用间相互隔离
# 安装 Docker
macOS:
# 方法 1:官方下载(推荐)
# 下载地址:https://docs.docker.com/desktop/install/mac-install/
# 方法 2:使用 Homebrew
brew install --cask docker
2
3
4
5
Linux(Ubuntu/Debian):
# 更新软件包
sudo apt update
# 安装依赖
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker
# 添加当前用户到 docker 组(避免每次 sudo)
sudo usermod -aG docker $USER
newgrp docker
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Linux(CentOS/RHEL):
# 安装 Docker
sudo yum install -y docker
# 启动 Docker
sudo systemctl start docker
sudo systemctl enable docker
2
3
4
5
6
# 验证安装
# 查看 Docker 版本
docker --version
# 输出:Docker version 24.0.7, build afdd53b
# 查看详细版本信息
docker version
# 查看 Docker 系统信息
docker info
# 测试 Docker 是否正常工作(重要)
docker run hello-world
2
3
4
5
6
7
8
9
10
11
12
成功输出示例:
Hello from Docker!
This message shows that your installation appears to be working correctly.
2
# Hello World 示例
# 运行第一个容器
docker run hello-world
# 这个命令做了什么?
# 1. 检查本地是否有 hello-world 镜像
# 2. 如果没有,从 Docker Hub 下载
# 3. 创建并运行容器
# 4. 显示消息后自动退出
2
3
4
5
6
7
8
# 🎯 2. 核心概念
# 2.1 镜像(Image)
定义:
镜像是容器的只读模板,包含运行应用所需的所有内容:代码、运行时、系统工具、库和设置。
特点:
- 📦 分层存储:每个指令创建一层,共享基础层
- 🔒 只读:镜像一旦创建不可修改
- 🏷️ 可标签:
name:tag格式,如nginx:1.25 - 📚 可复用:一个镜像可创建多个容器
镜像层级示意:
┌─────────────────────┐
│ 应用代码层 │ ← 你的应用
├─────────────────────┤
│ 依赖安装层 │ ← npm install
├─────────────────────┤
│ 运行时环境层 │ ← Node.js
├─────────────────────┤
│ 基础操作系统层 │ ← Alpine Linux
└─────────────────────┘
只读镜像层
2
3
4
5
6
7
8
9
10
# 2.2 容器(Container)
定义:
容器是镜像的运行实例,是一个独立的、可执行的软件包。
特点:
- 🚀 轻量级:共享主机内核,秒级启动
- 🔐 隔离性:独立的进程空间、网络、文件系统
- ✏️ 可写层:在镜像只读层上添加可写层
- ♻️ 可重建:删除后可从镜像重新创建
容器与镜像关系:
镜像 = 类(Class)
容器 = 对象(Instance)
一个镜像可以创建多个容器:
nginx:latest 镜像
↓
├─→ 容器 1: web-server-1
├─→ 容器 2: web-server-2
└─→ 容器 3: web-server-3
2
3
4
5
6
7
8
9
# 2.3 数据卷(Volume)
定义:
数据卷是用于持久化数据的机制,数据不会随容器删除而丢失。
类型:
| 类型 | 特点 | 使用场景 |
|---|---|---|
| Volume | Docker 管理,推荐 | 数据持久化 |
| Bind Mount | 挂载主机目录 | 开发环境、配置文件 |
| tmpfs | 内存存储 | 临时数据、敏感信息 |
数据持久化对比:
无数据卷:
容器删除 → 数据丢失 ❌
使用数据卷:
容器删除 → 数据保留 ✅
2
3
4
5
# 2.4 网络(Network)
定义:
Docker 网络用于实现容器间通信和容器与外部通信。
网络类型:
| 网络类型 | 说明 | 使用场景 |
|---|---|---|
| bridge | 桥接网络(默认) | 单主机容器通信 |
| host | 使用主机网络 | 性能要求高 |
| none | 无网络 | 完全隔离 |
| overlay | 跨主机网络 | 集群、Swarm |
# 2.5 架构原理
docker CLI] -->|REST API| B[Docker Daemon
dockerd] B --> C[容器 Container] B --> D[镜像 Image] B --> E[数据卷 Volume] B --> F[网络 Network] D -->|创建| C C -->|使用| E C -->|连接| F G[Docker Registry
Docker Hub] -->|pull| D D -->|push| G style A fill:#e3f2fd style B fill:#fff3e0 style C fill:#e8f5e9 style D fill:#f3e5f5 style G fill:#fce4ec
核心组件:
- Docker Client(CLI):用户交互界面,执行
docker命令 - Docker Daemon(dockerd):后台服务,管理镜像、容器、网络、数据卷
- Docker Registry:镜像仓库,存储和分发镜像(如 Docker Hub)
工作流程:
1. 用户执行:docker run nginx
↓
2. Docker Client 发送请求到 Docker Daemon
↓
3. Docker Daemon 检查本地是否有 nginx 镜像
↓
4. 如果没有,从 Docker Hub 拉取
↓
5. 创建容器并启动
↓
6. 返回容器 ID
2
3
4
5
6
7
8
9
10
11
# 🖼️ 3. 镜像管理
# 镜像命令速查表
| 命令 | 说明 | 常用选项 |
|---|---|---|
docker pull | 拉取镜像 | <image>:<tag> |
docker push | 推送镜像 | <image>:<tag> |
docker build | 构建镜像 | -t, -f |
docker images | 列出镜像 | -a, -q |
docker rmi | 删除镜像 | -f |
docker tag | 标签管理 | <source> <target> |
docker search | 搜索镜像 | --limit, --filter |
docker save | 导出镜像 | -o |
docker load | 导入镜像 | -i |
docker image prune | 清理镜像 | -a, -f |
# 3.1 拉取镜像(pull)
# 基本用法
docker pull nginx
# 指定版本
docker pull nginx:1.25
docker pull nginx:alpine
# 指定仓库
docker pull mysql:8.0
docker pull redis:7-alpine
# 从私有仓库拉取
docker pull myregistry.com:5000/myapp:latest
2
3
4
5
6
7
8
9
10
11
12
13
镜像命名规范:
格式: [registry/][username/]repository[:tag]
示例:
nginx # 官方镜像,latest 标签
nginx:1.25 # 官方镜像,指定版本
nginx:alpine # 官方镜像,alpine 变体
myusername/myapp:1.0 # 用户镜像
registry.com/team/app:v2.0 # 私有仓库镜像
2
3
4
5
6
7
8
# 3.2 查看镜像(images)
# 查看所有镜像
docker images
# 只显示镜像 ID
docker images -q
# 查看所有镜像(包括中间层)
docker images -a
# 过滤镜像
docker images nginx
docker images "nginx:*"
# 格式化输出
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
# 查看镜像详细信息
docker inspect nginx:latest
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
输出示例:
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 141MB
mysql 8.0 3218b38490ce 3 weeks ago 517MB
redis alpine 7614ae9453d1 4 weeks ago 32MB
2
3
4
# 3.3 构建镜像(build)
# 基本构建(当前目录的 Dockerfile)
docker build -t myapp:1.0 .
# 指定 Dockerfile
docker build -t myapp:1.0 -f Dockerfile.prod .
# 指定构建参数
docker build -t myapp:1.0 --build-arg NODE_VERSION=18 .
# 不使用缓存
docker build -t myapp:1.0 --no-cache .
# 多平台构建
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:1.0 .
# 查看构建历史
docker history myapp:1.0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3.4 标签管理(tag)
# 给镜像打标签
docker tag myapp:1.0 myapp:latest
docker tag myapp:1.0 myregistry.com/myapp:1.0
# 常见标签策略
docker tag myapp:latest myapp:v1.0.0 # 版本号
docker tag myapp:latest myapp:prod # 环境
docker tag myapp:latest myapp:stable # 稳定版
docker tag myapp:latest myapp:$(git rev-parse --short HEAD) # Git commit
2
3
4
5
6
7
8
9
# 3.5 删除镜像(rmi)
# 删除单个镜像
docker rmi nginx:latest
# 删除多个镜像
docker rmi nginx:latest mysql:8.0 redis:alpine
# 强制删除(即使有容器使用)
docker rmi -f nginx:latest
# 删除所有未使用的镜像
docker image prune
# 删除所有镜像(包括有标签的)
docker image prune -a
# 删除所有悬空镜像(<none>)
docker images -f "dangling=true" -q | xargs docker rmi
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3.6 搜索镜像(search)
# 搜索镜像
docker search nginx
# 限制结果数量
docker search --limit 5 nginx
# 只显示官方镜像
docker search --filter is-official=true nginx
# 显示星级大于 50 的镜像
docker search --filter stars=50 nginx
# 格式化输出
docker search --format "{{.Name}}: {{.StarCount}}" nginx
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3.7 镜像导出导入
# 导出镜像到 tar 文件
docker save -o nginx.tar nginx:latest
docker save nginx:latest > nginx.tar
# 导出多个镜像
docker save -o images.tar nginx:latest mysql:8.0
# 导入镜像
docker load -i nginx.tar
docker load < nginx.tar
# 查看 tar 文件内容
tar -tvf nginx.tar
2
3
4
5
6
7
8
9
10
11
12
13
使用场景:
- 离线环境部署
- 镜像备份
- 镜像迁移
# 3.8 镜像清理
# 清理未使用的镜像
docker image prune
# 清理所有未使用的镜像(包括有标签的)
docker image prune -a
# 自动确认
docker image prune -a -f
# 查看可清理的空间
docker system df
# 清理所有未使用资源(镜像、容器、网络、数据卷)
docker system prune -a --volumes
2
3
4
5
6
7
8
9
10
11
12
13
14
清理策略:
# 定期清理脚本
#!/bin/bash
echo "清理 Docker 资源..."
# 停止所有容器
docker stop $(docker ps -aq)
# 删除所有容器
docker rm $(docker ps -aq)
# 删除所有未使用的镜像
docker image prune -a -f
# 删除所有未使用的数据卷
docker volume prune -f
# 显示清理后的空间
docker system df
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 📦 4. 容器管理
# 容器命令速查表
| 命令 | 说明 | 常用选项 |
|---|---|---|
docker run | 创建并运行容器 | -d, -p, --name, -v, -e |
docker start | 启动已停止的容器 | <container> |
docker stop | 停止运行中的容器 | -t (超时时间) |
docker restart | 重启容器 | <container> |
docker rm | 删除容器 | -f, -v |
docker ps | 查看容器 | -a, -q, --filter |
docker exec | 在容器中执行命令 | -it, -u |
docker logs | 查看容器日志 | -f, --tail, --since |
docker stats | 查看资源使用 | --no-stream |
docker inspect | 查看容器详情 | <container> |
docker cp | 复制文件 | <src> <dest> |
docker top | 查看容器进程 | <container> |
docker port | 查看端口映射 | <container> |
# 4.1 创建并运行容器(run)
基本语法:
docker run [选项] 镜像名 [命令]
常用选项详解:
| 选项 | 说明 | 示例 |
|---|---|---|
-d | 后台运行(守护进程) | docker run -d nginx |
-p | 端口映射 | -p 8080:80 |
-P | 随机端口映射 | -P |
--name | 指定容器名称 | --name my-nginx |
-v | 挂载数据卷 | -v mydata:/data |
-e | 设置环境变量 | -e NODE_ENV=production |
--rm | 容器停止后自动删除 | --rm |
-it | 交互模式 | -it |
--network | 指定网络 | --network mynet |
-m | 限制内存 | -m 512m |
--cpus | 限制 CPU | --cpus="1.5" |
--restart | 重启策略 | --restart always |
-u | 指定用户 | -u 1000:1000 |
--env-file | 环境变量文件 | --env-file .env |
实战示例:
# 1. 简单运行(前台)
docker run nginx
# 2. 后台运行
docker run -d nginx
# 3. 指定名称和端口
docker run -d --name web -p 8080:80 nginx
# 4. 挂载目录
docker run -d \
--name web \
-p 8080:80 \
-v $(pwd)/html:/usr/share/nginx/html \
nginx
# 5. 设置环境变量
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=mypassword \
-e MYSQL_DATABASE=mydb \
-p 3306:3306 \
mysql:8.0
# 6. 完整配置
docker run -d \
--name myapp \
--restart always \
-p 3000:3000 \
-v app-data:/app/data \
-v $(pwd)/config:/app/config \
-e NODE_ENV=production \
-e DB_HOST=host.docker.internal \
--network app-network \
-m 512m \
--cpus="1" \
myapp:latest
# 7. 交互式运行(用于调试)
docker run -it --rm ubuntu:22.04 bash
# 8. 一次性容器(运行完自动删除)
docker run --rm alpine:latest echo "Hello Docker"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
重启策略:
| 策略 | 说明 |
|---|---|
no | 不自动重启(默认) |
on-failure | 非正常退出时重启 |
on-failure:3 | 最多重启 3 次 |
always | 总是重启 |
unless-stopped | 除非手动停止 |
# 4.2 查看容器(ps)
# 查看运行中的容器
docker ps
# 查看所有容器(包括停止的)
docker ps -a
# 只显示容器 ID
docker ps -q
# 查看最近创建的容器
docker ps -n 5
# 过滤容器
docker ps --filter "name=web"
docker ps --filter "status=running"
docker ps --filter "ancestor=nginx"
# 格式化输出
docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}"
# 显示容器大小
docker ps -s
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 4.3 启动/停止/重启
# 启动已停止的容器
docker start container_name
docker start container_id
# 启动多个容器
docker start web db cache
# 停止容器
docker stop container_name
# 指定超时时间(默认 10 秒)
docker stop -t 30 container_name
# 强制停止(立即停止)
docker kill container_name
# 重启容器
docker restart container_name
# 批量操作
docker stop $(docker ps -q) # 停止所有
docker stop $(docker ps -q --filter ancestor=nginx) # 停止特定镜像的容器
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 4.4 删除容器(rm)
# 删除已停止的容器
docker rm container_name
# 强制删除运行中的容器
docker rm -f container_name
# 删除多个容器
docker rm web db cache
# 删除所有已停止的容器
docker rm $(docker ps -aq -f status=exited)
# 删除所有容器(危险!)
docker rm -f $(docker ps -aq)
# 清理所有已停止的容器
docker container prune
# 自动确认
docker container prune -f
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 4.5 进入容器(exec)
# 进入容器的 bash shell
docker exec -it container_name bash
# 如果容器没有 bash,使用 sh
docker exec -it container_name sh
# 以 root 用户进入
docker exec -u root -it container_name bash
# 在容器中执行单个命令
docker exec container_name ls -la /app
docker exec container_name cat /etc/os-release
# 在容器中执行多个命令
docker exec container_name sh -c "cd /app && npm install"
# 设置环境变量
docker exec -e VAR=value container_name env
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
常用场景:
# 查看容器内部文件
docker exec web ls -la /usr/share/nginx/html
# 查看容器进程
docker exec web ps aux
# 查看容器网络配置
docker exec web ifconfig
docker exec web cat /etc/hosts
# 在容器中安装工具(调试用)
docker exec -u root -it web sh
# 然后在容器内:
apk add --no-cache curl # Alpine
apt-get update && apt-get install -y curl # Debian/Ubuntu
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 4.6 查看日志(logs)
# 查看容器日志
docker logs container_name
# 实时查看日志(类似 tail -f)
docker logs -f container_name
# 查看最后 100 行
docker logs --tail 100 container_name
# 查看最近 10 分钟的日志
docker logs --since 10m container_name
# 查看指定时间后的日志
docker logs --since 2025-01-19T10:00:00 container_name
# 显示时间戳
docker logs -t container_name
# 组合使用
docker logs -f --tail 50 -t container_name
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
日志重定向:
# 保存日志到文件
docker logs container_name > container.log
# 过滤日志
docker logs container_name 2>&1 | grep ERROR
# 统计错误数量
docker logs container_name 2>&1 | grep -c ERROR
2
3
4
5
6
7
8
# 4.7 资源监控(stats)
# 查看所有容器资源使用
docker stats
# 查看特定容器
docker stats container_name
# 不持续更新(只显示一次)
docker stats --no-stream
# 只显示指定列
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
2
3
4
5
6
7
8
9
10
11
输出示例:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
abc123def456 web 0.50% 50MiB / 512MiB 9.77% 1.2MB / 2MB 10MB / 0B
2
# 4.8 文件操作(cp)
# 从主机复制到容器
docker cp local_file.txt container_name:/path/in/container
docker cp ./config/ container_name:/app/config/
# 从容器复制到主机
docker cp container_name:/app/logs/app.log ./logs/
docker cp container_name:/var/log/ ./container_logs/
# 复制到标准输出
docker cp container_name:/etc/nginx/nginx.conf - | tar -xO
2
3
4
5
6
7
8
9
10
实用场景:
# 备份容器配置
docker cp web:/etc/nginx/nginx.conf ./nginx.conf.backup
# 更新容器配置
docker cp ./new_config.json app:/app/config/config.json
docker restart app
# 导出容器日志
docker cp app:/var/log/app.log ./app_$(date +%Y%m%d).log
2
3
4
5
6
7
8
9
# 4.9 容器详细信息(inspect)
# 查看容器完整信息(JSON 格式)
docker inspect container_name
# 提取特定字段
docker inspect --format='{{.State.Status}}' container_name
docker inspect --format='{{.NetworkSettings.IPAddress}}' container_name
docker inspect --format='{{.Config.Image}}' container_name
# 查看容器 IP 地址
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name
# 查看环境变量
docker inspect --format='{{.Config.Env}}' container_name
# 查看挂载点
docker inspect --format='{{.Mounts}}' container_name
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 4.10 其他实用命令
# 查看容器进程
docker top container_name
# 查看端口映射
docker port container_name
docker port container_name 80
# 查看容器文件系统变化
docker diff container_name
# 暂停/恢复容器
docker pause container_name
docker unpause container_name
# 重命名容器
docker rename old_name new_name
# 导出容器文件系统
docker export container_name > container.tar
# 等待容器停止
docker wait container_name
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 📝 5. Dockerfile 编写指南
# 5.1 Dockerfile 指令详解
基础指令:
| 指令 | 说明 | 示例 |
|---|---|---|
FROM | 指定基础镜像 | FROM node:18-alpine |
WORKDIR | 设置工作目录 | WORKDIR /app |
COPY | 复制文件 | COPY package.json ./ |
ADD | 复制文件(支持 URL、自动解压) | ADD app.tar.gz /app |
RUN | 执行命令(构建时) | RUN npm install |
CMD | 容器启动命令(可被覆盖) | CMD ["npm", "start"] |
ENTRYPOINT | 容器入口点(不可覆盖) | ENTRYPOINT ["python"] |
EXPOSE | 声明端口 | EXPOSE 3000 |
ENV | 设置环境变量 | ENV NODE_ENV=production |
ARG | 构建参数 | ARG VERSION=1.0 |
VOLUME | 声明挂载点 | VOLUME /data |
USER | 指定运行用户 | USER node |
LABEL | 添加元数据 | LABEL version="1.0" |
HEALTHCHECK | 健康检查 | HEALTHCHECK CMD curl localhost |
完整 Dockerfile 示例:
# 第一阶段:构建
FROM node:18 AS builder
# 设置工作目录
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
# 安装依赖
RUN npm ci
# 复制源代码
COPY . .
# 构建应用
RUN npm run build
# 第二阶段:生产环境
FROM node:18-alpine
# 设置元数据
LABEL maintainer="[email protected]"
LABEL version="1.0.0"
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000
# 从构建阶段复制文件
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
COPY /app/package.json ./
# 创建非 root 用户
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# 设置文件权限
RUN chown -R nodejs:nodejs /app
# 切换用户
USER nodejs
# 暴露端口
EXPOSE 3000
# 健康检查
HEALTHCHECK \
CMD node healthcheck.js || exit 1
# 声明数据卷
VOLUME /app/data
# 启动命令
CMD ["node", "dist/server.js"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 5.2 最佳实践
1. 使用官方基础镜像
# ✅ 推荐:官方 Alpine 镜像(体积小)
FROM node:18-alpine
# ✅ 推荐:官方镜像
FROM python:3.11-slim
# ❌ 避免:过大的基础镜像
FROM ubuntu:latest
2
3
4
5
6
7
8
2. 合并 RUN 指令(减少层数)
# ❌ 不好:多个 RUN 指令
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git
# ✅ 好:合并为一个 RUN
RUN apt-get update && \
apt-get install -y \
curl \
git && \
rm -rf /var/lib/apt/lists/*
2
3
4
5
6
7
8
9
10
11
3. 利用构建缓存
# ✅ 好:先复制依赖文件
COPY package.json package-lock.json ./
RUN npm install
COPY . .
# ❌ 不好:代码改动导致重新安装依赖
COPY . .
RUN npm install
2
3
4
5
6
7
8
4. 使用 .dockerignore
创建 .dockerignore 文件:
# 依赖
node_modules
npm-debug.log
# Git
.git
.gitignore
# 文档
README.md
docs/
# 环境变量
.env
.env.local
# 构建产物
dist
build
*.log
# IDE
.vscode
.idea
.DS_Store
# 测试
coverage
.nyc_output
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
5. 使用非 root 用户
# 创建用户
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
# 设置权限
RUN chown -R appuser:appgroup /app
# 切换用户
USER appuser
2
3
4
5
6
7
8
9
6. 多阶段构建(减小镜像体积)
# 构建阶段(包含开发工具)
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段(只包含运行时)
FROM node:18-alpine
WORKDIR /app
COPY /app/dist ./dist
COPY /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]
2
3
4
5
6
7
8
9
10
11
12
13
14
7. 添加健康检查
# HTTP 服务健康检查
HEALTHCHECK \
CMD curl -f http://localhost:3000/health || exit 1
# 自定义脚本检查
HEALTHCHECK \
CMD node healthcheck.js || exit 1
# 数据库健康检查
HEALTHCHECK \
CMD mysqladmin ping -h localhost || exit 1
2
3
4
5
6
7
8
9
10
11
# 5.3 常用 Dockerfile 模板
Node.js 应用:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
USER node
EXPOSE 3000
CMD ["node", "server.js"]
2
3
4
5
6
7
8
9
10
11
12
13
14
Python 应用:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m appuser
USER appuser
EXPOSE 8000
CMD ["python", "app.py"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Java 应用(多阶段构建):
# 构建阶段
FROM maven:3.9-eclipse-temurin-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY /app/target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
2
3
4
5
6
7
8
9
10
11
12
13
14
Go 应用(极小镜像):
# 构建阶段
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o app
# 运行阶段(scratch 最小镜像)
FROM scratch
COPY /app/app /app
EXPOSE 8080
CMD ["/app"]
2
3
4
5
6
7
8
9
10
11
12
13
# 🔧 6. Docker Compose
# 6.1 Docker Compose 简介
Docker Compose 是用于定义和运行多容器应用的工具,使用 YAML 文件配置服务。
优势:
- ✅ 一键启动多个服务
- ✅ 统一管理配置
- ✅ 服务依赖管理
- ✅ 环境隔离
# 6.2 常用命令
| 命令 | 说明 |
|---|---|
docker-compose up | 启动所有服务 |
docker-compose up -d | 后台启动 |
docker-compose up --build | 重新构建并启动 |
docker-compose down | 停止并删除所有服务 |
docker-compose down -v | 同时删除数据卷 |
docker-compose start | 启动已存在的服务 |
docker-compose stop | 停止服务 |
docker-compose restart | 重启服务 |
docker-compose ps | 查看服务状态 |
docker-compose logs | 查看日志 |
docker-compose logs -f | 实时查看日志 |
docker-compose exec | 在服务中执行命令 |
docker-compose pull | 拉取所有镜像 |
docker-compose build | 构建所有镜像 |
示例:
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f web
# 进入服务容器
docker-compose exec web sh
# 重启特定服务
docker-compose restart web
# 停止所有服务
docker-compose down
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 6.3 docker-compose.yml 配置详解
基础配置:
version: '3.8'
services:
web:
image: nginx:alpine
container_name: my-web
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
restart: always
environment:
- ENV=production
networks:
app-network:
driver: bridge
volumes:
app-data:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
完整配置示例(全栈应用):
version: '3.8'
services:
# 前端服务
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: frontend
ports:
- "3000:3000"
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- REACT_APP_API_URL=http://localhost:4000
depends_on:
- backend
networks:
- app-network
restart: unless-stopped
# 后端服务
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: backend
ports:
- "4000:4000"
volumes:
- ./backend:/app
- /app/node_modules
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=3306
- DB_NAME=myapp
- DB_USER=root
- DB_PASSWORD=password
- REDIS_HOST=cache
depends_on:
- db
- cache
networks:
- app-network
restart: unless-stopped
# 数据库服务
db:
image: mysql:8.0
container_name: mysql-db
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
environment:
- MYSQL_ROOT_PASSWORD=password
- MYSQL_DATABASE=myapp
networks:
- app-network
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 3s
retries: 3
# 缓存服务
cache:
image: redis:7-alpine
container_name: redis-cache
ports:
- "6379:6379"
volumes:
- cache-data:/data
networks:
- app-network
restart: unless-stopped
command: redis-server --appendonly yes
networks:
app-network:
driver: bridge
volumes:
db-data:
cache-data:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# 6.4 常用配置项说明
服务配置:
services:
app:
# 使用镜像
image: nginx:alpine
# 或构建镜像
build:
context: .
dockerfile: Dockerfile
args:
- NODE_VERSION=18
# 容器名称
container_name: my-app
# 端口映射
ports:
- "8080:80"
- "443:443"
# 数据卷挂载
volumes:
- ./app:/app # 主机目录
- app-data:/data # 命名卷
- /app/node_modules # 匿名卷
# 环境变量
environment:
- NODE_ENV=production
- PORT=3000
# 或从文件读取
env_file:
- .env
- .env.production
# 依赖关系
depends_on:
- db
- cache
# 网络
networks:
- frontend
- backend
# 重启策略
restart: always # no | on-failure | always | unless-stopped
# 资源限制
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 6.5 环境变量管理
方式 1:直接在 docker-compose.yml 中
environment:
- NODE_ENV=production
- DB_HOST=db
2
3
方式 2:使用 .env 文件(推荐)
创建 .env 文件:
NODE_ENV=production
DB_HOST=db
DB_PORT=3306
DB_NAME=myapp
REDIS_HOST=cache
2
3
4
5
在 docker-compose.yml 中引用:
env_file:
- .env
2
方式 3:变量替换
.env 文件:
WEB_PORT=8080
DB_PASSWORD=secret
2
docker-compose.yml:
services:
web:
ports:
- "${WEB_PORT}:80"
db:
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
2
3
4
5
6
7
# 🌐 7. 网络和存储管理
# 7.1 网络类型详解
bridge(桥接网络 - 默认):
# 创建自定义桥接网络
docker network create my-bridge
# 运行容器并连接
docker run -d --name web --network my-bridge nginx
docker run -d --name db --network my-bridge mysql
# 容器间通信(通过容器名)
docker exec web ping db # ✅ 可以 ping 通
2
3
4
5
6
7
8
9
host(主机网络):
# 使用主机网络(性能最好,但失去隔离性)
docker run -d --network host nginx
# 容器直接使用主机的网络栈
# 无需端口映射,直接访问主机端口
2
3
4
5
none(无网络):
# 完全隔离的容器
docker run -d --network none alpine
2
overlay(跨主机网络):
# 用于 Docker Swarm 集群
docker network create -d overlay my-overlay
2
# 7.2 网络管理命令
# 创建网络
docker network create mynetwork
docker network create --driver bridge --subnet=172.18.0.0/16 mynetwork
# 查看网络列表
docker network ls
# 查看网络详情
docker network inspect mynetwork
# 连接容器到网络
docker network connect mynetwork container_name
# 断开网络连接
docker network disconnect mynetwork container_name
# 删除网络
docker network rm mynetwork
# 清理未使用的网络
docker network prune
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 7.3 容器间通信
同一网络的容器可以通过容器名通信:
# 创建网络
docker network create app-net
# 启动数据库
docker run -d \
--name mysql-db \
--network app-net \
-e MYSQL_ROOT_PASSWORD=password \
mysql:8.0
# 启动应用(通过容器名连接数据库)
docker run -d \
--name web-app \
--network app-net \
-e DB_HOST=mysql-db \
-p 3000:3000 \
myapp:latest
# 在 web-app 中可以直接使用 mysql-db 作为主机名
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 7.4 数据卷管理
命名卷(推荐):
# 创建数据卷
docker volume create mydata
# 查看数据卷
docker volume ls
# 查看数据卷详情
docker volume inspect mydata
# 使用数据卷
docker run -d -v mydata:/app/data nginx
# 删除数据卷
docker volume rm mydata
# 清理未使用的数据卷
docker volume prune
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
绑定挂载(Bind Mount):
# 挂载主机目录到容器
docker run -d \
-v $(pwd)/html:/usr/share/nginx/html \
-v $(pwd)/config:/etc/nginx/conf.d \
nginx
# 只读挂载
docker run -d -v $(pwd)/config:/app/config:ro nginx
# 挂载单个文件
docker run -d -v $(pwd)/app.conf:/etc/app.conf nginx
2
3
4
5
6
7
8
9
10
11
tmpfs 挂载(内存存储):
# 挂载 tmpfs(数据在内存中,容器停止后丢失)
docker run -d --tmpfs /tmp nginx
# 指定大小
docker run -d --tmpfs /tmp:size=100m nginx
2
3
4
5
# 7.5 数据备份和恢复
备份数据卷:
# 备份数据卷到 tar 文件
docker run --rm \
-v mydata:/data \
-v $(pwd):/backup \
alpine tar czf /backup/mydata-backup.tar.gz -C /data .
# 或使用更简单的方式
docker run --rm \
-v mydata:/source \
-v $(pwd):/backup \
busybox tar czf /backup/backup.tar.gz /source
2
3
4
5
6
7
8
9
10
11
恢复数据卷:
# 创建新数据卷
docker volume create mydata-restored
# 恢复数据
docker run --rm \
-v mydata-restored:/data \
-v $(pwd):/backup \
alpine sh -c "cd /data && tar xzf /backup/mydata-backup.tar.gz"
2
3
4
5
6
7
8
# 💼 8. 实战案例
# 8.1 Web 服务器
Nginx 静态网站:
# 创建网站目录
mkdir -p ~/my-website/html
echo "<h1>Hello Docker!</h1>" > ~/my-website/html/index.html
# 运行 Nginx
docker run -d \
--name my-website \
-p 8080:80 \
-v ~/my-website/html:/usr/share/nginx/html:ro \
nginx:alpine
# 访问 http://localhost:8080
2
3
4
5
6
7
8
9
10
11
12
Nginx + 自定义配置:
创建 nginx.conf:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api {
proxy_pass http://backend:4000;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
运行:
docker run -d \
--name web \
-p 8080:80 \
-v $(pwd)/html:/usr/share/nginx/html:ro \
-v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
nginx:alpine
2
3
4
5
6
# 8.2 数据库服务
MySQL:
# 运行 MySQL
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=mypassword \
-e MYSQL_DATABASE=myapp \
-e MYSQL_USER=appuser \
-e MYSQL_PASSWORD=apppass \
-p 3306:3306 \
-v mysql-data:/var/lib/mysql \
mysql:8.0
# 连接到 MySQL
docker exec -it mysql-db mysql -uroot -p
# 从主机连接
mysql -h 127.0.0.1 -P 3306 -uroot -p
# 导入 SQL 文件
docker exec -i mysql-db mysql -uroot -ppassword myapp < dump.sql
# 导出数据库
docker exec mysql-db mysqldump -uroot -ppassword myapp > backup.sql
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
PostgreSQL:
# 运行 PostgreSQL
docker run -d \
--name postgres-db \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
-v postgres-data:/var/lib/postgresql/data \
postgres:15
# 连接到数据库
docker exec -it postgres-db psql -U postgres
# 执行 SQL 文件
docker exec -i postgres-db psql -U postgres -d myapp < schema.sql
2
3
4
5
6
7
8
9
10
11
12
13
14
MongoDB:
# 运行 MongoDB
docker run -d \
--name mongodb \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
-p 27017:27017 \
-v mongo-data:/data/db \
mongo:7
# 连接到 MongoDB
docker exec -it mongodb mongosh -u admin -p password
2
3
4
5
6
7
8
9
10
11
Redis:
# 运行 Redis
docker run -d \
--name redis-cache \
-p 6379:6379 \
-v redis-data:/data \
redis:7-alpine \
redis-server --appendonly yes
# 连接到 Redis
docker exec -it redis-cache redis-cli
# 测试 Redis
docker exec redis-cache redis-cli ping
# 输出:PONG
2
3
4
5
6
7
8
9
10
11
12
13
14
# 8.3 开发环境
Node.js 开发环境:
# 运行 Node.js 容器
docker run -it --rm \
-v $(pwd):/app \
-w /app \
-p 3000:3000 \
node:18-alpine \
sh
# 在容器内:
npm init -y
npm install express
node server.js
2
3
4
5
6
7
8
9
10
11
12
Python 开发环境:
# 运行 Python 容器
docker run -it --rm \
-v $(pwd):/app \
-w /app \
-p 8000:8000 \
python:3.11-slim \
bash
# 在容器内:
pip install flask
python app.py
2
3
4
5
6
7
8
9
10
11
# 8.4 完整的全栈应用
项目结构:
my-fullstack-app/
├── docker-compose.yml
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ └── src/
├── backend/
│ ├── Dockerfile
│ ├── package.json
│ └── src/
└── nginx/
└── nginx.conf
2
3
4
5
6
7
8
9
10
11
12
docker-compose.yml:
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- frontend
- backend
networks:
- app-network
frontend:
build: ./frontend
environment:
- REACT_APP_API_URL=/api
networks:
- app-network
backend:
build: ./backend
environment:
- DB_HOST=db
- REDIS_HOST=cache
depends_on:
- db
- cache
networks:
- app-network
db:
image: postgres:15
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_DB=myapp
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
cache:
image: redis:7-alpine
volumes:
- cache-data:/data
networks:
- app-network
networks:
app-network:
volumes:
db-data:
cache-data:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
启动:
# 构建并启动所有服务
docker-compose up -d --build
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs -f
2
3
4
5
6
7
8
# 🐛 9. 故障排查
# 9.1 常见问题 FAQ
Q1: 容器无法启动怎么办?
# 1. 查看容器状态
docker ps -a
# 2. 查看详细错误信息
docker logs container_name
# 3. 查看容器配置
docker inspect container_name
# 4. 尝试交互式运行(调试)
docker run -it --rm image_name sh
2
3
4
5
6
7
8
9
10
11
Q2: 端口已被占用?
# 查看端口占用
lsof -i :8080 # macOS
netstat -tuln | grep 8080 # Linux
# 解决方法:
# 1. 更换端口
docker run -d -p 8081:80 nginx
# 2. 停止占用端口的进程
kill -9 <PID>
# 3. 停止冲突的容器
docker stop $(docker ps -q --filter publish=8080)
2
3
4
5
6
7
8
9
10
11
12
13
Q3: 容器内无法访问网络?
# 1. 检查容器网络
docker exec container_name ping google.com
# 2. 查看 DNS 配置
docker exec container_name cat /etc/resolv.conf
# 3. 检查网络驱动
docker network inspect bridge
# 4. 重启 Docker 服务
# macOS: 重启 Docker Desktop
# Linux:
sudo systemctl restart docker
2
3
4
5
6
7
8
9
10
11
12
13
Q4: 数据丢失了怎么办?
# 检查数据卷是否还在
docker volume ls
# 查看数据卷详情
docker volume inspect volume_name
# 如果数据卷被删除,尝试从备份恢复
# 务必定期备份重要数据!
2
3
4
5
6
7
8
Q5: 容器占用磁盘空间太大?
# 查看 Docker 磁盘使用
docker system df
# 详细信息
docker system df -v
# 清理未使用的资源
docker system prune -a --volumes
# 清理特定类型
docker image prune -a # 清理镜像
docker container prune # 清理容器
docker volume prune # 清理数据卷
2
3
4
5
6
7
8
9
10
11
12
13
Q6: 容器中时间不对?
# 挂载主机时区
docker run -d \
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
nginx
# 或设置时区环境变量
docker run -d \
-e TZ=Asia/Shanghai \
nginx
2
3
4
5
6
7
8
9
10
Q7: 如何访问主机服务?
# macOS/Windows Docker Desktop
docker run -d \
-e DB_HOST=host.docker.internal \
myapp
# Linux
docker run -d \
--add-host=host.docker.internal:host-gateway \
-e DB_HOST=host.docker.internal \
myapp
2
3
4
5
6
7
8
9
10
Q8: 容器性能差怎么优化?
# 1. 查看资源使用
docker stats
# 2. 增加资源限制
docker run -d \
-m 2g \
--cpus="2" \
myapp
# 3. 使用更轻量的基础镜像
# ❌ ubuntu:latest (77MB)
# ✅ alpine:latest (5MB)
# 4. 优化 Dockerfile(减少层数、利用缓存)
2
3
4
5
6
7
8
9
10
11
12
13
14
Q9: 如何调试容器?
# 1. 查看容器日志
docker logs -f container_name
# 2. 进入容器
docker exec -it container_name sh
# 3. 查看容器进程
docker top container_name
# 4. 查看容器文件变化
docker diff container_name
# 5. 导出容器文件系统
docker export container_name > container.tar
tar -tvf container.tar | less
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Q10: 镜像拉取失败?
# 1. 检查网络连接
ping docker.io
# 2. 配置镜像加速器(国内)
# 在 Docker Desktop 设置中添加:
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
# 3. 使用代理
# 在 ~/.docker/config.json 添加:
{
"proxies": {
"default": {
"httpProxy": "http://proxy.example.com:8080",
"httpsProxy": "http://proxy.example.com:8080"
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 9.2 日志查看和分析
# 查看实时日志
docker logs -f container_name
# 查看最近 100 行
docker logs --tail 100 container_name
# 查看特定时间的日志
docker logs --since 2025-01-19T10:00:00 container_name
docker logs --since 10m container_name
# 过滤日志
docker logs container_name 2>&1 | grep ERROR
docker logs container_name 2>&1 | grep -i "exception"
# 保存日志到文件
docker logs container_name > container.log 2>&1
# 统计错误数量
docker logs container_name 2>&1 | grep -c ERROR
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 9.3 性能监控
# 实时监控所有容器
docker stats
# 监控特定容器
docker stats container_name
# 只显示一次
docker stats --no-stream
# 格式化输出
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# 导出监控数据
docker stats --no-stream --format "{{.Container}},{{.CPUPerc}},{{.MemUsage}}" > stats.csv
2
3
4
5
6
7
8
9
10
11
12
13
14
# 9.4 容器健康检查
# 查看健康状态
docker ps
# 显示 health: healthy 或 unhealthy
# 查看健康检查详情
docker inspect --format='{{.State.Health.Status}}' container_name
# 查看健康检查日志
docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' container_name
2
3
4
5
6
7
8
9
# 🚀 10. 最佳实践和优化
# 10.1 安全最佳实践
1. 使用官方镜像
# ✅ 使用官方验证的镜像
FROM node:18-alpine
FROM nginx:alpine
FROM postgres:15
# ❌ 避免使用未知来源的镜像
FROM randomuser/node:latest
2
3
4
5
6
7
2. 扫描镜像漏洞
# 使用 Docker Scout
docker scout cves nginx:latest
# 使用 Trivy
docker run aquasec/trivy image nginx:latest
2
3
4
5
3. 使用非 root 用户
# 创建并使用非 root 用户
RUN addgroup -g 1001 appgroup && \
adduser -S appuser -u 1001 -G appgroup
USER appuser
2
3
4
5
4. 限制容器权限
# 以只读文件系统运行
docker run -d --read-only nginx
# 禁用特权模式
# ❌ docker run --privileged nginx
# 删除不必要的 capabilities
docker run -d --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
2
3
4
5
6
7
8
5. 使用密钥管理
# 使用 Docker secrets(Swarm 模式)
echo "mypassword" | docker secret create db_password -
# 在容器中使用
docker service create \
--name myapp \
--secret db_password \
myapp:latest
2
3
4
5
6
7
8
# 10.2 镜像优化
体积优化:
# ✅ 使用 Alpine 基础镜像
FROM node:18-alpine # ~110MB
# vs
FROM node:18 # ~900MB
# ✅ 多阶段构建
FROM node:18 AS builder
# ... 构建过程
FROM node:18-alpine
COPY /app/dist ./dist
# ✅ 清理缓存
RUN apt-get update && \
apt-get install -y curl && \
rm -rf /var/lib/apt/lists/*
# ✅ 合并层
RUN apk add --no-cache curl git vim
# vs
RUN apk add --no-cache curl
RUN apk add --no-cache git
RUN apk add --no-cache vim
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
缓存优化:
# ✅ 先复制依赖文件(利用缓存)
COPY package*.json ./
RUN npm install
COPY . .
# ❌ 代码改动会重新安装依赖
COPY . .
RUN npm install
2
3
4
5
6
7
8
# 10.3 性能优化
1. 资源限制
# 限制内存和 CPU
docker run -d \
-m 512m \
--memory-swap 1g \
--cpus="1.5" \
--cpu-shares=512 \
nginx
2
3
4
5
6
7
2. 使用合适的存储驱动
# 查看存储驱动
docker info | grep "Storage Driver"
# 推荐:
# - overlay2(最佳性能)
# - devicemapper
2
3
4
5
6
3. 网络性能优化
# 使用 host 网络(性能最好)
docker run -d --network host nginx
# 调整网络 MTU
docker network create --opt com.docker.network.driver.mtu=1450 mynet
2
3
4
5
# 10.4 生产环境建议
1. 健康检查
services:
web:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
2
3
4
5
6
7
8
2. 重启策略
services:
web:
restart: unless-stopped # 推荐
2
3
3. 日志管理
# 限制日志大小
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
2
3
4
5
6
4. 资源限制
services:
web:
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
2
3
4
5
6
7
8
9
10
# 10.5 备份策略
# 备份脚本
#!/bin/bash
# docker_backup.sh
BACKUP_DIR="/backup/docker/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# 备份所有数据卷
for volume in $(docker volume ls -q); do
echo "备份数据卷: $volume"
docker run --rm \
-v "$volume":/source \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/${volume}.tar.gz" -C /source .
done
# 备份镜像
docker save $(docker images -q) -o "$BACKUP_DIR/images.tar"
echo "备份完成: $BACKUP_DIR"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 10.6 监控和日志
监控工具推荐:
| 工具 | 特点 | 使用场景 |
|---|---|---|
docker stats | 内置工具 | 快速查看 |
| Portainer | Web UI 管理 | 可视化管理 |
| cAdvisor | Google 开源 | 容器监控 |
| Prometheus + Grafana | 专业监控 | 生产环境 |
| ELK Stack | 日志收集分析 | 大规模应用 |
Portainer 快速部署:
docker run -d \
-p 9000:9000 \
--name portainer \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
# 访问:http://localhost:9000
2
3
4
5
6
7
8
9
# 10.7 CI/CD 集成
GitLab CI 示例:
# .gitlab-ci.yml
stages:
- build
- test
- deploy
build:
stage: build
script:
- docker build -t myapp:$CI_COMMIT_SHA .
- docker tag myapp:$CI_COMMIT_SHA myapp:latest
test:
stage: test
script:
- docker run --rm myapp:$CI_COMMIT_SHA npm test
deploy:
stage: deploy
script:
- docker push myapp:$CI_COMMIT_SHA
- docker push myapp:latest
only:
- main
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
GitHub Actions 示例:
# .github/workflows/docker.yml
name: Docker Build and Push
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t myapp:latest .
- name: Run tests
run: docker run --rm myapp:latest npm test
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push to Docker Hub
run: docker push myapp:latest
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 📚 11. 学习资源
# 官方文档
- Docker 官方文档 (opens new window)
- Dockerfile 参考 (opens new window)
- Docker Compose 文档 (opens new window)
- Docker Hub (opens new window)
# 在线学习
- Play with Docker (opens new window) - 在线实验环境
- Docker 官方教程 (opens new window)
- Docker 从入门到实践 (opens new window)
# 实用工具
- Portainer (opens new window) - Docker Web 管理界面
- Lazydocker (opens new window) - 终端 UI 管理工具
- Dive (opens new window) - 镜像层分析工具
- Docker Slim (opens new window) - 镜像优化工具
# 镜像仓库
- Docker Hub (opens new window) - 官方公共仓库
- 腾讯云镜像仓库 (opens new window)
- 阿里云容器镜像服务 (opens new window)
- Harbor (opens new window) - 开源私有仓库
# 💡 快速参考
# 常用命令速查
# === 镜像操作 ===
docker pull nginx # 拉取镜像
docker images # 查看镜像
docker rmi nginx # 删除镜像
docker build -t myapp:1.0 . # 构建镜像
# === 容器操作 ===
docker run -d --name web -p 80:80 nginx # 运行容器
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器
docker stop web # 停止容器
docker start web # 启动容器
docker restart web # 重启容器
docker rm web # 删除容器
docker exec -it web sh # 进入容器
# === 日志和监控 ===
docker logs -f web # 查看日志
docker stats # 查看资源使用
docker inspect web # 查看详细信息
# === 清理 ===
docker system prune -a # 清理所有未使用资源
docker container prune # 清理容器
docker image prune -a # 清理镜像
docker volume prune # 清理数据卷
# === Docker Compose ===
docker-compose up -d # 启动服务
docker-compose down # 停止服务
docker-compose ps # 查看状态
docker-compose logs -f # 查看日志
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 完整工作流示例
# 1. 编写 Dockerfile
cat > Dockerfile << 'EOF'
FROM nginx:alpine
COPY html /usr/share/nginx/html
EOF
# 2. 创建网站内容
mkdir html
echo "<h1>Hello Docker</h1>" > html/index.html
# 3. 构建镜像
docker build -t mywebsite:1.0 .
# 4. 运行容器
docker run -d --name web -p 8080:80 mywebsite:1.0
# 5. 测试访问
curl http://localhost:8080
# 6. 查看日志
docker logs web
# 7. 进入容器调试
docker exec -it web sh
# 8. 停止并删除
docker stop web
docker rm web
# 9. 清理镜像
docker rmi mywebsite:1.0
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 🎯 总结
Docker 核心要点:
- ✅ 镜像:应用的模板,只读、分层、可复用
- ✅ 容器:镜像的运行实例,轻量、隔离、可移植
- ✅ 数据卷:持久化数据,容器删除后数据保留
- ✅ 网络:容器间通信,支持多种网络模式
- ✅ Dockerfile:定义镜像构建过程,可版本化
- ✅ Docker Compose:管理多容器应用,一键部署
- ✅ 最佳实践:安全、性能、可维护性
掌握 Docker,让你的应用"一次构建,到处运行"!🚀