Docker Compose 部署中间件实战
上一章学了语法,本章直接给两个可复用的完整配置:① MySQL + Redis 组合;② Nginx 反向代理前端与后端 API。两者都包含数据卷持久化与重启策略,照抄改参数即可上线。
示例一:MySQL + Redis
电商类项目最常见的存储组合:MySQL 存业务数据、Redis 做缓存。把两个服务写进同一 compose 文件,应用通过服务名 mysql、redis 访问:
services:
mysql:
image: mysql:8.0
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "Root@123"
MYSQL_DATABASE: shop
MYSQL_USER: shop
MYSQL_PASSWORD: "Shop@123"
command: --character-set-server=utf8mb4
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p$$MYSQL_ROOT_PASSWORD"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
restart: always
ports:
- "6379:6379"
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
volumes:
mysql-data:
redis-data:
启动并验证:
docker compose up -d
docker compose ps
# 输出:NAME STATUS mysql (healthy) redis (running)
docker compose exec mysql mysql -uroot -pRoot@123 -e "SHOW DATABASES;"
示例二:Nginx 反代前端与后端 API
静态页面由 Nginx 托管,/api/ 请求反代到后端容器。后端用源码目录构建,前端目录挂载 HTML 与 Nginx 站点配置;此例默认与示例一合并在同一 compose 项目运行(backend 用服务名 mysql 连库),代码改动后执行 docker compose up -d --build 重建:
services:
backend:
build: ./backend # 目录内需有 Dockerfile
restart: unless-stopped
environment:
DB_HOST: mysql
depends_on:
mysql:
condition: service_healthy
frontend:
image: nginx:1.27-alpine
restart: unless-stopped
ports:
- "80:80"
volumes:
- ./frontend/html:/usr/share/nginx/html:ro
- ./frontend/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- backend
# frontend/nginx.conf:同一 compose 网络内,服务名即主机名
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /api/ {
proxy_pass http://backend:8080/; # backend 是容器网络别名
}
}
注意事项
- 数据卷持久化:mysql-data、redis-data 挂到具名卷,容器删了重建数据仍在;但 docker compose down -v 会把卷一起删掉,务必慎用;
- 重启策略:生产服务都配 restart: always 或 unless-stopped,机器重启后自动拉起;
- 顺序与就绪:depends_on 只保证启动先后,真正「等就绪」要靠 condition: service_healthy 配合健康检查(示例二已示范)。
小结
中间件上 Compose 的套路是固定的:镜像 + 端口 + 环境变量 + 具名卷 + healthcheck + restart,再让应用容器通过服务名连接;Nginx 场景则把前端挂载进来、/api/ 反代到后端服务名即可。照这两个模板改改,多数部署需求都能覆盖。