**作者:洛水石** | **更新日期:2026-05-11** | **标签:Docker | Docker Compose | 容器编排 | DevOps**
前言
团队来了个新同事,问:"我本地跑个项目要怎么配数据库、Redis、消息队列?"
以前的我:给你10个配置文件,自己装MySQL、Redis、Elasticsearch...大概配置一天能跑起来。
现在的我:一条命令,`docker-compose up -d`,3分钟搞定。
Docker Compose就是来解决****多容器协作****问题的。本文从实战出发,手把手教你用Docker Compose搭建完整的开发/生产环境。
一、Docker Compose核心概念
1.1 为什么需要Compose
|---------------|----------|-----------------|
| 场景 | 痛点 | Compose解决方案 |
| **本地开发** | 手动安装多个服务 | 一键启动整套环境 |
| **测试环境** | 环境不一致 | 固定版本,隔离环境 |
| **演示部署** | 快速交付 | 配置文件即交付物 |
| **CI/CD** | 构建复杂 | 可重复、可版本化 |
1.2 核心组件
▲ Docker Compose架构图 
docker-compose.yml
├── version: "3.8" # Compose版本
├── services: # 服务定义
│ ├── web: # 服务名
│ │ ├── image: nginx # 或 build: .
│ │ ├── ports: # 端口映射
│ │ ├── environment: # 环境变量
│ │ ├── volumes: # 持久化
│ │ ├── depends_on: # 依赖关系
│ │ └── networks: # 网络配置
│ ├── api:
│ └── db:
├── networks: # 网络定义
└── volumes: # 卷定义
二、快速开始
▲ Docker容器生命周期 
2.1 第一个Compose项目
docker-compose.yml
version: "3.8"
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes: - ./html:/usr/share/nginx/html:ro
depends_on: - api
networks: - app-network
api:
image: node:18-alpine
working_dir: /app
volumes:
- ./api:/app
command: npm start
networks: - app-network
networks:
app-network:
driver: bridge
启动
docker-compose up -d
查看状态
docker-compose ps
查看日志
docker-compose logs -f api
停止
docker-compose down
重新构建
docker-compose up -d --build
2.2 Laravel项目实战
docker-compose.yml
version: "3.8"
services:
PHP应用
app:
build:
context: ./docker/php
dockerfile: Dockerfile
container_name: laravel_app
ports:
- "8000:8000"
volumes: - ./:/var/www/html
depends_on: - mysql
- redis
environment: - DB_HOST=mysql
- DB_DATABASE=laravel
- DB_USERNAME=root
- DB_PASSWORD=secret
- REDIS_HOST=redis
networks: - laravel
Nginx反向代理
nginx:
image: nginx:alpine
container_name: laravel_nginx
ports:
- "80:80"
volumes: - ./:/var/www/html
- ./docker/nginx/conf.d:/etc/nginx/conf.d:ro
depends_on: - app
networks: - laravel
MySQL数据库
mysql:
image: mysql:8.0
container_name: laravel_mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: laravel
MYSQL_USER: laravel
MYSQL_PASSWORD: laravel123
volumes: - mysql_data:/var/lib/mysql
networks: - laravel
Redis缓存
redis:
image: redis:7-alpine
container_name: laravel_redis
ports:
- "6379:6379"
volumes: - redis_data:/data
command: redis-server --appendonly yes
networks: - laravel
Composer依赖
composer:
image: composer:2
container_name: laravel_composer
volumes:
- ./:/app
working_dir: /app
depends_on: - app
networks: - laravel
networks:
laravel:
driver: bridge
volumes:
mysql_data:
redis_data:
2.3 Nginx配置
docker/nginx/conf.d/default.conf
upstream laravel {
server app:9000;
}
server {
listen 80;
server_name localhost;
root /var/www/html/public;
index index.php index.html;
charset utf-8;
location / {
try_files uri uri/ /index.php?$query_string;
}
location ~ \.php {
fastcgi_pass laravel;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME realpath_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
2.4 PHP Dockerfile
docker/php/Dockerfile
FROM php:8.2-fpm-alpine
安装扩展
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl bcmath
安装Redis扩展
RUN pecl install redis && docker-php-ext-enable redis
安装Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
EXPOSE 9000
三、高级配置
3.1 环境变量文件
.env 文件
MYSQL_ROOT_PASSWORD=secret
MYSQL_DATABASE=laravel
REDIS_PASSWORD=redis123
NGINX_PORT=80
docker-compose.yml
version: "3.8"
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: {MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: {MYSQL_DATABASE}
env_file:
- .env
volumes: - mysql_data:/var/lib/mysql
3.2 多环境配置
docker-compose.yml (基础配置)
version: "3.8"
services:
app:
build: ./docker/php
volumes:
- ./:/var/www/html
depends_on: - mysql
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
networks:
app-network:
driver: bridge
volumes:
mysql_data:
docker-compose.dev.yml (开发环境)
version: "3.8"
services:
app:
environment:
- DEBUG=true
- LOG_LEVEL=debug
ports: - "8000:8000"
mysql:
ports:
- "3306:3306"
docker-compose.prod.yml (生产环境)
version: "3.8"
services:
app:
environment:
- DEBUG=false
- LOG_LEVEL=info
restart: unless-stopped
volumes: - app_data:/var/www/html
mysql:
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_PROD_PASSWORD}
restart: unless-stopped
networks:
app-network:
driver: overlay
volumes:
app_data:
使用不同环境
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
3.3 资源限制
version: "3.8"
services:
app:
deploy:
resources:
limits:
cpus: '1.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
mysql:
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
3.4 健康检查
version: "3.8"
services:
mysql:
image: mysql:8.0
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
app:
depends_on:
mysql:
condition: service_healthy # 等待健康
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
四、Swarm集群编排
▲ Docker Swarm集群架构 
4.1 切换到Swarm模式
初始化Swarm
docker swarm init
加入Worker节点
docker swarm join-token worker
查看节点
docker node ls
4.2 Swarm部署
docker-compose.swarm.yml
version: "3.8"
services:
app:
image: myapp:latest
deploy:
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: '1.0'
memory: 1G
ports:
- "80:80"
volumes: - app_data:/app/data
configs: - source: app_config
target: /app/config.json
secrets: - source: db_password
target: /run/secrets/db_password
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
secrets: - source: db_password
configs:
app_config:
file: ./config/app.json
secrets:
db_password:
file: ./secrets/db_password.txt
volumes:
app_data:
mysql_data:
部署到Swarm
docker stack deploy -c docker-compose.swarm.yml myapp
查看服务
docker service ls
docker service ps myapp_app
扩缩容
docker service scale myapp_app=5
更新服务
docker service update --image myapp:v2 myapp_app
五、日志与监控
5.1 日志配置
version: "3.8"
services:
app:
logging:
driver: "json-file"
options:
max-size: "100m"
max-file: "5"
compress: "true"
volumes:
- ./logs:/var/www/html/storage/logs
5.2 ELK日志收集
version: "3.8"
services:
app:
logging:
driver: fluentd
options:
fluentd-address: localhost:24224
tag: app.logs
fluentd:
image: fluent/fluentd:v1.16
ports:
- "24224:24224"
- "24224:24224/udp"
volumes: - ./docker/fluentd/conf:/fluentd/etc
depends_on: - elasticsearch
elasticsearch:
image: elasticsearch:8.11.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
volumes: - es_data:/usr/share/elasticsearch/data
kibana:
image: kibana:8.11.0
ports:
- "5601:5601"
depends_on: - elasticsearch
volumes:
es_data:
六、CI/CD集成
6.1 GitHub Actions
.github/workflows/deploy.yml
name: Deploy to Staging
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
-
uses: actions/checkout@v4
-
name: Build images
run: |
docker-compose -f docker-compose.yml -f docker-compose.prod.yml build -
name: Push to registry
run: |
echo {{ secrets.DOCKER_TOKEN }} \| docker login -u {{ secrets.DOCKER_USER }} --password-stdin
docker-compose -f docker-compose.yml -f docker-compose.prod.yml push -
name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: {{ secrets.SERVER_HOST }} username: {{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_KEY }}
script: |
cd /opt/app
docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
docker-compose -f docker-compose.yml -f docker-compose.prod.yml logs -f --tail=100
七、常见问题
Q1: 端口冲突?
检查端口占用
netstat -tlnp | grep 80
停止其他容器
docker-compose down
修改端口映射
ports:
- "8080:80" # 改为8080
Q2: 数据卷权限问题?
在Dockerfile中设置
RUN chown -R www-data:www-data /var/www/html
RUN chmod -R 755 /var/www/html
Q3: 网络不通?
查看网络
docker network ls
docker network inspect app_app-network
手动创建网络
docker network create my-network
在compose中引用
networks:
my-network:
external: true
总结
Docker Compose最佳实践:
|--------------|-------------------|
| 场景 | 建议 |
| **开发环境** | 挂载源码卷,热重载 |
| **测试环境** | 固定镜像版本,隔离网络 |
| **生产环境** | Swarm部署,资源限制,日志收集 |
**核心命令**:
日常操作
docker-compose up -d # 启动
docker-compose down # 停止
docker-compose restart # 重启
docker-compose logs -f # 查看日志
维护操作
docker-compose build --no-cache # 重新构建
docker-compose exec app bash # 进入容器
docker-compose ps # 查看状态
清理
docker-compose down -v # 删除卷
docker system prune -f # 清理未使用资源
**进阶方向**:
- Kubernetes(K8s)编排大规模集群
- Docker Stack部署Swarm集群
- Helm Charts管理复杂应用
*一条命令,搭建完整环境;一份配置,实现快速交付。*