vault backup: 2026-04-28 21:55:18
This commit is contained in:
+211
-277
@@ -1,55 +1,76 @@
|
||||
---
|
||||
tags:
|
||||
- docker
|
||||
- devops
|
||||
- containerization
|
||||
- docker-compose
|
||||
create time: 2026-04-28 14:35
|
||||
---
|
||||
|
||||
# Docker Compose 使用指南
|
||||
|
||||
> Docker Compose 用 **YAML 文件**定义多容器应用,一条 `docker compose up` 启动所有服务。**开发环境和生产环境都大量使用。**
|
||||
> 用 **YAML 文件**定义多容器应用,一条 `docker compose up` 启动所有服务。从"一条命令跑起全栈"到多环境编排,本文带你掌握 Compose 从入门到进阶的所有关键能力。
|
||||
|
||||
---
|
||||
## 概述
|
||||
|
||||
## 快速开始(TL;DR)
|
||||
Docker Compose 的核心价值:**把分散的 `docker run` 命令变成声明式的 YAML 配置**,让团队用同一份文件即可启动完整应用栈。
|
||||
|
||||
```bash
|
||||
# 1. 创建 docker-compose.yml
|
||||
# 2. 启动所有服务
|
||||
docker compose up -d
|
||||
> [!tip] 快速上手(TL;DR)
|
||||
>
|
||||
> ```bash
|
||||
> # 1. 写好 docker-compose.yml,包含所有服务
|
||||
> # 2. 一条命令启动全部
|
||||
> docker compose up -d
|
||||
> # 3. 看日志、看状态
|
||||
> docker compose logs -f
|
||||
> docker compose ps
|
||||
> # 4. 清理
|
||||
> docker compose down
|
||||
> ```
|
||||
|
||||
# 3. 查看状态
|
||||
docker compose ps
|
||||
> [!question] 什么时候需要 Compose?
|
||||
> 如果你的应用只跑一个进程(比如单个 Nginx),`docker run` 就够了。但只要涉及**两个及以上**的容器协作(应用 + 数据库、前端 + API + 缓存),Compose 就是标配。
|
||||
|
||||
# 4. 查看日志
|
||||
docker compose logs -f
|
||||
## 正文
|
||||
|
||||
# 5. 停止并清理
|
||||
docker compose down
|
||||
### 一、Compose 文件结构
|
||||
|
||||
Compose 文件由三个顶级字段构成,理解它们就能掌握 80% 的配置:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["services — 要跑的服务"] --> D["docker compose up"]
|
||||
B["networks — 服务间的网络"] --> D
|
||||
C["volumes — 数据持久化"] --> D
|
||||
style A fill:#e3f2fd
|
||||
style B fill:#f3e5f5
|
||||
style C fill:#e8f5e9
|
||||
```
|
||||
|
||||
**目录:** [基本结构](#一基本结构) · [完整示例](#二完整示例) · [常用配置](#三常用配置详解) · [多环境](#四多环境配置) · [常用命令](#五常用命令) · [常见问题](#六常见问题) · [模板速查](#七常用模板速查) · [格式演进](#八compose-文件格式演进) · [高级配置](#九高级配置) · [最佳实践](#十最佳实践) · [速查卡](#十一快速参考卡)
|
||||
|
||||
---
|
||||
|
||||
## 一、基本结构
|
||||
基本结构示例:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
web: # 前端/后端应用
|
||||
db: # 数据库
|
||||
redis: # 缓存
|
||||
nginx: # 反向代理
|
||||
web: # 前端/后端应用
|
||||
db: # 数据库
|
||||
redis: # 缓存
|
||||
nginx: # 反向代理
|
||||
|
||||
networks: # 网络定义
|
||||
volumes: # 数据卷定义
|
||||
networks: # 网络定义
|
||||
volumes: # 数据卷定义
|
||||
```
|
||||
|
||||
> [!note] `version` 字段已弃用
|
||||
> Compose V2(2020年起)已不需要 `version` 字段。新项目直接用无 version 的新格式,兼容性更好。
|
||||
|
||||
---
|
||||
|
||||
## 二、完整示例
|
||||
### 二、完整示例:Node.js + MySQL + Redis 全栈项目
|
||||
|
||||
### 2.1 Node.js + MySQL + Redis 全栈项目
|
||||
一个生产级别的 Compose 文件应该包含**健康检查、网络隔离、数据持久化**:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# ========== 后端应用 ==========
|
||||
api:
|
||||
@@ -58,24 +79,25 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
NODE_ENV: production
|
||||
target: production
|
||||
container_name: my-api
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DB_HOST=db
|
||||
- DB_PORT=3306
|
||||
- DB_USER=root
|
||||
- DB_PASSWORD=root123
|
||||
- DB_NAME=mydb
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
NODE_ENV: production
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
DB_USER: root
|
||||
DB_PASSWORD: root123
|
||||
DB_NAME: mydb
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
condition: service_healthy # 等 db 健康检查通过再启动
|
||||
redis:
|
||||
condition: service_started
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- app-network
|
||||
volumes:
|
||||
@@ -91,7 +113,7 @@ services:
|
||||
- "80:3000"
|
||||
depends_on:
|
||||
- api
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
@@ -114,7 +136,8 @@ services:
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
restart: always
|
||||
start_period: 30s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
@@ -127,7 +150,7 @@ services:
|
||||
volumes:
|
||||
- redis-data:/data
|
||||
command: redis-server --appendonly yes
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
@@ -143,7 +166,7 @@ services:
|
||||
depends_on:
|
||||
- web
|
||||
- api
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
@@ -159,11 +182,17 @@ volumes:
|
||||
api-logs:
|
||||
```
|
||||
|
||||
> [!warning] 服务启动顺序
|
||||
> 理解这个示例的启动链:**db + redis 先启动 → api 启动(依赖它们就绪)→ web 启动(依赖 api 就绪)→ nginx 启动(依赖前端和后端)**。用 `depends_on` + `healthcheck` 确保这个顺序。
|
||||
|
||||
---
|
||||
|
||||
## 三、常用配置详解
|
||||
### 三、常用配置详解
|
||||
|
||||
### 3.1 `build` — 从 Dockerfile 构建
|
||||
#### 3.1 `build` — 从 Dockerfile 构建
|
||||
|
||||
> [!info] build 与 image 的选择
|
||||
> 开发环境通常用 `build`(代码改动自动重构建),生产环境可以用 `image`(提前打好镜像推送仓库)。
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -177,7 +206,7 @@ services:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile.prod
|
||||
|
||||
# 方式三:加构建参数
|
||||
# 方式三:加构建参数 + 多阶段指定目标
|
||||
web:
|
||||
build:
|
||||
context: .
|
||||
@@ -185,14 +214,14 @@ services:
|
||||
args:
|
||||
NODE_ENV: production
|
||||
VERSION: 1.0.0
|
||||
target: production # 多阶段构建指定阶段
|
||||
target: production
|
||||
|
||||
# 方式四:直接用已有镜像(不构建)
|
||||
db:
|
||||
image: mysql:8.0
|
||||
```
|
||||
|
||||
### 3.2 `depends_on` — 启动顺序
|
||||
#### 3.2 `depends_on` — 启动顺序
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -204,9 +233,13 @@ services:
|
||||
condition: service_started # 等 redis 启动即可
|
||||
```
|
||||
|
||||
> **注意:** `depends_on` 只管**启动顺序**,不管**可用性**。`condition: service_healthy` + `healthcheck` 才能真正等服务就绪。
|
||||
> [!note] depends_on 的真相
|
||||
> `depends_on` 只管**启动顺序**,不管**可用性**。不加 `healthcheck` 时,容器"已启动"不代表服务"已就绪"。数据库可能需要几秒初始化才能接受连接。
|
||||
|
||||
### 3.3 `healthcheck` — 健康检查
|
||||
#### 3.3 `healthcheck` — 健康检查
|
||||
|
||||
> [!tip] 为什么数据库必须配健康检查?
|
||||
> 容器启动 ≠ 服务就绪。MySQL 启动后可能要跑初始化脚本,`start_period` 就是给这段缓冲时间。
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -214,31 +247,31 @@ services:
|
||||
image: mysql:8.0
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||
interval: 10s # 每 10 秒检查一次
|
||||
timeout: 5s # 超时时间
|
||||
retries: 5 # 最多重试 5 次
|
||||
start_period: 30s # 容器启动后等 30 秒才开始检查(给数据库初始化时间)
|
||||
interval: 10s # 每 10 秒检查一次
|
||||
timeout: 5s # 超时时间
|
||||
retries: 5 # 最多重试 5 次
|
||||
start_period: 30s # 启动后等 30 秒才开始检查
|
||||
```
|
||||
|
||||
**常见健康检查命令:**
|
||||
**常见健康检查命令速查:**
|
||||
|
||||
| 服务 | 健康检查命令 |
|
||||
|------|-------------|
|
||||
| MySQL | `mysqladmin ping -h localhost` |
|
||||
| Redis | `redis-cli ping` |
|
||||
| Node.js | `wget -qO- http://localhost:3000/health || exit 1` |
|
||||
| Nginx | `curl -f http://localhost/ || exit 1` |
|
||||
| Node.js | `wget -qO- http://localhost:3000/health` |
|
||||
| Nginx | `curl -f http://localhost/` |
|
||||
| PostgreSQL | `pg_isready -h localhost` |
|
||||
|
||||
### 3.4 `environment` — 环境变量
|
||||
#### 3.4 `environment` — 环境变量
|
||||
|
||||
```yaml
|
||||
# 方式一:列表格式
|
||||
# 方式一:列表格式(简洁)
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DB_HOST=db
|
||||
|
||||
# 方式二:字典格式(推荐,更易读)
|
||||
# 方式二:字典格式(推荐,更易读,支持类型)
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
DB_HOST: db
|
||||
@@ -256,66 +289,69 @@ env_file:
|
||||
- .env
|
||||
```
|
||||
|
||||
### 3.5 `volumes` — 数据持久化
|
||||
#### 3.5 `volumes` — 数据持久化
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
# 命名卷(推荐,Docker 管理)
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
# 命名卷(推荐,Docker 自动管理)
|
||||
- db-data:/var/lib/mysql
|
||||
|
||||
# 绑定挂载(绑定到宿主机路径)
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
# 绑定挂载(绑定宿主机路径,开发用)
|
||||
- ./data:/app/data
|
||||
|
||||
# 只读挂载
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
# 只读挂载(配置文件)
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
|
||||
# 匿名卷(不需要命名)
|
||||
volumes:
|
||||
- /tmp/data
|
||||
- /tmp/data
|
||||
```
|
||||
|
||||
### 3.6 `restart` — 重启策略
|
||||
> [!abstract] 命名卷 vs 绑定挂载
|
||||
> - **命名卷**:Docker 管理存储位置,更安全,推荐生产环境用
|
||||
> - **绑定挂载**:直接映射宿主机路径,开发方便但可能跨平台不兼容
|
||||
|
||||
#### 3.6 `restart` — 重启策略
|
||||
|
||||
```yaml
|
||||
restart: always # 永远重启(包括手动停止后重启)
|
||||
restart: always # 永远重启(包括手动停止后也重启)
|
||||
restart: on-failure # 仅失败时重启
|
||||
restart: unless-stopped # 除非手动停止,否则重启(推荐)
|
||||
restart: no # 不自动重启(默认)
|
||||
```
|
||||
|
||||
### 3.7 `ports` vs `expose`
|
||||
#### 3.7 `ports` vs `expose`
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "8080:80" # 宿主端口:容器端口(外部可访问)
|
||||
- "127.0.0.1:8080:80" # 仅本地可访问
|
||||
- "127.0.0.1:8080:80" # 仅本地可访问(安全)
|
||||
- "3000" # 随机端口
|
||||
|
||||
expose:
|
||||
- "3000" # 仅容器间通信,外部不可访问
|
||||
```
|
||||
|
||||
> [!danger] 安全警告
|
||||
> 数据库**不要暴露 `ports` 到宿主机**!用 `expose` 或同网络即可,避免被外部直接访问。
|
||||
|
||||
---
|
||||
|
||||
## 四、多环境配置
|
||||
### 四、多环境配置
|
||||
|
||||
### 4.1 使用覆盖文件
|
||||
> [!abstract] 多环境策略
|
||||
> 核心思路:**一份基础配置 + 环境差异覆盖**,而不是为每个环境写完整文件。
|
||||
|
||||
#### 4.1 覆盖文件(推荐)
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml(基础配置)
|
||||
# docker-compose.yml(开发环境基础配置)
|
||||
services:
|
||||
api:
|
||||
build: .
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
NODE_ENV: development
|
||||
volumes:
|
||||
- ./server:/app # 开发时热重载
|
||||
|
||||
db:
|
||||
image: mysql:8.0
|
||||
- ./server:/app # 开发热重载
|
||||
```
|
||||
|
||||
```yaml
|
||||
@@ -323,17 +359,16 @@ services:
|
||||
services:
|
||||
api:
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
# 覆盖开发时的 volume 挂载
|
||||
volumes: [] # 生产时不要挂载宿主机目录
|
||||
NODE_ENV: production
|
||||
volumes: [] # 生产时不挂载宿主机目录
|
||||
```
|
||||
|
||||
```bash
|
||||
# 使用:基础 + 生产覆盖
|
||||
# 组合使用
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 4.2 更简洁的方式(环境变量控制)
|
||||
#### 4.2 环境变量控制(简洁)
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
@@ -341,14 +376,14 @@ services:
|
||||
api:
|
||||
build: .
|
||||
environment:
|
||||
- NODE_ENV=${NODE_ENV:-development}
|
||||
- DB_HOST=${DB_HOST:-db}
|
||||
NODE_ENV: ${NODE_ENV:-development}
|
||||
DB_HOST: ${DB_HOST:-db}
|
||||
volumes:
|
||||
- ${MOUNT_VOLUMES:-./server:/app}
|
||||
```
|
||||
|
||||
```bash
|
||||
# 开发环境(默认)
|
||||
# 开发环境(默认值)
|
||||
docker compose up -d
|
||||
|
||||
# 生产环境
|
||||
@@ -357,67 +392,29 @@ NODE_ENV=production MOUNT_VOLUMES="" docker compose up -d
|
||||
|
||||
---
|
||||
|
||||
## 五、常用命令
|
||||
### 五、常用命令
|
||||
|
||||
```bash
|
||||
# 启动所有服务(后台)
|
||||
docker compose up -d
|
||||
|
||||
# 启动所有服务(前台,看日志)
|
||||
docker compose up
|
||||
|
||||
# 启动单个服务
|
||||
docker compose up -d db redis
|
||||
|
||||
# 停止所有服务(不删除容器和数据卷)
|
||||
docker compose stop
|
||||
|
||||
# 停止并删除所有容器
|
||||
docker compose down
|
||||
|
||||
# 停止并删除容器、网络
|
||||
docker compose down --rmi all
|
||||
|
||||
# 重建镜像并启动(代码改动后)
|
||||
docker compose up -d --build
|
||||
|
||||
# 重建并重新初始化数据卷
|
||||
docker compose down -v
|
||||
docker compose up -d --build
|
||||
|
||||
# 查看服务状态
|
||||
docker compose ps
|
||||
|
||||
# 查看服务日志
|
||||
docker compose logs
|
||||
docker compose logs -f api # 只看 api 服务的日志
|
||||
docker compose logs -f --tail 100 db # 只看 db 的最后 100 行
|
||||
|
||||
# 进入运行中的容器
|
||||
docker compose exec api bash
|
||||
docker compose exec db mysql -u root -p
|
||||
|
||||
# 执行单次命令
|
||||
docker compose run api npm run db:migrate
|
||||
docker compose run --rm web npm test # --rm 执行完自动删除
|
||||
|
||||
# 查看资源占用
|
||||
docker compose ps
|
||||
|
||||
# 构建并启动
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
|
||||
# 更新镜像
|
||||
docker compose pull
|
||||
docker compose up -d --pull always
|
||||
```
|
||||
| 操作 | 命令 |
|
||||
|------|------|
|
||||
| 启动全部(后台) | `docker compose up -d` |
|
||||
| 启动全部(前台看日志) | `docker compose up` |
|
||||
| 启动单个服务 | `docker compose up -d db redis` |
|
||||
| 停止全部 | `docker compose stop` |
|
||||
| 停止并删除容器 | `docker compose down` |
|
||||
| 删除容器 + 网络 | `docker compose down --rmi all` |
|
||||
| 代码改动后重建 | `docker compose up -d --build` |
|
||||
| 删除容器 + 数据卷 | `docker compose down -v` |
|
||||
| 查看服务状态 | `docker compose ps` |
|
||||
| 查看日志 | `docker compose logs -f` |
|
||||
| 进入容器 | `docker compose exec api bash` |
|
||||
| 单次执行命令 | `docker compose run --rm web npm test` |
|
||||
| 拉取新镜像 | `docker compose pull` |
|
||||
|
||||
---
|
||||
|
||||
## 六、常见问题
|
||||
### 六、常见问题
|
||||
|
||||
### 6.1 容器间无法互相访问
|
||||
#### 6.1 容器间无法互相访问
|
||||
|
||||
```yaml
|
||||
# 确保所有服务在同一网络下
|
||||
@@ -432,9 +429,10 @@ networks:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
> 默认情况下,Docker Compose 会为同一个 compose 文件创建同一个网络,不同 compose 文件的容器**不能互相访问**。
|
||||
> [!note] 默认网络
|
||||
> 同一个 Compose 文件下的服务**默认在同一网络**,可以互相通过服务名访问。不同 Compose 文件的容器不能互相访问。
|
||||
|
||||
### 6.2 数据库启动慢,应用连不上
|
||||
#### 6.2 数据库启动慢,应用连不上
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -444,9 +442,9 @@ services:
|
||||
condition: service_healthy # 健康检查通过才启动
|
||||
```
|
||||
|
||||
或在应用代码中添加重试逻辑。
|
||||
或在应用代码中添加重试逻辑(指数退避)。
|
||||
|
||||
### 6.3 端口冲突
|
||||
#### 6.3 端口冲突
|
||||
|
||||
```bash
|
||||
# 查看端口占用
|
||||
@@ -461,7 +459,7 @@ ports:
|
||||
- "3001:3000" # 宿主机 3001 → 容器 3000
|
||||
```
|
||||
|
||||
### 6.4 `.env` 文件
|
||||
#### 6.4 `.env` 文件
|
||||
|
||||
```bash
|
||||
# 在项目根目录创建 .env 文件
|
||||
@@ -471,24 +469,24 @@ NODE_ENV=production
|
||||
COMPOSE_PROJECT_NAME=myapp
|
||||
```
|
||||
|
||||
> Docker Compose 会**自动读取**当前目录的 `.env` 文件,无需额外配置。`$DB_HOST` 在 `docker-compose.yml` 中会被自动替换。
|
||||
> [!info] 自动读取
|
||||
> Docker Compose 会**自动读取**当前目录的 `.env` 文件,`$DB_HOST` 在 `docker-compose.yml` 中会被自动替换。
|
||||
|
||||
---
|
||||
|
||||
## 七、常用模板速查
|
||||
### 七、常用模板速查
|
||||
|
||||
### 7.1 纯前端静态站点(Nginx)
|
||||
#### 7.1 纯前端静态站点(Nginx)
|
||||
|
||||
```yaml
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "80:80"
|
||||
restart: always
|
||||
ports: ["80:80"]
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### 7.2 Node.js + PostgreSQL
|
||||
#### 7.2 Node.js + PostgreSQL
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -496,7 +494,7 @@ services:
|
||||
build: .
|
||||
ports: ["3000:3000"]
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
|
||||
DATABASE_URL: postgresql://user:pass@db:5432/mydb
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
@@ -504,21 +502,20 @@ services:
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_USER=user
|
||||
- POSTGRES_PASSWORD=pass
|
||||
- POSTGRES_DB=mydb
|
||||
POSTGRES_USER: user
|
||||
POSTGRES_PASSWORD: pass
|
||||
POSTGRES_DB: mydb
|
||||
volumes:
|
||||
- pg-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U user"]
|
||||
interval: 10s
|
||||
|
||||
networks:
|
||||
volumes:
|
||||
pg-data:
|
||||
```
|
||||
|
||||
### 7.3 Next.js 全功能模板
|
||||
#### 7.3 Next.js 全功能模板
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -529,18 +526,18 @@ services:
|
||||
target: production
|
||||
ports: ["3000:3000"]
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DATABASE_URL=$DATABASE_URL
|
||||
- NEXTAUTH_SECRET=$NEXTAUTH_SECRET
|
||||
restart: always
|
||||
NODE_ENV: production
|
||||
DATABASE_URL: $DATABASE_URL
|
||||
NEXTAUTH_SECRET: $NEXTAUTH_SECRET
|
||||
restart: unless-stopped
|
||||
networks: [app-network]
|
||||
|
||||
db:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
- POSTGRES_DB=myapp
|
||||
- POSTGRES_USER=app
|
||||
- POSTGRES_PASSWORD=$DB_PASSWORD
|
||||
POSTGRES_DB: myapp
|
||||
POSTGRES_USER: app
|
||||
POSTGRES_PASSWORD: $DB_PASSWORD
|
||||
volumes: [pg-data:/var/lib/postgresql/data]
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U app"]
|
||||
@@ -560,11 +557,10 @@ volumes:
|
||||
|
||||
---
|
||||
|
||||
## 八、Compose 文件格式演进
|
||||
### 八、Compose 文件格式演进
|
||||
|
||||
### 8.1 新版 Compose Specification(推荐)
|
||||
|
||||
**不再需要 `version` 字段**,Docker Compose V2 起默认使用 Compose Specification 格式:
|
||||
> [!tip] 新项目直接用新格式
|
||||
> Compose V2 起默认使用 Compose Specification 格式,不再需要 `version` 字段。
|
||||
|
||||
```yaml
|
||||
# 新版写法(推荐)
|
||||
@@ -584,27 +580,17 @@ volumes:
|
||||
data:
|
||||
```
|
||||
|
||||
> **关键区别:**
|
||||
> - V3 及以下:必须写 `version: '3.8'`,字段名用点号分隔(如 `networks.default`)
|
||||
> - V4 及以上(Compose Specification):**不需要 version**,字段名用嵌套格式(如 `networks:` 下的 `default:`)
|
||||
|
||||
### 8.2 如何判断使用哪种格式
|
||||
|
||||
```bash
|
||||
# 查看 Compose 版本
|
||||
docker compose version
|
||||
|
||||
# Compose V2+(2020 年起)→ 使用 Compose Specification 格式
|
||||
# 使用 `docker compose`(注意是空格,不是连字符)
|
||||
```
|
||||
|
||||
> **建议:** 新项目直接使用无 version 的新格式,兼容性更好。
|
||||
| 对比项 | V3 及以下(旧) | V4+ / Compose Specification(新) |
|
||||
|--------|----------------|--------------------------------|
|
||||
| `version` 字段 | 必须写 | 不需要 |
|
||||
| 命令 | `docker-compose`(连字符) | `docker compose`(空格) |
|
||||
| 字段格式 | 点号分隔 | YAML 嵌套格式 |
|
||||
|
||||
---
|
||||
|
||||
## 九、高级配置
|
||||
### 九、高级配置
|
||||
|
||||
### 9.1 `deploy` — 资源限制(适用于 Compose V3+)
|
||||
#### 9.1 `deploy` — 资源限制
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -617,13 +603,6 @@ services:
|
||||
delay: 5s
|
||||
max_attempts: 3
|
||||
window: 120s
|
||||
update_config:
|
||||
parallelism: 1 # 每次更新 1 个容器
|
||||
delay: 10s
|
||||
order: start-first # 先启动新再停止旧
|
||||
rollback_config:
|
||||
parallelism: 1
|
||||
delay: 5s
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5' # 最多 0.5 核 CPU
|
||||
@@ -633,9 +612,10 @@ services:
|
||||
memory: 128M
|
||||
```
|
||||
|
||||
> **注意:** `deploy` 在 `docker compose up`(非 Swarm 模式)下**部分字段不生效**(`replicas`、`update_config` 等)。资源限制 `limits/reservations` 在普通模式下仍然生效。
|
||||
> [!warning] 注意
|
||||
> `deploy` 的 `replicas`、`update_config` 在 `docker compose up`(非 Swarm)下**不生效**。但 `resources.limits/reservations` 在普通模式下仍然有效。
|
||||
|
||||
### 9.2 `profiles` — 按需启停服务
|
||||
#### 9.2 `profiles` — 按需启停服务
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -657,25 +637,17 @@ services:
|
||||
```
|
||||
|
||||
```bash
|
||||
# 启动 app 相关服务(web + db + redis)
|
||||
# 只启动 app 相关服务(web + db + redis)
|
||||
docker compose --profile app up -d
|
||||
|
||||
# 启动 app + 监控
|
||||
docker compose --profile app --profile monitoring up -d
|
||||
|
||||
# 启动所有带 profile 的服务
|
||||
docker compose --profile app --profile db --profile cache --profile monitoring up -d
|
||||
|
||||
# 启动所有服务(包括无 profile 的)
|
||||
docker compose up -d
|
||||
|
||||
# 查看当前 profile 配置
|
||||
docker compose config --profiles
|
||||
```
|
||||
|
||||
> **场景:** 开发时只启动 `app`,测试时加上 `db`,生产环境加上 `monitoring`。
|
||||
|
||||
### 9.3 `configs` — 配置文件管理
|
||||
#### 9.3 `configs` — 配置文件管理
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -684,26 +656,14 @@ services:
|
||||
configs:
|
||||
- source: nginx_conf
|
||||
target: /etc/nginx/conf.d/default.conf
|
||||
mode: 0444 # 文件权限
|
||||
|
||||
app:
|
||||
image: my-app:latest
|
||||
configs:
|
||||
- source: app_config
|
||||
target: /etc/app/config.yaml
|
||||
mode: 0440
|
||||
mode: 0444
|
||||
|
||||
configs:
|
||||
nginx_conf:
|
||||
file: ./configs/nginx.conf
|
||||
app_config:
|
||||
file: ./configs/app.yaml
|
||||
external: false # 本地文件
|
||||
```
|
||||
|
||||
> **适用场景:** 需要分发配置文件但不想硬编码到镜像中。
|
||||
|
||||
### 9.4 `secrets` — 敏感信息管理
|
||||
#### 9.4 `secrets` — 敏感信息管理
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -713,18 +673,18 @@ services:
|
||||
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_pass
|
||||
secrets:
|
||||
- db_root_pass
|
||||
- db_config
|
||||
|
||||
secrets:
|
||||
db_root_pass:
|
||||
file: ./secrets/db_root_pass.txt # 从文件读取
|
||||
file: ./secrets/db_root_pass.txt
|
||||
db_config:
|
||||
string: '{"max_connections": 100}' # 直接写字符串
|
||||
string: '{"max_connections": 100}'
|
||||
```
|
||||
|
||||
> **安全建议:** 敏感信息不要写死在 `docker-compose.yml` 中,使用 `secrets` 或 `.env` 文件管理。
|
||||
> [!danger] 安全建议
|
||||
> 敏感信息不要写死在 `docker-compose.yml` 中,使用 `secrets` 或 `.env` 文件管理。
|
||||
|
||||
### 9.5 其他实用配置
|
||||
#### 9.5 其他实用配置
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -741,13 +701,12 @@ services:
|
||||
entrypoint: ["node"]
|
||||
command: ["server.js"]
|
||||
|
||||
# 容器别名(同一 compose 内通过别名访问)
|
||||
# 容器别名
|
||||
container_name: my-app
|
||||
|
||||
# 标签(元数据)
|
||||
labels:
|
||||
- "com.example.description=API Server"
|
||||
- "com.example.environment=production"
|
||||
|
||||
# 时区
|
||||
environment:
|
||||
@@ -763,20 +722,13 @@ services:
|
||||
- ALL
|
||||
cap_add:
|
||||
- NET_BIND_SERVICE
|
||||
|
||||
# 资源限制
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、最佳实践
|
||||
### 十、最佳实践
|
||||
|
||||
### 10.1 安全性
|
||||
#### 10.1 安全性
|
||||
|
||||
```yaml
|
||||
# ✅ 使用非 root 用户
|
||||
@@ -788,22 +740,14 @@ cap_drop:
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
|
||||
# ✅ 敏感信息用 secrets 或 .env
|
||||
secrets:
|
||||
- db_password
|
||||
|
||||
# ❌ 避免使用 privileged
|
||||
# ❌ 避免 privileged
|
||||
# privileged: true
|
||||
|
||||
# ❌ 避免绑定 0.0.0.0
|
||||
# ports:
|
||||
# - "0.0.0.0:3000:3000"
|
||||
```
|
||||
|
||||
### 10.2 可靠性
|
||||
#### 10.2 可靠性
|
||||
|
||||
```yaml
|
||||
# ✅ 所有外部依赖都加 healthcheck
|
||||
# ✅ 外部依赖都加 healthcheck
|
||||
db:
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
||||
@@ -818,7 +762,7 @@ depends_on:
|
||||
condition: service_healthy
|
||||
```
|
||||
|
||||
### 10.3 可维护性
|
||||
#### 10.3 可维护性
|
||||
|
||||
```yaml
|
||||
# ✅ 使用 .env 管理变量
|
||||
@@ -827,15 +771,6 @@ COMPOSE_PROJECT_NAME=myapp
|
||||
MYSQL_ROOT_PASSWORD=xxxxx
|
||||
NODE_ENV=production
|
||||
|
||||
# docker-compose.yml
|
||||
services:
|
||||
db:
|
||||
image: mysql:8.0
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
volumes:
|
||||
- db-data:/var/lib/mysql
|
||||
|
||||
# ✅ 命名卷而不是绑定挂载(数据持久化)
|
||||
volumes:
|
||||
db-data: # Docker 管理,更安全
|
||||
@@ -845,7 +780,7 @@ volumes:
|
||||
# docker compose --profile dev up -d
|
||||
```
|
||||
|
||||
### 10.4 性能优化
|
||||
#### 10.4 性能优化
|
||||
|
||||
```yaml
|
||||
# ✅ 生产环境使用 Alpine 镜像
|
||||
@@ -860,21 +795,15 @@ deploy:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
|
||||
# ✅ 只暴露必要的端口
|
||||
# ❌ 数据库不要暴露到宿主机
|
||||
# ✅ 数据库不要暴露到宿主机
|
||||
# db:
|
||||
# ports:
|
||||
# - "3306:3306" # 删除这行
|
||||
|
||||
# ✅ 使用 expose 代替 ports(容器间通信)
|
||||
db:
|
||||
expose:
|
||||
- "3306"
|
||||
# - "3306:3306" # 删除这行,用 expose 代替
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十一、快速参考卡
|
||||
## 快速参考卡
|
||||
|
||||
| 字段 | 用途 | 示例 |
|
||||
|------|------|------|
|
||||
@@ -890,7 +819,12 @@ db:
|
||||
| `networks` | 网络归属 | `app-network` |
|
||||
| `profiles` | 按需启停 | `["dev", "monitoring"]` |
|
||||
| `secrets` | 敏感信息管理 | `file: ./secrets/xxx` |
|
||||
| `configs` | 配置文件管理 | `target: /etc/app/config` |
|
||||
| `deploy.resources` | 资源限制 | `cpus: '0.5', memory: 512M` |
|
||||
| `container_name` | 固定容器名 | `my-container` |
|
||||
| `user` | 运行用户 | `"1000:1000"` |
|
||||
|
||||
---
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[Dockerfile编写指南]] — 编写高效的 Dockerfile
|
||||
- [[Docker常用命令]] — 日常 Docker 操作速查
|
||||
|
||||
Reference in New Issue
Block a user