教程来源:《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 学习资源

官方文档

其他资源