全部文章

Docker Compose 常用配置

Nginx、MySQL、PostgreSQL、Redis、MinIO 等常用服务的 Docker Compose 配置模板

目录 20 节

Docker Compose 常用配置

这页更适合当“本地服务编排起步模板”使用。真正难的通常不是写出一个能跑的 compose.yaml,而是把数据卷、环境变量、端口和服务关系一次性想清楚。

推荐写法原则

  • 默认给有状态服务加数据卷
  • 密码和密钥放进 .env
  • 对外暴露的端口尽量最少
  • 服务名保持简单,方便容器间互相访问
  • 先跑最小栈,再逐步加服务

Docker 基础见 Docker Desktop 安装与使用,本文提供常用服务的 Compose 模板。

Nginx 反向代理

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./html:/usr/share/nginx/html
      - ./certs:/etc/nginx/certs:ro
    restart: unless-stopped

适合做静态文件分发或统一代理入口,但正式使用时建议再补完整配置文件与证书目录管理。

MySQL

services:
  mysql:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: mydb
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    restart: unless-stopped

volumes:
  mysql_data:

MySQL 这类有状态服务最重要的是数据目录持久化,不要只图能跑。

PostgreSQL

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"
    volumes:
      - pg_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  pg_data:

PostgreSQL 在本地开发和测试环境里非常常见,和应用一起放进 Compose 是很自然的用法。

Redis

services:
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes
    restart: unless-stopped

volumes:
  redis_data:

如果 Redis 只是做临时缓存,也可以不持久化;如果承担消息、队列或状态角色,就要认真看持久化策略。

MinIO(S3 兼容对象存储)

services:
  minio:
    image: minio/minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
      MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
    volumes:
      - minio_data:/data
    command: server /data --console-address ":9001"
    restart: unless-stopped

volumes:
  minio_data:

MinIO 很适合本地模拟 S3,对文件上传、对象存储和测试环境特别有帮助。

Adminer(数据库管理)

services:
  adminer:
    image: adminer
    ports:
      - "8080:8080"
    restart: unless-stopped

数据库管理面板很好用,但不要长期暴露到公网。

完整示例:Web 应用栈

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://postgres:secret@postgres:5432/mydb
      REDIS_URL: redis://redis:6379
    depends_on:
      - postgres
      - redis
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: mydb
    volumes:
      - pg_data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    command: redis-server --appendonly yes
    restart: unless-stopped

volumes:
  pg_data:
  redis_data:

常见组合

Web 应用本地开发

  • app + postgres
  • app + redis
  • 必要时再补 adminer

自建服务入口

  • nginx
  • 后端应用服务
  • 证书目录 / 静态资源目录

文件服务 / 对象存储

  • minio
  • 业务服务
  • 可选管理面板

常用命令

docker compose up -d              # 后台启动
docker compose down               # 停止并删除容器
docker compose down -v            # 同时删除数据卷
docker compose logs -f app        # 查看指定服务日志
docker compose exec postgres psql -U postgres  # 进入数据库
docker compose pull               # 更新所有镜像
docker compose restart app        # 重启指定服务

环境变量

创建 .env 文件,Compose 会自动读取:

POSTGRES_PASSWORD=your_secure_password
MYSQL_ROOT_PASSWORD=your_secure_password
MINIO_USER=admin
MINIO_PASSWORD=your_secure_password

.env 加入 .gitignore,不要提交到版本控制。

常见问题

容器起来了,但服务互相连不上

优先检查服务名、端口和环境变量。容器内访问数据库时,通常应该写服务名而不是 localhost

一重启数据没了

说明你可能没挂数据卷,或者卷路径写错了。对数据库和对象存储来说,这通常是第一优先级问题。

depends_on 写了,为什么还是连不上数据库

depends_on 只保证启动顺序,不保证服务真正就绪。应用层最好自己处理重试或等待机制。

使用建议

  • 每个栈单独一个目录
  • compose.yaml.env.example 一起维护
  • 重要服务先跑 docker compose logs -f
  • 真正长期使用前,补健康检查、备份和升级策略

参考链接

阅读建议
  • - 先读标题和摘要,再结合目录决定从哪个章节开始精读。
  • - 看到具体命令、配置或步骤时,尽量在自己的环境里同步验证。
  • - 如果你只是快速查资料,可先看目录和相关文档,再决定是否深入全文。
适合谁看
  • - 希望把零散经验整理成长期可复用工作流的人
  • - 想先建立认知,再决定是否深入实践的人
  • - 希望阅读时顺手建立自己的操作清单或收藏体系的人
执行前检查
  • - 先浏览标题、摘要和目录,带着问题阅读会更高效
  • - 顺手记录真正对你有用的命令、链接和注意事项,避免重复搜索
  • - 如果页面里提到相关文档,尽量一起打开对照,效果通常更完整
同类内容
← 上一篇DNS 与 Hosts 配置