同一主机部署两个Docker实例时PostgreSQL认证失败问题
解决同一主机Docker Compose部署双实例PostgreSQL认证&环境文件失效问题
核心问题分析
你遇到的问题本质是预发布实例未正确加载.env.staging配置,同时存在端口冲突、数据卷共享的连锁问题:
- Docker Compose默认仅加载当前目录下的
.env文件,不会主动识别.env.staging - 预发布和生产曾共享PostgreSQL数据卷,导致预发布启动时复用了生产的DB目录(跳过初始化),但应用却尝试用预发布配置的用户连接,自然出现角色不存在的错误
- 端口映射未正确区分,导致预发布实例复用了生产的5432端口
分步解决方案
1. 明确环境文件加载方式
Docker Compose不会自动加载.env.staging,必须通过--env-file参数手动指定。启动预发布实例时使用:
docker-compose --env-file .env.staging up -d
生产实例用默认命令即可:
docker-compose up -d
2. 配置完全隔离的实例资源
修改docker-compose.yml,通过环境变量动态指定端口、数据卷名称,确保两个实例彻底隔离:
version: '3.8' services: app: image: your-hanami-ruby-image environment: - DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME} depends_on: - db ports: - "${APP_PORT}:3000" # 应用端口:生产3000,预发布3001 db: image: postgres:14-alpine environment: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_DB=${DB_NAME} volumes: - ${DB_VOLUME_NAME}:/var/lib/postgresql/data ports: - "${DB_HOST_PORT}:5432" # 主机映射端口:生产5432,预发布5433
3. 编写对应环境配置文件
.env(生产环境)
APP_PORT=3000 DB_HOST_PORT=5432 DB_USER=some_user DB_PASSWORD=prod_pass DB_NAME=prod_app_db DB_VOLUME_NAME=prod_postgres_data
.env.staging(预发布环境)
APP_PORT=3001 DB_HOST_PORT=5433 DB_USER=other_user DB_PASSWORD=staging_pass DB_NAME=staging_app_db DB_VOLUME_NAME=staging_postgres_data
4. 清理旧数据卷(关键操作)
如果之前预发布实例复用了生产的数据卷,先删除预发布的旧数据卷(操作前请确认已备份必要数据):
# 查看所有数据卷 docker volume ls # 删除预发布的旧数据卷(如果存在) docker volume rm staging_postgres_data
重新启动预发布实例后,PostgreSQL会自动初始化新的数据库和对应角色。
验证配置有效性
启动前可以用以下命令查看Docker Compose实际加载的配置,确认环境变量是否正确生效:
docker-compose --env-file .env.staging config
检查输出中services.db.environment和services.db.ports部分是否与.env.staging配置一致。
内容的提问来源于stack exchange,提问作者Sebastjan Hribar
相关产品推荐
相关产品推荐

