当前位置: 首页 > news >正文

第09章:Docker Compose 编排

第09章:Docker Compose 编排

本章目标:掌握 Docker Compose 的语法和使用,学会编排多容器应用,实现一键部署和管理。


9.1 Docker Compose 是什么

9.1.1 定义与价值

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。通过一个 YAML 文件,你可以配置应用的所有服务、网络和存储卷,然后用一个命令创建并启动所有服务。

传统方式(多个终端分别操作): 终端1: docker run -d --name db mysql 终端2: docker run -d --name redis redis 终端3: docker run -d --name app myapp 终端4: docker network connect ... 终端5: docker run -d --name nginx nginx Docker Compose 方式(一个文件,一条命令): docker compose up -d

9.1.2 Compose 的优势

优势说明
声明式配置一个 YAML 文件描述整个应用架构
一键启停docker compose up/down管理所有服务
环境隔离每个 compose 项目独立的网络和卷
开发/测试/生产同一配置适配不同环境
可版本控制compose 文件可以纳入 Git 管理

9.2 Compose 文件语法详解

9.2.1 文件结构

# docker-compose.yml 完整结构version:'3.8'# Compose 文件版本services:# 服务定义(容器配置)web:# ... 服务配置db:# ... 服务配置networks:# 自定义网络frontend:backend:volumes:# 声明命名卷db-data:cache-data:configs:# 配置对象app-config:file:./config.ymlsecrets:# 敏感信息db-password:file:./secrets/db_password.txt

9.2.2 services 配置详解

services:# ========== 服务名称 ==========web-app:# 基本配置image:myapp:latest# 使用镜像# 或从 Dockerfile 构建build:context:.# 构建上下文dockerfile:Dockerfile# Dockerfile 文件名args:# 构建参数VERSION:1.0.0target:production# 多阶段构建的目标阶段container_name:my-web-app# 容器名称hostname:web-server# 主机名restart:unless-stopped# 重启策略# 环境变量environment:-APP_ENV=production-DB_HOST=db-DB_PORT=3306-REDIS_HOST=redis# 从文件加载环境变量env_file:-.env-.env.production# 端口映射ports:-"80:80"-"443:443"# - "127.0.0.1:8080:80" # 仅本地访问# - "8080:80/tcp" # 指定协议# 卷挂载volumes:-./src:/app/src:ro# 只读挂载-app-logs:/app/logs# 命名卷-/data/images:/app/images# 绝对路径# 网络networks:-frontend-backend# 资源限制deploy:resources:limits:cpus:'2.0'memory:1Greservations:cpus:'0.5'memory:256Mreplicas:2# 副本数restart_policy:condition:on-failuremax_attempts:3# 健康检查healthcheck:test:["CMD","curl","-f","http://localhost:80/health"]interval:30stimeout:5sretries:3start_period:10s# 依赖关系depends_on:db:condition:service_healthy# 等待依赖服务健康redis:condition:service_started# 链接(旧语法,不推荐)links:-db-redis# 别名(DNS 名称)aliases:-web-application# 日志配置logging:driver:json-fileoptions:max-size:"10m"max-file:"3"# 安全选项security_opt:-no-new-privileges:trueread_only:true# 只读文件系统tmpfs:-/tmp-/var/run# 容器内命令command:["python3","app.py"]# 或# command: python3 app.py# 入口点entrypoint:["/app/entrypoint.sh"]# 工作目录working_dir:/app# 用户user:"1000:1000"# 其他容器extra_hosts:-"other-host:192.168.1.100"# PID 模式pid:"host"# 配置文件configs:-source:app-configtarget:/app/config.ymlmode:0444

9.2.3 networks 配置详解

networks:# 默认 bridge 网络default:driver:bridge# 自定义网络frontend:driver:bridgedriver_opts:com.docker.network.bridge.name:"frontend-br"ipam:driver:defaultconfig:-subnet:192.168.100.0/24gateway:192.168.100.1labels:-"com.example.network.frontend=true"# Overlay 网络(用于 Swarm)backend:driver:overlayattachable:true# 外部网络(使用已存在的网络)existing-network:external:true

9.2.4 volumes 配置详解

volumes:# 命名卷(Docker 管理)db-data:driver:localdriver_opts:type:nonedevice:/data/mysqlo:bind# 带标签的卷app-logs:labels:com.example.description:"Application logs"com.example.department:"Operations"# 外部卷(使用已存在的卷)existing-volume:external:true# tmpfs 卷temp-cache:driver:localdriver_opts:type:tmpfsdevice:tmpfso:size=100m,uid=1000

9.3 Compose 常用命令

9.3.1 服务管理

# 启动所有服务dockercompose up# 后台启动dockercompose up-d# 重建并启动(有变更时)dockercompose up-d--build# 停止并删除容器dockercompose down# 停止并删除容器和卷dockercompose down-v# 查看服务状态dockercomposeps# 查看服务日志dockercompose logs# 实时跟踪日志dockercompose logs-f# 查看特定服务日志dockercompose logs-fweb-app# 查看服务资源使用dockercomposetop

9.3.2 单个服务操作

# 启动特定服务dockercompose up-ddb# 停止特定服务dockercompose stop web-app# 重启特定服务dockercompose restart web-app# 进入服务容器dockercomposeexecweb-appbashdockercomposeexecdb mysql-uroot-p# 查看服务进程dockercomposetopweb-app

9.3.3 构建相关

# 构建所有服务dockercompose build# 构建特定服务dockercompose build web-app# 不使用缓存构建dockercompose build --no-cache# 拉取最新镜像dockercompose pull# 推送镜像dockercompose push

9.3.4 镜像和卷管理

# 列出项目中的镜像dockercompose images# 删除停止的容器dockercomposerm# 列出项目中的卷dockercompose volumels# 删除未使用的卷dockercompose down-v

9.4 环境变量管理

9.4.1 多种设置方式

services:web-app:# 方式1:直接在 compose 文件中设置environment:APP_ENV:productionDB_HOST:db# 方式2:从文件加载env_file:-.env# 方式3:使用变量替换(compose 文件中)image:myapp:${VERSION:-latest}# 方式4:在容器内使用command:python3 app.py

9.4.2 .env 文件示例

# .env 文件APP_ENV=productionAPP_VERSION=1.0.0DB_ROOT_PASSWORD=supersecretDB_NAME=myappDB_USER=appuserDB_PASSWORD=apppass123REDIS_PASSWORD=redis123

9.4.3 多环境配置

# 项目结构project/ ├── docker-compose.yml# 基础配置├── docker-compose.override.yml# 开发环境覆盖├── docker-compose.prod.yml# 生产环境配置├── .env# 默认环境变量├── .env.dev# 开发环境变量└── .env.prod# 生产环境变量# 开发环境(默认)dockercompose up-d# 生产环境dockercompose-fdocker-compose.yml-fdocker-compose.prod.yml up-d# 或使用环境变量COMPOSE_FILE=docker-compose.yml:docker-compose.prod.ymldockercompose up-d

9.5 完整的多容器应用示例

9.5.1 LAMP 架构(Linux + Apache + MySQL + PHP)

# docker-compose.ymlversion:'3.8'services:# Web 服务器apache:image:php:8.2-apachecontainer_name:lamp-apacheports:-"80:80"-"443:443"volumes:-./src:/var/www/html-./apache/conf.d:/etc/apache2/sites-enablednetworks:-lamp-networkdepends_on:mysql:condition:service_healthyenvironment:-DB_HOST=mysql-DB_NAME=${DB_NAME:-laravel}-DB_USER=${DB_USER:-user}-DB_PASSWORD=${DB_PASSWORD:-password}restart:unless-stopped# MySQL 数据库mysql:image:mysql:8.0container_name:lamp-mysqlenvironment:MYSQL_ROOT_PASSWORD:${DB_ROOT_PASSWORD:-rootpassword}MYSQL_DATABASE:${DB_NAME:-laravel}MYSQL_USER:${DB_USER:-user}MYSQL_PASSWORD:${DB_PASSWORD:-password}volumes:-mysql-data:/var/lib/mysql-./mysql/initdb:/docker-entrypoint-initdb.dnetworks:-lamp-networkhealthcheck:test:["CMD","mysqladmin","ping","-h","localhost"]interval:10stimeout:5sretries:5restart:unless-stopped# Redis 缓存redis:image:redis:7-alpinecontainer_name:lamp-rediscommand:redis-server--requirepass ${REDIS_PASSWORD:-redis123}volumes:-redis-data:/datanetworks:-lamp-networkhealthcheck:test:["CMD","redis-cli","ping"]interval:10stimeout:5sretries:5restart:unless-stoppednetworks:lamp-network:driver:bridgevolumes:mysql-data:redis-data:

9.5.2 Python + Nginx + Gunicorn + PostgreSQL + Redis

# docker-compose.ymlversion:'3.8'services:# Nginx 反向代理nginx:image:nginx:alpinecontainer_name:app-nginxports:-"80:80"-"443:443"volumes:-./nginx/conf.d:/etc/nginx/conf.d:ro-./nginx/ssl:/etc/nginx/ssl:ro-static-files:/app/static:ronetworks:-app-networkdepends_on:-webrestart:unless-stopped# Python Web 应用web:build:context:.dockerfile:Dockerfiletarget:productioncontainer_name:app-webvolumes:-static-files:/app/static-./logs:/app/logsenvironment:-APP_ENV=production-DATABASE_URL=postgresql+asyncpg://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_NAME}-REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0networks:-app-networkdepends_on:postgres:condition:service_healthyredis:condition:service_healthyhealthcheck:test:["CMD","curl","-f","http://localhost:8000/health"]interval:30stimeout:5sretries:3restart:unless-stopped# PostgreSQL 数据库postgres:image:postgres:15-alpinecontainer_name:app-postgresenvironment:POSTGRES_DB:${DB_NAME:-myapp}POSTGRES_USER:${DB_USER:-appuser}POSTGRES_PASSWORD:${DB_PASSWORD:-apppass123}PGDATA:/var/lib/postgresql/data/pgdatavolumes:-postgres-data:/var/lib/postgresql/datanetworks:-app-networkhealthcheck:test:["CMD-SHELL","pg_isready -U ${DB_USER:-appuser}"]interval:10stimeout:5sretries:5restart:unless-stopped# Redis 缓存redis:image:redis:7-alpinecontainer_name:app-rediscommand:redis-server--requirepass ${REDIS_PASSWORD:-redis123}volumes:-redis-data:/datanetworks:-app-networkhealthcheck:test:["CMD","redis-cli","-a","${REDIS_PASSWORD:-redis123}","ping"]interval:10stimeout:5sretries:5restart:unless-stoppednetworks:app-network:driver:bridgevolumes:static-files:postgres-data:redis-data:

9.5.3 Node.js + MongoDB + Redis

# docker-compose.ymlversion:'3.8'services:# Node.js 应用app:build:context:.dockerfile:Dockerfilecontainer_name:node-appports:-"3000:3000"environment:-NODE_ENV=production-MONGODB_URI=mongodb://mongo:27017/myapp-REDIS_URL=redis://redis:6379volumes:-./uploads:/app/uploadsnetworks:-node-networkdepends_on:mongo:condition:service_healthyredis:condition:service_healthyhealthcheck:test:["CMD","curl","-f","http://localhost:3000/health"]interval:30stimeout:5sretries:3restart:unless-stopped# MongoDB 数据库mongo:image:mongo:6container_name:node-mongoenvironment:MONGO_INITDB_ROOT_USERNAME:${MONGO_USER:-admin}MONGO_INITDB_ROOT_PASSWORD:${MONGO_PASSWORD:-password}volumes:-mongo-data:/data/db-mongo-config:/data/configdbnetworks:-node-networkhealthcheck:test:["CMD","mongosh","--eval","db.adminCommand('ping')"]interval:10stimeout:5sretries:5restart:unless-stopped# Redis 缓存redis:image:redis:7-alpinecontainer_name:node-rediscommand:redis-server--requirepass ${REDIS_PASSWORD:-redis123}volumes:-redis-data:/datanetworks:-node-networkhealthcheck:test:["CMD","redis-cli","-a","${REDIS_PASSWORD:-redis123}","ping"]interval:10stimeout:5sretries:5restart:unless-stoppednetworks:node-network:driver:bridgevolumes:mongo-data:mongo-config:redis-data:

9.6 Compose 高级特性

9.6.1 服务扩缩容

# 扩容服务(启动多个实例)dockercompose up-d--scaleweb=3# 缩容dockercompose up-d--scaleweb=1# 注意:使用 scale 时不要映射固定端口# 应该使用随机端口或负载均衡器

9.6.2 服务依赖与启动顺序

services:db:image:mysql:8.0# ...redis:image:redis:7# ...web:image:myappdepends_on:db:condition:service_healthy# 等待数据库健康redis:condition:service_started# 只需 Redis 启动# ...

9.6.3 配置文件挂载

services:nginx:image:nginx:alpineconfigs:-source:nginx-conftarget:/etc/nginx/conf.d/default.confmode:0444configs:nginx-conf:file:./nginx/default.conf

9.6.4 敏感信息管理

services:db:image:mysql:8.0secrets:-db-passwordenvironment:MYSQL_PASSWORD_FILE:/run/secrets/db-passwordsecrets:db-password:file:./secrets/db_password.txt

9.7 动手实验

实验 9.1:WordPress 一键部署

# 创建项目目录mkdir-p~/docker-lab/wordpresscd~/docker-lab/wordpress# 创建 docker-compose.ymlcat>docker-compose.yml<<'EOF' version: '3.8' services: db: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress volumes: - db-data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped wordpress: image: wordpress:latest ports: - "8080:80" environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: - wp-data:/var/www/html depends_on: db: condition: service_healthy restart: unless-stopped volumes: db-data: wp-data: EOF# 启动dockercompose up-d# 访问 http://localhost:8080 完成 WordPress 安装

实验 9.2:多服务应用

# 使用上面的 Python + Nginx + PostgreSQL + Redis 示例cd~/docker-lab# 创建项目结构mkdir-pnginx/conf.d# 创建 Nginx 配置cat>nginx/conf.d/default.conf<<'EOF' upstream web { server web:8000; } server { listen 80; server_name localhost; location /static/ { alias /app/static/; } location / { proxy_pass http://web; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } EOF# 启动所有服务dockercompose up-d# 查看服务状态dockercomposeps# 查看日志dockercompose logs-f

9.8 本章小结

命令说明
docker compose up -d后台启动所有服务
docker compose down停止并删除所有服务
docker compose ps查看服务状态
docker compose logs -f实时跟踪日志
docker compose exec <svc> bash进入服务容器
docker compose restart <svc>重启指定服务
docker compose build构建服务镜像
docker compose pull拉取最新镜像

9.9 课后练习

  1. 基础题:使用 Docker Compose 部署 WordPress + MySQL。
  2. 进阶题:编写一个包含 Web、数据库、缓存、反向代理的完整 compose 文件。
  3. 实践题:使用多环境配置(dev/prod)管理不同的部署环境。

📖 下一章:企业级镜像仓库 —— 搭建和管理私有镜像仓库

http://www.jsqmd.com/news/1111062/

相关文章:

  • C++23新特性在CLion中的实战体验:从语法糖到生产力提升
  • 如何准确研判企业技术需求,避免伪需求和低效匹配?
  • 2026Word文档压缩实操指南:带图文文档轻量化、官方瘦身完整操作教程
  • 10分钟搞定Joy-Con手柄连接电脑:从蓝牙配到游戏畅玩的完整方案
  • CentOS 7.9 64位 PostgreSQL安装和配置指南
  • 2026多端AI抠图工具指南:免费付费网页电脑手机软件实操教程
  • 杰理之获取设备总数【篇】
  • 【BMS上位机UI(C#)】
  • 如何利用AI图像分层工具将单张插画秒变PSD分层文件:设计师的终极效率革命
  • StepCI:统一API测试框架,高效覆盖HTTP与GraphQL协议
  • 计算机Java毕设实战-基于 SpringBoot 的高校学生部门资料归档管理系统的设计与实现 校园学生会组织活动运维管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 2026免费音频转文字工具全解:电脑手机在线离线工具实操指南
  • 100_VSCOLD常用安装插件(持续更新)
  • 5分钟快速上手!NHSE动物森友会存档编辑器完整指南
  • 智能音频处理实战:Audacity AI效果插件如何革新专业工作流
  • 1979年7月1日:索尼 Walkman 问世——砍掉核心功能的“半残系统”,如何跑成数码史上最伟大的 Feature?
  • 【鸿蒙ArkTS】极简登录注册页面+页面跳转+密码校验
  • 2026年最新英语单词学习APP 很多老师都在用适合学生日常练词汇
  • 2026Word文件压缩至10M完整实操指南,含官方步骤、图片瘦身与清理隐藏内容技巧
  • 如何三步搞定网易云QQ音乐歌词?163MusicLyrics终极免费工具完整指南
  • Claude全方位揭秘:多产品特性、科研支持及常见问题解答
  • 图吧工具箱
  • codex连接过程中遇到各种报错如何解决(持续更新中)
  • novelWriter(开源小说创作工具
  • 杰理之搭配3in1 dongle1.13.0出现lea连接异【篇】
  • 【Windows运维】写一个安全的C盘一键清理BAT脚本(附源码+逐行代码详解)
  • Anthropic 推出测试版 Claude Science:打造面向科学家的 AI 工作台
  • 8051内部结构
  • 学生公寓人走自动断电系统的新功能和新技术
  • 1688拍立淘图片搜索API完整文档