GitLab CI环境中PostgreSQL 5432端口无法接收连接排查求助
环境配置
GitLab CI配置
image: docker:latest services: - docker:dind stages: - build before_script: - apk add --update python3 python3-pip python3-dev git openssh-client && pip3 install docker-compose main_script: stage: build network_mode: bridge script: - docker-compose up -d --build - docker-compose exec -T users python manage.py test - docker-compose exec -T users flake8 project --ignore=W191,E401,E999 after_script: - docker-compose down
docker-compose.yml配置
version: '3.7' services: users: build: context: ./services/users dockerfile: Dockerfile volumes: - './services/users:/usr/src/app' expose: - 5000 environment: - FLASK_DEBUG=True - APP_SETTINGS=project.config.DevelopmentConfig - DATABASE_URL=postgresql://postgres:postgres@users-db:5432/users_dev - DATABASE_TEST_URL=postgresql://postgres:postgres@users-db:5432/users_test depends_on: - users-db users-db: build: context: ./services/users/project/db dockerfile: Dockerfile expose: - 5432 environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres nginx: build: context: ./services/nginx dockerfile: Dockerfile restart: always ports: - 80:80 depends_on: - users
PostgreSQL Dockerfile
FROM postgres:14.7-alpine ADD create.sql /docker-entrypoint-initdb.d
entrypoint.sh文件
#!/bin/sh echo "Waiting for postgres ..." while ! nc -z users-db 5432; do sleep 0.1 done echo "PostgreSQL started" python3 manage.py run -h 0.0.0.0
错误信息
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) 无法连接到服务器"users-db"(172.19.0.2)的5432端口:连接被拒绝
服务器是否在该主机上运行并接受TCP/IP连接?
已执行的排查操作
- 进入PostgreSQL容器,确认配置文件中
listen_addresses='*' - 在流水线主脚本中添加命令:
docker-compose exec -T users-db /bin/sh -c "echo 'host all all 0.0.0.0/0 md5' >> /var/lib/postgresql/data/postgresql.conf",无改善 - 尝试将数据库URI中的主机IP改为PostgreSQL服务器的IP地址172.19.0.2,问题依旧
- 执行
ps ux | grep postgres,输出仅显示grep进程:ps ux | grep postgres 90 root 0:00 grep postgres - netstat输出:
Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 runner--project-0:39744 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:38424 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:38456 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:40648 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:60706 ec2-52-1-184-176.co:443 TIME_WAIT tcp 0 0 runner--project-0:38442 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:38474 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:57332 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:38460 docker:2375 TIME_WAIT tcp 0 0 runner--project-0:57348 docker:2375 TIME_WAIT Active UNIX domain sockets (w/o servers) Proto RefCnt Flags Type State I-Node Path
疑问
已尝试上述步骤,但仍无法解决连接被拒绝的问题,该如何进一步排查?
检查PostgreSQL容器启动状态与日志
执行docker-compose logs users-db查看数据库容器的启动日志,重点关注初始化阶段是否有语法错误、权限报错或其他异常。从ps ux输出看,postgres进程未运行,大概率是容器启动失败或异常退出,日志会给出直接原因。验证初始化SQL文件的合法性
你将create.sql放入/docker-entrypoint-initdb.d目录,若SQL文件存在语法错误、编码问题或权限不足,会导致PostgreSQL初始化失败,进程无法启动。可以临时注释掉Dockerfile中的ADD create.sql语句,重新构建运行,验证postgres是否能正常启动。修正访问控制配置的位置
之前的错误操作是将访问规则写入了postgresql.conf,但PostgreSQL的IP访问控制配置在pg_hba.conf文件中,正确命令应为:docker-compose exec -T users-db /bin/sh -c "echo 'host all all 0.0.0.0/0 md5' >> /var/lib/postgresql/data/pg_hba.conf"更推荐在Dockerfile中直接复制预先配置好的
pg_hba.conf,避免容器启动后再修改的延迟问题。替换CI中的等待逻辑为更可靠的检测方式
当前entrypoint.sh的等待逻辑仅检测端口开放,但CI中是启动容器后立刻执行测试,此时users-db可能还未完成初始化。建议在CI脚本中添加PostgreSQL就绪检测:script: - docker-compose up -d --build # 等待PostgreSQL真正就绪 - until docker-compose exec -T users-db pg_isready -U postgres; do sleep 1; done - docker-compose exec -T users python manage.py test - docker-compose exec -T users flake8 project --ignore=W191,E401,E999pg_isready会检测PostgreSQL服务是否完全可用,比nc检测端口更可靠。确认容器间网络连通性
在users容器中执行ping users-db验证DNS解析是否正常,再执行nc -zv users-db 5432检查端口是否可连通。若DNS解析失败,需排查Docker网络配置;若端口不通,回到容器启动日志找根源。查看users-db容器状态
执行docker-compose ps users-db查看容器状态是Up还是Exited,若为Exited状态,结合docker-compose logs users-db分析退出原因。
内容的提问来源于stack exchange,提问作者Mark

