$npx -y skills add chaterm/terminal-skills --skill composeDocker Compose 编排
| 1 | # Docker Compose 编排 |
| 2 | |
| 3 | ## 概述 |
| 4 | 多容器编排、环境变量、网络配置等技能。 |
| 5 | |
| 6 | ## 基础命令 |
| 7 | |
| 8 | ```bash |
| 9 | # 启动服务 |
| 10 | docker compose up |
| 11 | docker compose up -d # 后台运行 |
| 12 | docker compose up --build # 重新构建 |
| 13 | |
| 14 | # 停止服务 |
| 15 | docker compose down |
| 16 | docker compose down -v # 同时删除卷 |
| 17 | docker compose down --rmi all # 同时删除镜像 |
| 18 | |
| 19 | # 查看状态 |
| 20 | docker compose ps |
| 21 | docker compose ps -a |
| 22 | |
| 23 | # 查看日志 |
| 24 | docker compose logs |
| 25 | docker compose logs -f # 实时跟踪 |
| 26 | docker compose logs service_name |
| 27 | |
| 28 | # 执行命令 |
| 29 | docker compose exec service_name sh |
| 30 | docker compose run service_name command |
| 31 | |
| 32 | # 重启服务 |
| 33 | docker compose restart |
| 34 | docker compose restart service_name |
| 35 | |
| 36 | # 扩缩容 |
| 37 | docker compose up -d --scale web=3 |
| 38 | ``` |
| 39 | |
| 40 | ## 配置文件 |
| 41 | |
| 42 | ### 基础结构 |
| 43 | ```yaml |
| 44 | # docker-compose.yml |
| 45 | version: "3.9" |
| 46 | |
| 47 | services: |
| 48 | web: |
| 49 | image: nginx:alpine |
| 50 | ports: |
| 51 | - "80:80" |
| 52 | volumes: |
| 53 | - ./html:/usr/share/nginx/html |
| 54 | depends_on: |
| 55 | - api |
| 56 | |
| 57 | api: |
| 58 | build: ./api |
| 59 | environment: |
| 60 | - DATABASE_URL=postgres://db:5432/mydb |
| 61 | depends_on: |
| 62 | - db |
| 63 | |
| 64 | db: |
| 65 | image: postgres:15 |
| 66 | volumes: |
| 67 | - db_data:/var/lib/postgresql/data |
| 68 | environment: |
| 69 | POSTGRES_PASSWORD: secret |
| 70 | |
| 71 | volumes: |
| 72 | db_data: |
| 73 | |
| 74 | networks: |
| 75 | default: |
| 76 | driver: bridge |
| 77 | ``` |
| 78 | |
| 79 | ### 服务配置详解 |
| 80 | |
| 81 | #### build |
| 82 | ```yaml |
| 83 | services: |
| 84 | app: |
| 85 | # 简单形式 |
| 86 | build: ./app |
| 87 | |
| 88 | # 完整形式 |
| 89 | build: |
| 90 | context: ./app |
| 91 | dockerfile: Dockerfile.prod |
| 92 | args: |
| 93 | - VERSION=1.0 |
| 94 | target: production |
| 95 | cache_from: |
| 96 | - myapp:cache |
| 97 | ``` |
| 98 | |
| 99 | #### ports |
| 100 | ```yaml |
| 101 | services: |
| 102 | web: |
| 103 | ports: |
| 104 | - "80:80" # HOST:CONTAINER |
| 105 | - "443:443" |
| 106 | - "8080-8090:8080-8090" # 端口范围 |
| 107 | - "127.0.0.1:3000:3000" # 绑定特定 IP |
| 108 | ``` |
| 109 | |
| 110 | #### volumes |
| 111 | ```yaml |
| 112 | services: |
| 113 | app: |
| 114 | volumes: |
| 115 | # 命名卷 |
| 116 | - data:/var/lib/data |
| 117 | # 绑定挂载 |
| 118 | - ./config:/etc/app/config:ro |
| 119 | # 匿名卷 |
| 120 | - /var/lib/data |
| 121 | |
| 122 | volumes: |
| 123 | data: |
| 124 | driver: local |
| 125 | ``` |
| 126 | |
| 127 | #### environment |
| 128 | ```yaml |
| 129 | services: |
| 130 | app: |
| 131 | environment: |
| 132 | - NODE_ENV=production |
| 133 | - DATABASE_URL=postgres://localhost/db |
| 134 | # 或使用映射形式 |
| 135 | environment: |
| 136 | NODE_ENV: production |
| 137 | DATABASE_URL: postgres://localhost/db |
| 138 | # 从文件加载 |
| 139 | env_file: |
| 140 | - .env |
| 141 | - .env.local |
| 142 | ``` |
| 143 | |
| 144 | #### depends_on |
| 145 | ```yaml |
| 146 | services: |
| 147 | web: |
| 148 | depends_on: |
| 149 | - db |
| 150 | - redis |
| 151 | # 带条件 |
| 152 | depends_on: |
| 153 | db: |
| 154 | condition: service_healthy |
| 155 | redis: |
| 156 | condition: service_started |
| 157 | ``` |
| 158 | |
| 159 | #### healthcheck |
| 160 | ```yaml |
| 161 | services: |
| 162 | web: |
| 163 | healthcheck: |
| 164 | test: ["CMD", "curl", "-f", "http://localhost/health"] |
| 165 | interval: 30s |
| 166 | timeout: 10s |
| 167 | retries: 3 |
| 168 | start_period: 40s |
| 169 | ``` |
| 170 | |
| 171 | #### deploy(Swarm 模式) |
| 172 | ```yaml |
| 173 | services: |
| 174 | web: |
| 175 | deploy: |
| 176 | replicas: 3 |
| 177 | resources: |
| 178 | limits: |
| 179 | cpus: '0.5' |
| 180 | memory: 512M |
| 181 | reservations: |
| 182 | cpus: '0.25' |
| 183 | memory: 256M |
| 184 | restart_policy: |
| 185 | condition: on-failure |
| 186 | delay: 5s |
| 187 | max_attempts: 3 |
| 188 | ``` |
| 189 | |
| 190 | ## 网络配置 |
| 191 | |
| 192 | ### 自定义网络 |
| 193 | ```yaml |
| 194 | services: |
| 195 | frontend: |
| 196 | networks: |
| 197 | - frontend |
| 198 | |
| 199 | backend: |
| 200 | networks: |
| 201 | - frontend |
| 202 | - backend |
| 203 | |
| 204 | db: |
| 205 | networks: |
| 206 | - backend |
| 207 | |
| 208 | networks: |
| 209 | frontend: |
| 210 | driver: bridge |
| 211 | backend: |
| 212 | driver: bridge |
| 213 | internal: true # 内部网络,无外部访问 |
| 214 | ``` |
| 215 | |
| 216 | ### 网络别名 |
| 217 | ```yaml |
| 218 | services: |
| 219 | db: |
| 220 | networks: |
| 221 | backend: |
| 222 | aliases: |
| 223 | - database |
| 224 | - postgres |
| 225 | ``` |
| 226 | |
| 227 | ## 环境变量 |
| 228 | |
| 229 | ### .env 文件 |
| 230 | ```bash |
| 231 | # .env |
| 232 | POSTGRES_VERSION=15 |
| 233 | POSTGRES_PASSWORD=secret |
| 234 | APP_PORT=3000 |
| 235 | ``` |
| 236 | |
| 237 | ```yaml |
| 238 | # docker-compose.yml |
| 239 | services: |
| 240 | db: |
| 241 | image: postgres:${POSTGRES_VERSION} |
| 242 | environment: |
| 243 | POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} |
| 244 | |
| 245 | app: |
| 246 | ports: |
| 247 | - "${APP_PORT}:3000" |
| 248 | ``` |
| 249 | |
| 250 | ### 多环境配置 |
| 251 | ```bash |
| 252 | # docker-compose.override.yml(开发环境,自动加载) |
| 253 | # docker-compose.prod.yml(生产环境) |
| 254 | |
| 255 | # 使用多个配置文件 |
| 256 | docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d |
| 257 | ``` |
| 258 | |
| 259 | ```yaml |
| 260 | # docker-compose.yml(基础配置) |
| 261 | services: |
| 262 | app: |
| 263 | image: myapp:latest |
| 264 | |
| 265 | # docker-compose.override.yml(开发覆盖) |
| 266 | services: |
| 267 | app: |
| 268 | build: . |
| 269 | volumes: |
| 270 | - .:/app |
| 271 | environment: |
| 272 | - DEBUG=true |
| 273 | |
| 274 | # docker-compose.prod.yml(生产覆盖) |
| 275 | services: |
| 276 | app: |
| 277 | restart: always |
| 278 | environment: |
| 279 | - DEBUG=false |
| 280 | ``` |
| 281 | |
| 282 | ## 常见场景 |
| 283 | |
| 284 | ### 场景 1:Web 应用栈 |
| 285 | ```yaml |
| 286 | version: "3.9" |
| 287 | |
| 288 | services: |
| 289 | nginx: |
| 290 | image: nginx:alpine |
| 291 | ports: |
| 292 | - "80:80" |
| 293 | volumes: |
| 294 | - ./nginx.conf:/etc/nginx/nginx.conf:ro |
| 295 | depends_on: |
| 296 | - app |
| 297 | |
| 298 | app: |
| 299 | build: . |
| 300 | environment: |
| 301 | - DATABASE_URL=postgres://postgres:secret@db:5432/mydb |
| 302 | - REDIS_URL=redis://redis:6379 |
| 303 | depends_on: |
| 304 | db: |
| 305 | condition: service_healthy |
| 306 | redis: |
| 307 | condition: service_started |
| 308 | |
| 309 | db: |
| 310 | image: postgres:15-alpine |
| 311 | volumes: |
| 312 | - postgres_data:/var/lib/postgresql/data |
| 313 | environment: |
| 314 | POSTGRES_PASSWORD: secret |
| 315 | POSTGRES_DB: mydb |
| 316 | healthcheck: |
| 317 | test: ["CMD-SHELL", "pg_isready -U postgres"] |
| 318 | interval: 5s |
| 319 | timeout: 5s |
| 320 | retries: |