Docker Compose 从入门到实战:多容器编排完全指南 Docker Compose 从入门到实战多容器编排完全指南一、什么是 Docker ComposeDocker Compose 是 Docker 官方提供的多容器编排工具用于定义和运行多个 Docker 容器的应用。通过一个docker-compose.yml文件你可以配置应用程序所需的所有服务容器然后使用一条命令即可启动所有服务。Docker Compose 的核心价值将多个容器的配置、依赖关系、网络、数据卷等集中声明在一个 YAML 文件中实现多容器应用的一键部署和环境一致性。1.1 适用场景场景说明开发环境快速搭建完整的应用依赖数据库、缓存、消息队列等本地测试模拟生产环境进行集成测试CI/CD 流水线自动化构建和测试环境单机生产部署小型项目或微服务部署生产环境一般用 K8s二、安装 Docker Compose安装看这篇二进制安装 Docker 和 Docker-compose三、docker-compose.yml 核心语法详解3.1 基础结构version:3.8# Compose 文件版本services:# 服务定义每个服务对应一个容器web:# 服务名称image:nginx# 使用的镜像ports:# 端口映射-8080:80volumes:# 数据卷挂载-./html:/usr/share/nginx/htmlnetworks:# 网络定义可选default:driver:bridgevolumes:# 卷定义可选data:四、核心配置项详解4.1 image——指定镜像services:web:image:nginx:alpine# 从仓库拉取app:build:./app# 从 Dockerfile 构建# 或指定构建参数build:context:./appdockerfile:Dockerfileargs:VERSION:1.0db:image:mysql:5.74.2 ports——端口映射services:web:ports:-8080:80# 宿主机:容器-127.0.0.1:8081:81# 绑定到指定 IP-8082:80# 多个端口映射# 暴露内部端口但不映射到宿主机仅服务间通信app:expose:-8080-90904.3 volumes——数据卷挂载services:web:volumes:# 绑定挂载宿主机目录:容器目录-./app:/app# 命名卷-data:/var/lib/mysql# 只读挂载-./config:/etc/app/config:ro# 相对路径挂载-./logs:/var/log/appdb:volumes:-db_data:/var/lib/mysql# 定义命名卷volumes:data:db_data:4.4 environment 与 env_file——环境变量services:web:# 直接定义environment:-NODE_ENVproduction-DB_HOSTmysql-APP_PORT8080db:# 从文件加载.env 文件env_file:-.env-./config/db.envenvironment:-MYSQL_ROOT_PASSWORD${MYSQL_ROOT_PASSWORD}# 引用外部变量.env文件示例MYSQL_ROOT_PASSWORD123456 MYSQL_DATABASEmyapp DB_USERadmin4.5 depends_on——依赖与启动顺序services:web:image:nginxdepends_on:-app-dbapp:build:./appdepends_on:-dbdb:image:mysql:5.7注意depends_on仅控制容器启动顺序不等待服务完全就绪。如需健康检查后才启动需配合conditionservices:web:depends_on:db:condition:service_healthy# 等待 db 健康后才启动db:image:mysql:5.7healthcheck:test:[CMD,mysqladmin,ping,-h,localhost]interval:10stimeout:5sretries:54.6 restart——重启策略services:web:restart:always# 总是重启# restart: unless-stopped # 除非手动停止# restart: on-failure:3 # 失败时重启最多 3 次# restart: no # 不自动重启默认4.7 networks——网络配置services:web:networks:-frontend-backendapp:networks:-backenddb:networks:-backend# 定义网络networks:frontend:driver:bridgebackend:driver:bridgeinternal:true# 内部网络不对外暴露4.8 command 与 entrypoint——启动命令services:web:image:python:3.11command:python app.py# 或数组格式command:[python,app.py]app:build:.entrypoint:[java,-jar]command:[app.jar]# 组合使用实际执行 java -jar app.jar4.9 container_name——指定容器名services:web:container_name:my-web-app# 固定容器名image:nginx注意生产环境尽量不要固定容器名避免冲突。4.10 logging——日志配置services:web:logging:driver:json-file# 日志驱动options:max-size:10m# 单个日志文件最大 10Mmax-file:3# 最多保留 3 个文件五、配置文件完整参考含全部常用字段version:3.8services:# Web 服务 web:image:nginx:alpinecontainer_name:nginx-webrestart:alwaysports:-80:80-443:443volumes:-./html:/usr/share/nginx/html:ro-./nginx.conf:/etc/nginx/conf.d/default.conf:rodepends_on:app:condition:service_healthynetworks:-frontend-backendlogging:driver:json-fileoptions:max-size:10mmax-file:3# 应用服务 app:build:context:./appdockerfile:Dockerfileargs:BUILD_ENV:productioncontainer_name:spring-apprestart:alwaysenvironment:-SPRING_PROFILES_ACTIVEprod-DB_HOSTdb-DB_PORT3306-REDIS_HOSTredisenv_file:-./config/app.envvolumes:-./logs:/app/logs-app_data:/app/dataports:-8080:8080depends_on:db:condition:service_healthyredis:condition:service_healthyhealthcheck:test:[CMD,curl,-f,http://localhost:8080/actuator/health]interval:30stimeout:3sretries:3start_period:30snetworks:-backend-internallogging:driver:json-fileoptions:max-size:50mmax-file:5# 数据库服务 db:image:mysql:5.7container_name:mysql-dbrestart:alwaysenvironment:-MYSQL_ROOT_PASSWORD${MYSQL_ROOT_PASSWORD}-MYSQL_DATABASEmyapp-MYSQL_USERappuser-MYSQL_PASSWORD${MYSQL_USER_PASSWORD}volumes:-db_data:/var/lib/mysql-./init.sql:/docker-entrypoint-initdb.d/init.sql:roports:-3306:3306healthcheck:test:[CMD,mysqladmin,ping,-h,127.0.0.1,-uroot,-p${MYSQL_ROOT_PASSWORD}]interval:10stimeout:5sretries:5networks:-backend-internal# Redis 缓存 redis:image:redis:7.0-alpinecontainer_name:redis-cacherestart:alwayscommand:redis-server--requirepass ${REDIS_PASSWORD}volumes:-redis_data:/dataports:-6379:6379healthcheck:test:[CMD,redis-cli,ping]interval:10stimeout:3sretries:5networks:-backend# 网络定义 networks:frontend:driver:bridgebackend:driver:bridgeinternal:falseinternal:driver:bridgeinternal:true# 内部网络无法访问外部# 卷定义 volumes:db_data:driver:localredis_data:app_data:六、常用命令详解6.1 基础命令命令说明示例up启动所有服务docker-compose up -ddown停止并删除所有容器、网络docker-compose downps查看服务状态docker-compose pslogs查看日志docker-compose logs -f webstop停止服务不删除容器docker-compose stopstart启动已停止的服务docker-compose startrestart重启服务docker-compose restart webexec进入容器执行命令docker-compose exec web bashbuild构建或重新构建服务镜像docker-compose build --no-cachepull拉取服务镜像docker-compose pullpush推送服务镜像到仓库docker-compose pushtop查看容器内进程docker-compose topconfig验证配置文件格式docker-compose config6.2 常用组合示例# 后台启动所有服务docker-composeup-d# 只启动特定服务docker-composeup-dweb db# 查看所有容器状态docker-composeps-a# 实时查看所有服务日志docker-composelogs-f# 查看特定服务日志最近 100 行docker-composelogs--tail100web# 进入 Web 容器终端docker-composeexecweb /bin/sh# 执行数据库备份docker-composeexecdb mysqldump-uroot-p123456myappbackup.sql# 停止并删除所有容器、网络、卷docker-composedown-v# 重新构建并启动docker-composeup-d--build# 验证配置文件docker-composeconfig--quiet七、实战案例7.1 案例一LAMP 环境WordPress MySQLversion:3.8services:# WordPress 服务wordpress:image:wordpress:latestcontainer_name:wordpressrestart:alwaysports:-8080:80environment:WORDPRESS_DB_HOST:dbWORDPRESS_DB_USER:wordpressWORDPRESS_DB_PASSWORD:wordpress_passWORDPRESS_DB_NAME:wordpressvolumes:-wordpress_data:/var/www/html-./wp-content:/var/www/html/wp-contentdepends_on:db:condition:service_healthynetworks:-webnet# MySQL 数据库db:image:mysql:5.7container_name:mysql-wprestart:alwaysenvironment:MYSQL_ROOT_PASSWORD:root_passMYSQL_DATABASE:wordpressMYSQL_USER:wordpressMYSQL_PASSWORD:wordpress_passvolumes:-db_data:/var/lib/mysqlhealthcheck:test:[CMD,mysqladmin,ping,-h,localhost]interval:10stimeout:5sretries:5networks:-webnet# phpMyAdmin可选phpmyadmin:image:phpmyadmin/phpmyadmincontainer_name:phpmyadminrestart:alwaysports:-8081:80environment:PMA_HOST:dbPMA_PORT:3306UPLOAD_LIMIT:100Mdepends_on:-dbnetworks:-webnetvolumes:wordpress_data:db_data:networks:webnet:启动访问WordPress: http://localhost:8080phpMyAdmin: http://localhost:80817.2 案例二微服务架构Spring Boot MySQL Redis Nginxversion:3.8services:# Nginx 网关nginx:image:nginx:alpinecontainer_name:api-gatewayrestart:alwaysports:-80:80volumes:-./nginx/nginx.conf:/etc/nginx/nginx.conf:ro-./nginx/conf.d:/etc/nginx/conf.d:rodepends_on:-user-service-order-service-product-servicenetworks:-frontend-backend# 用户服务user-service:build:./user-servicecontainer_name:user-servicerestart:alwaysenvironment:-SPRING_PROFILES_ACTIVEdocker-DB_HOSTmysql-REDIS_HOSTredisports:-8081:8080depends_on:mysql:condition:service_healthyredis:condition:service_healthyhealthcheck:test:[CMD,curl,-f,http://localhost:8080/actuator/health]interval:30stimeout:3sretries:3start_period:30snetworks:-backend# 订单服务order-service:build:./order-servicecontainer_name:order-servicerestart:alwaysenvironment:-SPRING_PROFILES_ACTIVEdocker-DB_HOSTmysql-REDIS_HOSTredisports:-8082:8080depends_on:mysql:condition:service_healthyredis:condition:service_healthyhealthcheck:test:[CMD,curl,-f,http://localhost:8080/actuator/health]interval:30stimeout:3sretries:3start_period:30snetworks:-backend# 商品服务product-service:build:./product-servicecontainer_name:product-servicerestart:alwaysenvironment:-SPRING_PROFILES_ACTIVEdocker-DB_HOSTmysql-REDIS_HOSTredisports:-8083:8080depends_on:mysql:condition:service_healthyredis:condition:service_healthyhealthcheck:test:[CMD,curl,-f,http://localhost:8080/actuator/health]interval:30stimeout:3sretries:3start_period:30snetworks:-backend# MySQLmysql:image:mysql:5.7container_name:mysql-microrestart:alwaysenvironment:-MYSQL_ROOT_PASSWORDroot123volumes:-mysql_data:/var/lib/mysql-./init.sql:/docker-entrypoint-initdb.d/init.sqlports:-3306:3306healthcheck:test:[CMD,mysqladmin,ping,-h,localhost,-uroot,-proot123]interval:10stimeout:5sretries:5networks:-backend# Redisredis:image:redis:7.0-alpinecontainer_name:redis-microrestart:alwaysvolumes:-redis_data:/dataports:-6379:6379healthcheck:test:[CMD,redis-cli,ping]interval:10stimeout:3sretries:5networks:-backendvolumes:mysql_data:redis_data:networks:frontend:driver:bridgebackend:driver:bridge八、常用环境变量文件 .env# .env 文件与 docker-compose.yml 同目录 # 数据库配置 MYSQL_ROOT_PASSWORDroot123456 MYSQL_DATABASEmyapp MYSQL_USERappuser MYSQL_PASSWORDapppass123 # 应用配置 APP_ENVproduction APP_PORT8080 JWT_SECRETyour-secret-key-here # Redis 配置 REDIS_PASSWORDredispass # 对外域名 DOMAINexample.com在docker-compose.yml中引用services:db:environment:MYSQL_ROOT_PASSWORD:${MYSQL_ROOT_PASSWORD}MYSQL_DATABASE:${MYSQL_DATABASE}MYSQL_USER:${MYSQL_USER}MYSQL_PASSWORD:${MYSQL_PASSWORD}九、最佳实践总结9.1 配置文件规范序号最佳实践说明1使用固定版本号避免latest保证环境一致性2使用.env管理敏感信息不将密码硬编码在 YAML 中3添加healthcheck健康检查确保服务就绪后再启动依赖4合理规划网络隔离前后端分离网络提高安全性5使用restart: always保证容器意外退出后自动恢复6限制日志文件大小避免磁盘爆满7使用命名卷持久化数据容器重启后数据不丢失8配置文件添加注释便于团队协作和维护9使用depends_oncondition确保依赖服务健康后才启动9.2 常用 .gitignore 内容# 环境变量含敏感信息 .env *.env # 日志目录 logs/ *.log # 数据卷目录避免提交大文件 data/ volumes/ # IDE 配置 .idea/ .vscode/ *.iml9.3 生产环境注意事项注意事项说明禁用latest标签指定具体版本号保证可追溯性使用国内镜像加速在docker-compose.yml中配置registry-mirrors设置资源限制使用deploy.resources.limits限制 CPU 和内存配置日志轮转避免日志占满磁盘使用外部卷便于数据备份和迁移定期备份数据数据库卷需要定期备份资源限制示例services:web:deploy:resources:limits:cpus:0.5memory:512Mreservations:cpus:0.25memory:256M十、常用命令速查表分类命令说明启动docker-compose up -d后台启动所有服务停止docker-compose down停止并删除容器、网络docker-compose down -v同时删除数据卷查看docker-compose ps查看服务状态docker-compose logs -f实时查看所有日志操作docker-compose exec web bash进入容器docker-compose restart web重启特定服务构建docker-compose build构建或重建镜像docker-compose build --no-cache不使用缓存构建调试docker-compose config验证配置文件docker-compose top查看容器内进程如果这篇文章对你有帮助欢迎收藏、分享也欢迎在评论区交流讨论