教程来源《Docker入门到项目实战》

1. 基础概念

1.1 为什么有Docker?

传统部署的痛点

  • 环境不一致:”在我机器上能跑”的经典问题
  • 依赖管理复杂:版本冲突和依赖地狱
  • 资源利用率低:虚拟机资源开销大
  • 部署流程繁琐:手动配置容易出错

Docker的核心优势

特性 说明 对比传统方式
轻量级虚拟化 共享宿主机内核,启动速度快 比虚拟机节省90%资源
环境一致性 开发、测试、生产环境完全统一 消除环境差异问题
快速部署 秒级启动,支持水平扩展 部署时间从分钟级降到秒级
资源高效 容器间共享操作系统 单机可运行更多应用实例

1.2 Docker架构与容器化

系统架构图

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─────────────────────────────────────────────────────────┐
│ Docker架构 │
├─────────────────────────────────────────────────────────┤
│ Docker Client │
│ ├─ docker build ├─ docker pull ├─ docker run │
├─────────────────────────────────────────────────────────┤
│ Docker Daemon (dockerd) │
│ ├─ API Server ├─ Image Manager ├─ Container Mgr │
├─────────────────────────────────────────────────────────┤
│ Docker Objects │
│ ├─ Images ├─ Containers ├─ Networks │
│ └─ Volumes └─ Plugins └─ Services │
└─────────────────────────────────────────────────────────┘

核心概念解析

组件 定义 作用 示例
镜像(Image) 只读模板,包含应用运行环境 创建容器的基础 nginx:latest
容器(Container) 镜像的运行实例 应用的实际运行环境 运行中的Web服务
仓库(Registry) 镜像存储和分发中心 镜像版本管理 Docker Hub
Dockerfile 镜像构建脚本 自动化构建镜像 包含FROM、RUN等指令

2. Docker命令操作

2.1 镜像操作

镜像生命周期管理

搜索和获取镜像

1
2
3
4
5
6
# 在Docker Hub搜索镜像
docker search nginx

# 拉取指定版本镜像
docker pull nginx:1.21-alpine
docker pull nginx:latest

查看和检查镜像

1
2
3
4
5
6
7
8
9
# 列出本地所有镜像
docker images
docker image ls

# 查看镜像详细信息
docker inspect nginx:latest

# 查看镜像构建历史
docker history nginx:latest

镜像标签和清理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 为镜像创建新标签
docker tag nginx:latest mynginx:v1.0
docker tag nginx:latest registry.example.com/mynginx:v1.0

# 删除镜像(按标签)
docker rmi nginx:latest
docker image rm nginx:latest

# 删除镜像(按ID)
docker rmi 605c77e624dd

# 清理未使用的镜像
docker image prune
docker image prune -a # 删除所有未使用的镜像

2.2 容器操作

容器创建和运行

基础运行模式

1
2
3
4
5
6
7
8
# 前台运行
docker run nginx:latest

# 后台运行
docker run -d nginx:latest

# 交互式运行
docker run -it ubuntu:20.04 /bin/bash

高级运行配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 完整配置示例
docker run -d \
--name my-nginx \
-p 8080:80 \
-v /host/data:/usr/share/nginx/html \
--restart unless-stopped \
--memory 512m \
--cpus 0.5 \
nginx:latest

# 环境变量配置
docker run -d \
--name my-app \
-e NODE_ENV=production \
-e PORT=3000 \
node:16-alpine

容器状态管理

查看容器状态

1
2
3
4
5
6
7
8
9
10
11
12
# 查看运行中的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 查看容器详细信息
docker inspect my-nginx

# 实时监控容器资源使用
docker stats
docker stats my-nginx # 监控特定容器

容器生命周期控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 普通停止容器(发送SIGTERM信号)
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

容器交互和调试

进入容器

1
2
3
4
5
6
7
# 在运行中的容器执行命令
docker exec -it my-nginx /bin/bash
docker exec -it my-nginx sh

# 执行单个命令
docker exec my-nginx ls -la /usr/share/nginx/html
docker exec my-nginx nginx -t # 测试nginx配置

日志和监控

1
2
3
4
5
6
7
8
9
10
11
# 查看容器日志
docker logs my-nginx

# 实时跟踪日志
docker logs -f my-nginx

# 查看最近N行日志
docker logs --tail 50 my-nginx

# 带时间戳的日志
docker logs -t my-nginx

容器清理

1
2
3
4
5
6
7
8
9
10
11
# 删除停止的容器
docker rm my-nginx

# 强制删除运行中的容器
docker rm -f my-nginx

# 删除所有停止的容器
docker container prune

# 强制删除所有容器
docker rm -f $(docker ps -aq)

2.3 docker run

常用参数

1
2
3
4
5
6
7
8
9
10
11
12
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

# 重要参数说明:
-d, --detach # 后台运行
-it # 交互式终端
--name # 指定容器名称
-p, --publish # 端口映射
-v, --volume # 数据卷挂载
-e, --env # 环境变量
--network # 指定网络
--restart # 重启策略
--rm # 容器停止后自动删除

实际示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 运行MySQL容器
docker run -d \
--name mysql-server \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v mysql-data:/var/lib/mysql \
--restart unless-stopped \
mysql:8.0

# 运行Redis容器
docker run -d \
--name redis-server \
-p 6379:6379 \
-v redis-data:/data \
--restart unless-stopped \
redis:7-alpine redis-server --appendonly yes

2.4 保存和分享镜像

保存镜像到文件

1
2
3
4
5
6
7
8
9
10
11
# 保存镜像为tar文件
docker save -o nginx.tar nginx:latest

# 从tar文件加载镜像
docker load -i nginx.tar

# 导出容器为镜像
docker export mynginx > mynginx.tar

# 导入容器镜像
docker import mynginx.tar mynginx:v1.0

分享镜像到仓库

1
2
3
4
5
6
7
8
# 登录Docker Hub
docker login

# 推送镜像
docker push username/mynginx:v1.0

# 从仓库拉取
docker pull username/mynginx:v1.0

3. 存储管理

3.1 数据持久化策略

存储类型对比

存储类型 特点 使用场景 性能 可移植性
Volumes Docker管理,独立于容器 数据库、配置文件 优秀
Bind Mounts 直接挂载主机目录 开发环境、代码同步 依赖主机
tmpfs 内存存储,临时数据 缓存、临时文件 最高 不持久

3.2 目录挂载 (Bind Mounts)

基本概念

  • 将宿主机的目录或文件直接挂载到容器内
  • 路径必须是绝对路径
  • 适合开发环境和配置文件挂载
  • 性能优秀,但依赖主机文件系统

实际操作示例

1
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
# 基础目录挂载
docker run -d \
--name nginx-web \
-p 8080:80 \
-v /host/path:/container/path \
nginx

# Windows路径示例
docker run -d \
--name nginx-web \
-p 8080:80 \
-v D:/web:/usr/share/nginx/html \
nginx

# 只读挂载
docker run -d \
--name nginx-web \
-p 8080:80 \
-v D:/web:/usr/share/nginx/html:ro \
nginx

# 开发环境代码同步
docker run -d \
--name dev-app \
-p 3000:3000 \
-v $(pwd):/app \
-v /app/node_modules \
node:18-alpine npm run dev

3.3 数据卷(Docker Volumes)

数据卷优势

  • 由 Docker 管理,更安全可靠
  • 可以在容器间共享和重用
  • 支持远程存储驱动
  • 备份和迁移更方便
  • 跨平台兼容性好
  • 支持卷驱动插件

卷管理操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 创建命名数据卷
docker volume create mysql-data
docker volume create --driver local mysql-data

# 查看所有数据卷
docker volume ls

# 查看数据卷详细信息
docker volume inspect mysql-data

# 删除数据卷
docker volume rm mysql-data

# 清理未使用的数据卷
docker volume prune
docker volume prune -f # 强制清理

数据卷使用模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 命名卷挂载
docker run -d \
--name mysql-db \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0

# 匿名卷(Docker自动创建)
docker run -d \
--name redis-cache \
-v /data \
redis:7-alpine

# 只读挂载
docker run -d \
-v config-vol:/etc/nginx/conf.d:ro \
nginx:latest

# 多卷挂载
docker run -d \
-v app-data:/app/data \
-v app-logs:/app/logs \
-v app-config:/app/config:ro \
my-app:latest

数据卷备份与恢复

1
2
3
4
5
6
7
8
9
10
11
# 备份数据卷
docker run --rm \
-v mysql-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/mysql-backup.tar.gz -C /data .

# 恢复数据卷
docker run --rm \
-v mysql-data:/data \
-v $(pwd):/backup \
alpine tar xzf /backup/mysql-backup.tar.gz -C /data

4. 网络配置

4.1 网络驱动类型

网络驱动对比

网络类型 适用场景 隔离性 性能 配置复杂度
bridge 单主机容器通信 中等 简单
host 高性能网络需求 最高 最简单
none 完全隔离环境 最高 无网络 简单
overlay 跨主机集群 中等 复杂
macvlan 物理网络集成 复杂

4.2 网络管理操作

基础网络命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看所有网络
docker network ls

# 查看网络详细信息
docker network inspect bridge
docker network inspect my-network

# 创建自定义网络
docker network create my-network
docker network create --driver bridge my-bridge
docker network create --driver bridge --subnet=172.20.0.0/16 my-subnet

# 删除网络
docker network rm my-network

# 清理未使用的网络
docker network prune
docker network prune -f

容器网络连接

1
2
3
4
5
6
7
8
# 创建容器时指定网络
docker run -d --name web --network mynetwork nginx

# 将运行中的容器连接到网络
docker network connect mynetwork existing-container

# 断开容器网络连接
docker network disconnect mynetwork existing-container

4.2 Redis主从集群实战

创建Redis网络

1
2
# 创建专用网络
docker network create redis-network

Redis主从节点配置

启动Redis主节点

1
2
3
4
5
docker run -d \
--name redis-master \
--network redis-network \
-p 6379:6379 \
redis:7-alpine redis-server --appendonly yes

启动Redis从节点

1
2
3
4
5
6
7
8
9
10
11
12
13
# 从节点1
docker run -d \
--name redis-slave1 \
--network redis-network \
-p 6380:6379 \
redis:7-alpine redis-server --slaveof redis-master 6379 --appendonly yes

# 从节点2
docker run -d \
--name redis-slave2 \
--network redis-network \
-p 6381:6379 \
redis:7-alpine redis-server --slaveof redis-master 6379 --appendonly yes

测试主从同步

1
2
3
4
5
6
7
8
9
# 连接主节点写入数据
docker exec -it redis-master redis-cli
127.0.0.1:6379> set name "Docker"
127.0.0.1:6379> exit

# 连接从节点读取数据
docker exec -it redis-slave1 redis-cli
127.0.0.1:6379> get name
"Docker"

4.3 实践关注点:网络、存储、环境变量

最佳实践


5. Docker-Compose

5.1 Compose核心概念

Docker Compose简介

Docker Compose 是 Docker 官方的容器编排工具,通过 YAML 文件定义多容器应用的完整架构,实现一键部署和管理。

核心优势

  • 声明式配置:通过 YAML 文件描述整个应用架构
  • 服务发现:容器间可通过服务名直接通信
  • 依赖管理:自动处理服务启动顺序
  • 环境隔离:不同项目间完全隔离
  • 扩展性:支持服务水平扩展
  • 开发友好:本地开发环境快速搭建

架构组件

组件 作用 示例
Service 应用程序的逻辑组件 web服务、数据库服务
Project 相关服务的集合 完整的Web应用
Network 服务间通信网络 前端网络、后端网络
Volume 数据持久化存储 数据库数据、配置文件

5.2 WordPress实战案例

项目结构

1
2
3
4
5
6
7
8
wordpress-project/
├── docker-compose.yml
├── nginx/
│ └── nginx.conf
├── wordpress/
│ └── themes/
└── mysql/
└── init.sql

完整docker-compose.yml

1
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
version: '3.8'

services:
# Nginx反向代理
nginx:
image: nginx:1.21-alpine
container_name: wordpress-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- wordpress-data:/var/www/html:ro
depends_on:
- wordpress
networks:
- frontend
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3

# WordPress应用
wordpress:
image: wordpress:6.3-php8.2-fpm-alpine
container_name: wordpress-app
environment:
WORDPRESS_DB_HOST: mysql-db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress123
WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: wp_
WORDPRESS_DEBUG: 'false'
volumes:
- wordpress-data:/var/www/html
- ./wordpress/themes:/var/www/html/wp-content/themes
- ./wordpress/plugins:/var/www/html/wp-content/plugins
depends_on:
mysql:
condition: service_healthy
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "php-fpm-healthcheck"]
interval: 30s
timeout: 10s
retries: 3

# MySQL数据库
mysql:
image: mysql:8.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress123
MYSQL_CHARSET: utf8mb4
MYSQL_COLLATION: utf8mb4_unicode_ci
volumes:
- mysql-data:/var/lib/mysql
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'

# Redis缓存
redis:
image: redis:7-alpine
container_name: wordpress-redis
command: redis-server --appendonly yes --maxmemory 256mb
volumes:
- redis-data:/data
networks:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3

# 数据卷定义
volumes:
wordpress-data:
driver: local
mysql-data:
driver: local
redis-data:
driver: local

# 网络定义
networks:
frontend:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
backend:
driver: bridge
internal: true

部署和管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 启动完整服务栈
docker compose up -d

# 查看服务状态
docker compose ps

# 查看特定服务日志
docker compose logs -f wordpress

# 扩展WordPress实例
docker compose up -d --scale wordpress=3

# 重启特定服务
docker compose restart nginx

# 停止服务(保留数据)
docker compose stop

# 完全清理(删除容器和网络,保留数据卷)
docker compose down

# 删除所有数据
docker compose down -v

5.3 Docker Compose语法

核心配置项

1
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
version: '3.8'  # Compose 文件版本

services: # 服务定义
service-name:
image: nginx:latest # 使用镜像
build: ./app # 构建镜像
container_name: my-nginx # 容器名称
ports: # 端口映射
- "8080:80"
- "443:443"
volumes: # 数据卷挂载
- ./data:/app/data
- named-volume:/app/logs
environment: # 环境变量
- NODE_ENV=production
- API_KEY=secret
env_file: # 环境变量文件
- .env
depends_on: # 服务依赖
- database
- redis
networks: # 网络配置
- app-network
restart: unless-stopped # 重启策略
healthcheck: # 健康检查
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3

volumes: # 数据卷定义
named-volume:
driver: local

networks: # 网络定义
app-network:
driver: bridge

常用 Compose 命令

1
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
# 启动服务(后台运行)
docker compose up -d

# 构建并启动
docker compose up -d --build

# 停止服务
docker compose stop

# 停止并删除容器
docker compose down

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs [service-name]

# 重启服务
docker compose restart [service-name]

# 扩展服务实例
docker compose up -d --scale web=3

# 执行命令
docker compose exec service-name bash

6. Dockerfile镜像构建

6.1 Dockerfile核心概念

Dockerfile简介

Dockerfile 是声明式的镜像构建脚本,通过一系列指令定义镜像的构建过程。每个指令都会创建一个新的镜像层,最终形成完整的应用镜像。

构建原理

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────┐
│ Dockerfile 构建流程 │
├─────────────────────────────────────────┤
│ FROM base-image │ ← 基础镜像层
├─────────────────────────────────────────┤
│ RUN install dependencies │ ← 依赖安装层
├─────────────────────────────────────────┤
│ COPY application code │ ← 应用代码层
├─────────────────────────────────────────┤
│ CMD start application │ ← 启动命令层
└─────────────────────────────────────────┘

6.2 Dockerfile指令详解

核心指令对比

指令 作用 执行时机 缓存特性 最佳实践
FROM 指定基础镜像 构建时 强缓存 选择官方、轻量镜像
RUN 执行Shell命令 构建时 层缓存 合并命令减少层数
COPY 复制文件到镜像 构建时 内容缓存 优先复制依赖文件
ADD 复制+解压+下载 构建时 内容缓存 仅在需要特殊功能时使用
WORKDIR 设置工作目录 构建时 强缓存 使用绝对路径
EXPOSE 声明端口 文档化 无影响 明确声明所有端口
ENV 设置环境变量 构建+运行时 强缓存 合理使用,避免敏感信息
CMD 默认启动命令 运行时 无影响 使用exec格式
ENTRYPOINT 入口点命令 运行时 无影响 与CMD配合使用

指令使用示例

1
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
# 基础镜像选择
FROM node:18-alpine AS base
# FROM python:3.11-slim AS base
# FROM golang:1.21-alpine AS base

# 环境变量设置
ENV NODE_ENV=production \
APP_PORT=3000 \
APP_USER=appuser

# 工作目录设置
WORKDIR /app

# 系统包安装(合并命令)
RUN apk add --no-cache \
curl \
ca-certificates \
&& rm -rf /var/cache/apk/*

# 用户创建
RUN addgroup -g 1001 -S $APP_USER \
&& adduser -S $APP_USER -u 1001 -G $APP_USER

# 依赖文件复制(利用缓存)
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# 应用代码复制
COPY --chown=$APP_USER:$APP_USER . .

# 权限设置
USER $APP_USER

# 端口声明
EXPOSE $APP_PORT

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:$APP_PORT/health || exit 1

# 启动命令
CMD ["npm", "start"]

6.3 多阶段构建实战

Node.js应用优化构建

1
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
# ================================
# 多阶段构建:Node.js 应用
# ================================

# 阶段1:依赖安装和构建
FROM node:18-alpine AS builder

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY package*.json ./

# 安装所有依赖(包括开发依赖)
RUN npm ci

# 复制源代码
COPY . .

# 构建应用
RUN npm run build

# 阶段2:生产环境镜像
FROM node:18-alpine AS production

# 安装系统依赖
RUN apk add --no-cache \
dumb-init \
curl \
&& rm -rf /var/cache/apk/*

# 创建应用用户
RUN addgroup -g 1001 -S nodejs \
&& adduser -S nextjs -u 1001 -G nodejs

# 设置工作目录
WORKDIR /app

# 复制依赖文件并安装生产依赖
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# 从构建阶段复制构建产物
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

# 切换到非root用户
USER nextjs

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1

# 使用dumb-init作为PID 1
ENTRYPOINT ["dumb-init", "--"]
CMD ["npm", "start"]

Python 应用多阶段构建

1
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
# ================================
# 多阶段构建:Python 应用
# ================================

# 阶段1:依赖构建
FROM python:3.11-slim AS builder

# 安装构建工具
RUN apt-get update && apt-get install -y \
build-essential \
gcc \
&& rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /app

# 复制依赖文件
COPY requirements.txt .

# 创建虚拟环境并安装依赖
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir -r requirements.txt

# 阶段2:运行时镜像
FROM python:3.11-slim AS production

# 安装运行时依赖
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/*

# 创建应用用户
RUN groupadd -r appuser && useradd -r -g appuser appuser

# 设置工作目录
WORKDIR /app

# 从构建阶段复制虚拟环境
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# 复制应用代码
COPY --chown=appuser:appuser . .

# 切换到非root用户
USER appuser

# 暴露端口
EXPOSE 8000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

# 启动命令
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

构建和优化命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 基础构建
docker build -t myapp:v1.0 .

# 指定 Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .

# 构建时传递参数
docker build --build-arg NODE_VERSION=18 -t myapp:v1.0 .

# 多平台构建
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:v1.0 .

# 构建缓存优化
docker build --cache-from myapp:latest -t myapp:v1.1 .

# 查看镜像层信息
docker history myapp:v1.0

# 分析镜像大小
docker images myapp:v1.0

7. 实践与优化

7.1 Dockerfile实践

镜像优化策略

优化方向 具体措施 效果 示例
镜像大小 使用Alpine基础镜像 减少90%体积 node:18-alpine vs node:18
构建缓存 优化COPY指令顺序 提升构建速度 先复制依赖文件,后复制源码
安全性 非root用户运行 降低安全风险 USER appuser
多阶段构建 分离构建和运行环境 减少最终镜像大小 构建阶段 + 运行阶段

完整实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
FROM node:18-alpine

# 创建非特权用户
RUN addgroup -g 1001 -S appgroup \
&& adduser -S appuser -u 1001 -G appgroup

# 设置工作目录
WORKDIR /app

# 复制并设置文件权限
COPY --chown=appuser:appgroup package*.json ./
RUN npm ci --only=production && npm cache clean --force

COPY --chown=appuser:appgroup . .

# 切换到非root用户
USER appuser

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1

CMD ["npm", "start"]

7.2 生产环境部署指南

环境配置管理

1
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
# docker-compose.prod.yml
version: '3.8'

services:
app:
image: myapp:${APP_VERSION:-latest}
environment:
- NODE_ENV=production
- DB_HOST=${DB_HOST}
- DB_PASSWORD_FILE=/run/secrets/db_password
secrets:
- db_password
deploy:
replicas: 3
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s

secrets:
db_password:
external: true

监控和日志配置

1
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
# 添加到 docker-compose.yml
services:
app:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels:
- "prometheus.io/scrape=true"
- "prometheus.io/port=3000"
- "prometheus.io/path=/metrics"

# Prometheus监控
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'

# Grafana可视化
grafana:
image: grafana/grafana:latest
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
volumes:
- grafana-data:/var/lib/grafana

volumes:
prometheus-data:
grafana-data:

7.3 故障排查

常见问题及解决方案

问题1:端口被占用
1
2
3
4
5
6
7
8
9
10
11
12
# 错误信息
Error: bind: address already in use

# 解决方案
# 1.查看端口占用
netstat -tulpn | grep :8080

# 2.更换端口
docker run -p 8081:80 nginx

# 3.停止占用端口的容器
docker stop <container_id>
问题2:镜像拉取失败
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 错误信息
Error response from daemon: pull access denied

# 解决方案
# 1.使用国内镜像源
docker pull registry.cn-hangzhou.aliyuncs.com/library/nginx:latest

# 2.配置镜像加速器
# 编辑 /etc/docker/daemon.json
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://registry.docker-cn.com"
]
}
问题3:容器无法访问
1
2
3
4
5
6
7
8
9
10
11
# 检查容器状态
docker ps

# 检查端口映射
docker port <container_name>

# 查看容器日志
docker logs <container_name>

# 进入容器调试
docker exec -it <container_name> bash
问题4:磁盘空间不足
1
2
3
4
5
6
7
8
9
10
11
# 查看Docker磁盘使用
docker system df

# 清理未使用的资源
docker system prune

# 清理所有未使用的镜像
docker image prune -a

# 清理所有停止的容器
docker container prune

8. 项目实战

8.1 一键启动所有中间件

完整的开发环境

1
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
90
91
92
93
94
95
96
version: '3.8'

services:
# MySQL数据库
mysql:
image: mysql:8.0
container_name: dev-mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: devdb
volumes:
- mysql-data:/var/lib/mysql
networks:
- dev-network

# Redis缓存
redis:
image: redis:7-alpine
container_name: dev-redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- dev-network

# MongoDB文档数据库
mongodb:
image: mongo:6
container_name: dev-mongodb
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin123
volumes:
- mongodb-data:/data/db
networks:
- dev-network

# Elasticsearch搜索引擎
elasticsearch:
image: elasticsearch:8.8.0
container_name: dev-elasticsearch
ports:
- "9200:9200"
environment:
- discovery.type=single-node
- xpack.security.enabled=false
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
networks:
- dev-network

# RabbitMQ消息队列
rabbitmq:
image: rabbitmq:3-management
container_name: dev-rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: admin
RABBITMQ_DEFAULT_PASS: admin123
volumes:
- rabbitmq-data:/var/lib/rabbitmq
networks:
- dev-network

# Nginx反向代理
nginx:
image: nginx:alpine
container_name: dev-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
networks:
- dev-network
depends_on:
- mysql
- redis

volumes:
mysql-data:
redis-data:
mongodb-data:
elasticsearch-data:
rabbitmq-data:

networks:
dev-network:
driver: bridge

8.2 访问测试验证

测试脚本

1
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
#!/bin/bash

echo "启动开发环境..."
docker compose up -d

echo "等待服务启动..."
sleep 30

echo "测试服务连接..."

# 测试 MySQL
echo "测试 MySQL 连接..."
docker exec dev-mysql mysql -uroot -proot123 -e "SELECT 'MySQL OK' as status;"

# 测试 Redis
echo "测试 Redis 连接..."
docker exec dev-redis redis-cli ping

# 测试 MongoDB
echo "测试 MongoDB 连接..."
docker exec dev-mongodb mongosh --eval "db.runCommand('ping')"

# 测试 Elasticsearch
echo "测试 Elasticsearch 连接..."
curl -s http://localhost:9200/_cluster/health | jq '.status'

# 测试 RabbitMQ
echo "测试 RabbitMQ 管理界面..."
curl -s -u admin:admin123 http://localhost:15672/api/overview | jq '.product_name'

echo "所有服务测试完成!"
echo "访问地址:"
echo " - RabbitMQ 管理界面: http://localhost:15672 (admin/admin123)"
echo " - Elasticsearch: http://localhost:9200"
echo " - MySQL: localhost:3306 (root/root123)"
echo " - Redis: localhost:6379"
echo " - MongoDB: localhost:27017 (admin/admin123)"

9. 总结

9.1 核心知识点

基础概念

  • 理解容器化技术优势
  • 掌握镜像、容器、仓库关系
  • 熟悉Docker架构组件

命令操作

  • 镜像管理:pull、build、push、tag
  • 容器操作:run、start、stop、exec
  • 系统管理:system、volume、network

高级特性

  • 数据持久化:Volumes和Bind Mounts
  • 网络配置:自定义网络和服务发现
  • 服务编排:Docker Compose多容器应用
  • 镜像构建:Dockerfile最佳实践

9.2 学习资源

官方文档

其他资源