Docker Compose下db-replicator无法连接远程PostgreSQL数据库
问题:db-replicator服务执行pg_dump失败,报错socket不存在
我的compose.yaml配置如下:
services: pg-local: image: postgres:14.7 volumes: - pgdata:/var/lib/postgresql/data env_file: - .env.local_postgres_docker_env ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 30s timeout: 5s retries: 3 configuration-manager: build: context: .. ports: - "5000:8080" volumes: - ~/.aws:/root/.aws depends_on: db-replicator: condition: service_started env_file: - .env.config_manager_docker_env db-migrator: build: context: .. volumes: - .:/migrations depends_on: pg-local: condition: service_healthy env_file: - .env.config_manager_docker_env command: bash -c 'poetry run flask db upgrade && echo "Migration completed successfully"' db-replicator: build: context: ./postgres depends_on: db-migrator: condition: service_completed_successfully env_file: - .env.local_postgres_docker_env - .env.production_postgres_secrets command: > bash -c ' PGPASSWORD=${PROD_POSTGRES_PASSWORD} pg_dump -v --host=${PROD_HOST} --username=${PROD_USER} --dbname=${PROD_DB_NAME} --clean --create --no-password --file=/tmp/dump.sql && PGPASSWORD=${POSTGRES_PASSWORD} psql --host=pg-local --username=${POSTGRES_USER} < /tmp/globals.sql' && PGPASSWORD=${POSTGRES_PASSWORD} psql --host=pg-local --username=${POSTGRES_USER} < /tmp/dump.sql' volumes: pgdata:
pg-local和db-migrator服务运行正常,但db-replicator执行pg_dump时失败,报错:
pg_dump: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
已确认所有环境变量定义正确(通过docker compose config验证),尝试过以下操作但无效:
- 更换其他网络
- 设置
network_mode: host - 使用
docker run直接运行镜像(此方式可行)
问题分析与修复
核心问题
- 变量未正确展开:
db-replicator的command中,bash -c使用单引号包裹命令,导致其中的环境变量(如${PROD_HOST})无法被Docker Compose展开,pg_dump未收到正确的--host参数,默认尝试连接本地Unix socket,引发报错。 - 命令语法错误:原命令中第二个
psql语句后提前闭合了单引号,导致第三个psql语句被排除在bash -c的执行范围外,且末尾存在多余的单引号,进一步引发解析错误。
修复方案
修改db-replicator的command配置,将单引号替换为双引号,确保环境变量正常展开,并修正语法错误,将所有命令纳入bash -c的执行范围:
db-replicator: build: context: ./postgres depends_on: db-migrator: condition: service_completed_successfully env_file: - .env.local_postgres_docker_env - .env.production_postgres_secrets command: > bash -c " PGPASSWORD=${PROD_POSTGRES_PASSWORD} pg_dump -v --host=${PROD_HOST} --username=${PROD_USER} --dbname=${PROD_DB_NAME} --clean --create --no-password --file=/tmp/dump.sql && PGPASSWORD=${POSTGRES_PASSWORD} psql --host=pg-local --username=${POSTGRES_USER} < /tmp/globals.sql && PGPASSWORD=${POSTGRES_PASSWORD} psql --host=pg-local --username=${POSTGRES_USER} < /tmp/dump.sql"
说明
- 使用双引号包裹
bash -c的内容后,Docker Compose会提前展开环境变量,确保pg_dump能拿到正确的远程数据库地址,避免默认连接本地socket。 - 修正后的命令将所有操作纳入同一个
bash会话执行,保证命令逻辑的连贯性。
内容的提问来源于stack exchange,提问作者Yoni Melki
相关产品推荐
相关产品推荐

