集成Python/PostgreSQL/Redis的Docker镜像运行无响应问题排查
核心故障原因
你的容器启动后无响应直接退出,本质是三个问题:
- 你写的ENTRYPOINT命令执行完
postgresql和redis的重启脚本就直接结束,没有常驻前台的主进程。Docker容器会随PID 1主进程执行完毕直接终止,不会保持运行。 - 你在PostgreSQL初始化步骤后切换到了
postgres用户,ENTRYPOINT执行时没有root权限,根本跑不起来/etc/init.d/下的系统服务脚本,会直接触发权限报错。 - 构建阶段执行的
/etc/init.d/postgresql start只在构建用的临时容器里生效,构建完成临时容器销毁后,你创建的数据库用户、库的运行时状态不会保留到最终镜像,这段初始化逻辑实际运行时是完全失效的。
可直接使用的修正方案
单镜像跑多服务不要靠shell脚本串行执行启动命令,用supervisor做进程管理器常驻前台,统一托管、监控PostgreSQL、Redis服务,同时把数据库初始化逻辑改成服务启动后执行,避免构建阶段的临时状态丢失。
修正后的Dockerfile如下:
FROM python:3.8 # 安装系统依赖、supervisor、Redis、PostgreSQL RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4EB27DB2A3B88B8B && \ apt-get update && \ apt-get install -y --no-install-recommends redis-server supervisor && \ echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list && \ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \ apt-get update && \ apt-get install -y --no-install-recommends postgresql-12 postgresql-contrib-12 && \ rm -rf /var/lib/apt/lists/* # 调整PostgreSQL鉴权配置,允许本地test_user通过密码登录 RUN echo "host all test_user 127.0.0.1/32 md5" >> /etc/postgresql/12/main/pg_hba.conf && \ echo "local all test_user md5" >> /etc/postgresql/12/main/pg_hba.conf # 编写数据库初始化脚本,服务启动后自动执行创建用户和库 RUN mkdir -p /docker-entrypoint-initdb.d && \ printf '#!/bin/bash\nsu postgres -c "psql --command \"CREATE USER test_user WITH PASSWORD '\''123456'\'';\""\nsu postgres -c "psql --command \"CREATE DATABASE test_db WITH OWNER = test_user;\""\n' > /docker-entrypoint-initdb.d/init-pg.sh && \ chmod +x /docker-entrypoint-initdb.d/init-pg.sh # 配置supervisor托管所有服务 RUN mkdir -p /var/log/supervisor && \ printf '[supervisord]\nnodaemon=true\nlogfile=/var/log/supervisor/supervisord.log\n\n[program:postgresql]\ncommand=/usr/bin/pg_ctlcluster 12 main start -f\nuser=postgres\nautostart=true\nautorestart=true\n\n[program:redis]\ncommand=/usr/bin/redis-server --daemonize no\nuser=redis\nautostart=true\nautorestart=true\n\n[program:init-pg]\ncommand=/bin/bash -c "sleep 5 && /docker-entrypoint-initdb.d/init-pg.sh && supervisorctl stop init-pg"\nuser=root\nautostart=true\nautorestart=false\n' > /etc/supervisor/conf.d/multi-service.conf # 暴露服务默认端口 EXPOSE 5432 6379 # 启动supervisor作为常驻主进程 ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
验证方法
构建镜像启动容器后,执行以下命令确认服务正常:
- 执行
docker exec -it <你的容器ID> redis-cli ping,返回PONG即为Redis运行正常 - 执行
docker exec -it <你的容器ID> psql -U test_user -d test_db -h 127.0.0.1 -W,输入密码123456能成功进入PostgreSQL命令行即为数据库配置正常 - 执行
docker exec -it <你的容器ID> python --version可正常返回Python 3.8.x版本信息
内容的提问来源于stack exchange,提问作者Fei Qu
相关产品推荐
相关产品推荐

