Docker中PostgreSQL容器连接时突然终止问题排查求助
在Docker容器中运行PostgreSQL镜像时出现异常:PostgreSQL服务器初始启动正常(日志显示“database system is ready to accept connections”),但当Python应用容器启动并尝试连接数据库时,PostgreSQL服务器突然收到快速关闭请求。此外,Python应用容器的日志行在PostgreSQL就绪日志后短暂出现,随后被PostgreSQL的后续日志覆盖。
已尝试在Docker Compose文件中通过depends_on参数关联两个服务,分别使用condition: service_started和搭配test: ["CMD-SHELL", "pg_isready"]健康检查的condition: service_healthy配置,但问题依旧。需要排查PostgreSQL突然关闭的原因,并解决以实现应用与数据库的正常连接。
PostgreSQL容器日志示例
postgresql_db: PostgreSQL Database directory appears to contain a database; Skipping initialization postgresql_db: postgresql_db: 2024-04-25 21:55:37.945 UTC [1] LOG: starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit postgresql_db: 2024-04-25 21:55:37.945 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 postgresql_db: 2024-04-25 21:55:37.945 UTC [1] LOG: listening on IPv6 address "::", port 5432 postgresql_db: 2024-04-25 21:55:37.951 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" postgresql_db: 2024-04-25 21:55:37.958 UTC [29] LOG: database system was shut down at 2024-04-25 21:54:52 UTC postgresql_db: 2024-04-25 21:55:37.965 UTC [1] LOG: database system is ready to accept connections postgresql_db: 2024-04-25 21:56:44.241 UTC [1] LOG: received fast shutdown request postgresql_db: 2024-04-25 21:56:44.244 UTC [1] LOG: aborting any active transactions postgresql_db: 2024-04-25 21:56:44.245 UTC [1] LOG: background worker "logical replication launcher" (PID 32) exited with exit code 1 postgresql_db: 2024-04-25 21:56:44.246 UTC [27] LOG: shutting down postgresql_db: 2024-04-25 21:56:44.248 UTC [27] LOG: checkpoint starting: shutdown immediate postgresql_db: 2024-04-25 21:56:44.267 UTC [27] LOG: checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.006 s, sync=0.002 s, total=0.022 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB; lsn=0/19716B8, redo lsn=0/19716B8 postgresql_db: 2024-04-25 21:56:44.271 UTC [1] LOG: database system is shut down
Docker Compose配置
postgresql-db: container_name: postgresql_db image: postgres restart: always env_file: - .env volumes: - postgres_data:/var/lib/postgresql/data networks: - postgres_network stop_grace_period: 2m telegram-bot: container_name: telegram_bot restart: always env_file: - .env environment: - SQL_DB_ENGINE=postgresql build: dockerfile: Dockerfile depends_on: postgresql-db: condition: service_started networks: - postgres_network stop_grace_period: 2m volumes: postgres_data: networks: postgres_network:
1. 排查Python应用容器的启动异常
Python应用启动失败可能触发连锁反应(比如容器反复重启导致Docker Compose的依赖逻辑异常),但日志被PostgreSQL覆盖无法直接查看:
- 单独启动PostgreSQL容器,确认其能稳定运行:
docker-compose up postgresql-db,观察日志是否会自行关闭。 - 单独启动Python应用容器,查看完整启动日志:
docker-compose up telegram-bot,检查是否存在数据库连接错误(如认证失败、数据库不存在、网络不通)。
2. 检查PostgreSQL数据卷是否损坏
日志显示数据库目录已存在但跳过初始化,若数据卷内文件损坏,PostgreSQL可能在接受连接后触发自我保护式关闭:
- 备份现有数据卷:
docker run --rm -v postgres_data:/data -v $(pwd)/backup:/backup busybox cp -r /data /backup - 删除损坏的数据卷:
docker-compose down -v - 重新启动容器,让PostgreSQL重新初始化数据库:
docker-compose up,再测试应用连接。
3. 验证环境变量与数据库连接参数
检查.env文件中PostgreSQL相关变量(POSTGRES_USER、POSTGRES_PASSWORD、POSTGRES_DB)是否与Python应用的连接参数匹配:
- 手动进入PostgreSQL容器验证连接:
docker exec -it postgresql_db psql -U ${POSTGRES_USER} -d ${POSTGRES_DB},确认能正常登录。 - 确保Python应用使用
postgresql-db作为数据库主机名(Docker Compose网络中服务名即为主机名)。
4. 排查宿主机资源问题
若宿主机内存/CPU不足,系统可能触发OOM killer终止PostgreSQL进程,日志中的“快速关闭请求”可能是系统发送的终止信号:
- 检查宿主机系统日志(如
/var/log/syslog或dmesg),查看是否有OOM相关记录。 - 给PostgreSQL容器分配足够资源,在docker-compose.yml的
postgresql-db服务中添加:deploy: resources: limits: memory: 1G reservations: memory: 512M
5. 完善健康检查配置
之前的健康检查可能配置不完整,确保数据库真正就绪后再启动应用:
修改postgresql-db服务的配置,添加完整的健康检查:
postgresql-db: container_name: postgresql_db image: postgres restart: always env_file: - .env volumes: - postgres_data:/var/lib/postgresql/data networks: - postgres_network stop_grace_period: 2m healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 5
同时修改telegram-bot的depends_on配置:
depends_on: postgresql-db: condition: service_healthy
内容的提问来源于stack exchange,提问作者Milana

