Docker Compose配置模板:快速搭建常见应用架构
Docker Compose配置模板:快速搭建常见应用架构
引言:多容器应用部署的痛点与解决方案
你是否还在为多容器应用的复杂配置而烦恼?手动管理数据库、缓存、Web服务之间的网络连接和依赖关系耗费大量时间?Docker Compose(容器编排工具)通过单一配置文件简化了这一流程,让你用几行代码即可定义完整的应用架构。本文提供5种常见应用场景的配置模板,涵盖开发环境到生产部署,附带最佳实践和性能优化指南,读完你将能够:
- 快速搭建LNMP、微服务、API网关等架构
- 掌握环境变量、依赖管理、网络配置等核心技巧
- 实现配置复用与跨环境部署
- 解决数据持久化、服务健康检查等关键问题
Docker Compose核心概念与基础语法
配置文件结构解析
Docker Compose使用YAML格式的配置文件(默认compose.yaml或docker-compose.yaml)定义多容器应用。核心结构包含4个顶级元素:
version: '3.8' # Compose文件格式版本(推荐使用3.8+)
services: # 定义应用的服务容器
networks: # 自定义网络配置
volumes: # 数据卷声明(用于持久化数据)
configs: # 配置文件管理(生产环境)
关键参数速查表
| 参数 | 作用说明 | 常用值示例 |
|---|---|---|
image | 指定服务使用的镜像 | nginx:alpine, mysql:8.0 |
build | 从Dockerfile构建镜像 | ./docker/app |
ports | 端口映射(主机:容器) | 8080:80, 3306:3306 |
environment | 设置环境变量 | MYSQL_ROOT_PASSWORD=secret |
volumes | 数据卷挂载 | ./data:/var/lib/mysql |
depends_on | 定义服务启动顺序依赖 | ['db', 'redis'] |
restart | 容器重启策略 | always, on-failure:3 |
networks | 连接到指定网络 | app-network |
healthcheck | 服务健康检查配置 | test: ["CMD", "curl", "-f", "http://localhost"] |
基础示例:单服务配置
以下是一个最简单的Nginx服务配置,可直接保存为compose.yaml并通过docker compose up -d启动:
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html # 本地目录挂载到容器
restart: unless-stopped # 除非手动停止,否则总是重启
场景化配置模板
模板1:LNMP开发环境(Linux+Nginx+MySQL+PHP)
适合PHP Web应用开发,包含代码热重载和phpMyAdmin管理工具:
version: '3.8'
services:
# Nginx服务
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d # Nginx配置
- ./app:/var/www/html # PHP应用代码
depends_on:
- php
networks:
- lnmp-network
# PHP服务(FPM模式)
php:
build:
context: ./php
dockerfile: Dockerfile
volumes:
- ./app:/var/www/html # 共享代码目录
- ./php/php.ini:/usr/local/etc/php/php.ini # PHP配置
environment:
- DB_HOST=mysql
- DB_USER=devuser
- DB_PASSWORD=devpass
- DB_NAME=devdb
depends_on:
- mysql
networks:
- lnmp-network
# MySQL数据库
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=devdb
- MYSQL_USER=devuser
- MYSQL_PASSWORD=devpass
volumes:
- mysql-data:/var/lib/mysql # 数据持久化
- ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql # 初始化脚本
networks:
- lnmp-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]
interval: 10s
timeout: 5s
retries: 5
# phpMyAdmin管理工具
phpmyadmin:
image: phpmyadmin/phpmyadmin
ports:
- "8080:80"
environment:
- PMA_HOST=mysql
- PMA_USER=devuser
- PMA_PASSWORD=devpass
depends_on:
- mysql
networks:
- lnmp-network
# 定义命名卷(数据持久化)
volumes:
mysql-data: # 自动创建的命名卷,数据存储在Docker管理的目录
# 自定义网络(隔离不同应用网络)
networks:
lnmp-network:
driver: bridge # 默认桥接网络
使用说明:
- 创建项目目录结构:
./ ├── compose.yaml ├── app/ # PHP应用代码 ├── nginx/ │ └── conf.d/ # Nginx配置文件 └── mysql/ └── init.sql # 数据库初始化脚本 - 启动服务:
docker compose up -d - 访问应用:http://localhost
- 管理数据库:http://localhost:8080
模板2:微服务架构(API服务+Redis+MongoDB)
现代微服务应用通常包含API服务、缓存、数据库等组件。以下模板展示具有服务依赖关系的微服务配置:
version: '3.8'
services:
# API网关(反向代理)
gateway:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- user-service
- order-service
networks:
- microservice-network
restart: always
# 用户服务API
user-service:
build: ./services/user # 从本地Dockerfile构建
environment:
- SPRING_PROFILES_ACTIVE=prod
- REDIS_HOST=redis
- MONGO_URI=mongodb://mongo:27017/userdb
depends_on:
redis:
condition: service_healthy # 等待Redis健康检查通过
mongo:
condition: service_started # 仅需Mongo启动(无需健康检查)
networks:
- microservice-network
restart: on-failure:3 # 失败时重启,最多3次
deploy:
resources:
limits:
cpus: '0.5' # 限制CPU使用
memory: 512M # 限制内存使用
# 订单服务API
order-service:
build: ./services/order
environment:
- SPRING_PROFILES_ACTIVE=prod
- REDIS_HOST=redis
- MONGO_URI=mongodb://mongo:27017/orderdb
depends_on:
- redis
- mongo
networks:
- microservice-network
restart: on-failure:3
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
# Redis缓存
redis:
image: redis:alpine
command: redis-server --requirepass redis-pass # 设置密码
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- microservice-network
healthcheck:
test: ["CMD", "redis-cli", "-a", "redis-pass", "ping"]
interval: 5s
timeout: 3s
retries: 30
# MongoDB数据库
mongo:
image: mongo:5.0
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=mongo-root
- MONGO_INITDB_ROOT_PASSWORD=mongo-pass
volumes:
- mongo-data:/data/db
networks:
- microservice-network
# 持久化数据卷
volumes:
redis-data:
mongo-data:
# 微服务专用网络
networks:
microservice-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.28.0.0/16 # 自定义子网
架构流程图:
模板3:React前端开发环境(带热重载)
为前端开发提供零配置环境,支持代码热更新和依赖安装:
version: '3.8'
services:
# React开发服务器
react-dev:
image: node:18-alpine
user: node # 使用非root用户避免权限问题
working_dir: /app
ports:
- "3000:3000" # 开发服务器端口
- "35729:35729" # LiveReload端口
volumes:
- ./:/app # 挂载项目目录
- node_modules:/app/node_modules # 单独挂载依赖目录(避免覆盖)
environment:
- NODE_ENV=development
- REACT_APP_API_URL=http://localhost:4000 # API地址环境变量
command: sh -c "npm install && npm start" # 安装依赖并启动开发服务器
networks:
- frontend-network
# API模拟服务器(可选)
mock-api:
image: node:18-alpine
user: node
working_dir: /app
ports:
- "4000:4000"
volumes:
- ./mock-api:/app
- mock-api-node_modules:/app/node_modules
command: sh -c "npm install && npm run start"
networks:
- frontend-network
networks:
frontend-network:
driver: bridge
volumes:
node_modules: # 存储前端依赖
mock-api-node_modules: # 存储API模拟服务依赖
使用特性:
- 代码热重载:修改React组件后自动刷新浏览器
- 依赖持久化:
node_modules使用命名卷存储,避免重复安装 - 权限兼容:使用
node用户运行容器,解决文件权限问题 - 环境隔离:通过环境变量区分开发/生产API地址
模板4:ELK日志收集系统(企业级监控)
ELK Stack(Elasticsearch, Logstash, Kibana)用于集中式日志收集与分析:
version: '3.8'
services:
# Elasticsearch存储与索引日志
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.6.0
environment:
- discovery.type=single-node # 单节点模式(开发环境)
- ES_JAVA_OPTS=-Xms512m -Xmx512m # Java内存设置
- xpack.security.enabled=false # 禁用安全功能(开发环境)
ports:
- "9200:9200" # ES API端口
volumes:
- es-data:/usr/share/elasticsearch/data
networks:
- elk-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
interval: 10s
timeout: 10s
retries: 120
# Logstash处理日志
logstash:
image: docker.elastic.co/logstash/logstash:8.6.0
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline # 配置管道
- ./logs:/var/log/app # 挂载应用日志目录
environment:
- LS_JAVA_OPTS=-Xms256m -Xmx256m
depends_on:
elasticsearch:
condition: service_healthy
networks:
- elk-network
# Kibana可视化界面
kibana:
image: docker.elastic.co/kibana/kibana:8.6.0
ports:
- "5601:5601" # Kibana Web界面
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
elasticsearch:
condition: service_healthy
networks:
- elk-network
networks:
elk-network:
driver: bridge
volumes:
es-data: # 存储Elasticsearch数据
数据流向图:
模板5:生产环境部署配置(带SSL和健康检查)
生产环境需要考虑安全性、稳定性和可维护性,以下模板包含HTTPS配置、自动重启、健康检查等关键特性:
version: '3.8'
services:
# Nginx反向代理(带SSL)
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf:/etc/nginx/conf.d
- ./nginx/ssl:/etc/nginx/ssl # SSL证书
- static-files:/var/www/static
depends_on:
- webapp
networks:
- prod-network
restart: always
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"]
interval: 10s
timeout: 5s
retries: 3
# Web应用服务(Django/Flask示例)
webapp:
build:
context: ./webapp
dockerfile: Dockerfile.prod # 生产环境Dockerfile
expose:
- "8000" # 内部端口,不对外暴露
environment:
- DJANGO_SETTINGS_MODULE=config.settings.prod
- DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
- SECRET_KEY=${DJANGO_SECRET_KEY}
- ALLOWED_HOSTS=${DOMAIN_NAME}
depends_on:
- db
- redis
networks:
- prod-network
restart: always
command: gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers 4
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost:8000/health/"]
interval: 15s
timeout: 5s
retries: 3
# PostgreSQL数据库
db:
image: postgres:14-alpine
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=${DB_NAME}
networks:
- prod-network
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
# Redis缓存与队列
redis:
image: redis:alpine
volumes:
- redis-data:/data
networks:
- prod-network
restart: always
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 30
# 定时任务/异步任务处理器
celery:
build:
context: ./webapp
dockerfile: Dockerfile.prod
command: celery -A config worker -l INFO
environment:
- DJANGO_SETTINGS_MODULE=config.settings.prod
- DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
- SECRET_KEY=${DJANGO_SECRET_KEY}
depends_on:
- webapp
- redis
networks:
- prod-network
restart: always
networks:
prod-network:
driver: bridge
volumes:
postgres-data:
redis-data:
static-files:
生产环境安全最佳实践:
- 环境变量管理:敏感信息(如数据库密码、密钥)通过环境变量注入,避免硬编码
- 最小权限原则:容器仅暴露必要端口,使用
expose替代ports进行内部通信 - 健康检查:所有服务配置健康检查,确保故障时自动恢复
- 数据备份:定期备份命名卷数据(
postgres-data,redis-data) - SSL配置:使用Let's Encrypt免费证书,配置自动续期
高级配置技巧与最佳实践
环境变量与配置文件分离
使用.env文件存储环境变量,配合env_file参数加载,实现配置与代码分离:
# compose.yaml
services:
app:
image: myapp:latest
env_file: .env # 加载环境变量文件
environment:
- DEBUG=${DEBUG:-false} # 环境变量默认值
# .env文件(添加到.gitignore)
DB_USER=prod_user
DB_PASSWORD=secure_password_here
DB_NAME=app_prod
DJANGO_SECRET_KEY=long_random_string
DOMAIN_NAME=example.com
多环境配置策略
通过-f参数指定不同环境的配置文件,实现开发/测试/生产环境隔离:
# 开发环境(默认配置)
docker compose -f compose.yaml up
# 测试环境(扩展开发配置)
docker compose -f compose.yaml -f compose.test.yaml up
# 生产环境(最小化配置)
docker compose -f compose.prod.yaml up
配置文件继承示例:
# compose.test.yaml(仅包含测试环境特有配置)
version: '3.8'
services:
app:
environment:
- DEBUG=true
- TEST_MODE=true
volumes:
- ./tests:/app/tests # 挂载测试代码
test-db:
image: postgres:14-alpine
environment:
- POSTGRES_DB=app_test
性能优化指南
- 镜像选择:优先使用Alpine版本镜像(体积小、安全漏洞少),如
nginx:alpine替代nginx - 依赖缓存:构建镜像时优化层缓存,例如:
# 先复制依赖文件,再复制代码 COPY package.json package-lock.json ./ RUN npm ci # 安装依赖 COPY . . # 复制代码(修改频率高) - 资源限制:为每个服务设置资源限制,避免单个服务耗尽主机资源:
deploy: resources: limits: cpus: '1' memory: 1G reservations: cpus: '0.5' memory: 512M - 网络优化:使用自定义桥接网络替代默认网络,减少广播流量
常见问题解决方案
1. 服务启动顺序问题
问题:依赖的数据库还未就绪,应用服务已启动导致连接失败
解决方案:使用depends_on的条件判断(v3.8+支持):
services:
app:
depends_on:
db:
condition: service_healthy # 等待数据库健康检查通过
2. 数据卷权限问题
问题:容器内创建的文件所有者为root,宿主机无法修改
解决方案:在Dockerfile中创建非root用户,或启动时指定用户ID:
services:
app:
user: "${UID}:${GID}" # 使用宿主机用户ID启动容器
volumes:
- ./data:/app/data
3. 跨平台兼容性
问题:在Windows或Mac上开发的配置文件在Linux服务器上运行异常
解决方案:避免使用绝对路径,配置文件使用LF换行符,路径分隔符统一使用/
部署与运维命令速查表
| 命令 | 作用 | 示例 |
|---|---|---|
docker compose up | 创建并启动所有服务 | -d 后台运行,--build 强制重建 |
docker compose down | 停止并删除服务/网络 | -v 删除数据卷,--rmi all 删除镜像 |
docker compose ps | 查看服务状态 | -a 显示所有容器 |
docker compose logs | 查看服务日志 | -f 实时跟踪,--tail=100 显示最后100行 |
docker compose exec | 进入运行中的容器 | webapp sh 进入webapp容器的shell |
docker compose pull | 拉取最新镜像 | --include-deps 拉取依赖服务镜像 |
docker compose build | 构建服务镜像 | --no-cache 不使用缓存 |
docker compose restart | 重启服务 | webapp 仅重启webapp服务 |
docker compose cp | 在容器与主机间复制文件 | webapp:/app/logs ./logs |
总结与扩展学习
本文提供的5种配置模板覆盖了从开发到生产的全场景应用需求,通过Docker Compose可以显著降低多容器应用的管理复杂度。进阶学习建议:
- Compose文件版本:关注最新版特性(v3.8+),如
depends_on条件、健康检查等 - Docker Swarm集成:使用
docker stack deploy将Compose配置部署到Swarm集群 - CI/CD集成:结合GitLab CI或GitHub Actions实现自动构建和部署
- 监控与日志:集成Prometheus+Grafana监控容器性能,ELK Stack集中管理日志
通过合理使用Docker Compose,开发团队可以实现"一次配置,到处运行"的目标,大幅提升协作效率和部署一致性。
更多推荐



所有评论(0)