Dockerfile中PostgreSQL服务无法启动问题求助
解决Docker容器中PostgreSQL无法随Apache一同启动的问题
你在开发环境尝试构建整合Apache、PostgreSQL、PHP的LAPP架构Docker镜像,容器仅用于开发场景,虽然Apache能正常接收请求,但PostgreSQL始终处于down状态。手动进入容器执行pg_ctlcluster 12 main start可以正常启动服务,但在Dockerfile中通过RUN指令启动无效。
问题原因
- RUN指令的执行逻辑:
RUN是在镜像构建阶段执行的命令,执行完毕后该层的进程会被终止,不会延续到容器运行阶段。你添加的RUN pg_ctlcluster 12 main start只是在构建镜像时临时启动了一次PostgreSQL,容器启动时这个进程早已不存在。 - Ubuntu的服务启动限制:构建日志中的
invoke-rc.d: policy-rc.d denied execution of start说明,Ubuntu在非完整systemd环境(Docker容器默认没有完整systemd)下,会禁止包安装时自动启动服务,因此PostgreSQL安装后不会自动运行。
解决方案(开发环境适用)
虽然Docker最佳实践是单进程容器,但针对开发场景,可通过启动脚本同时管理两个服务,具体步骤如下:
步骤1:创建启动脚本
在项目根目录下创建start.sh脚本,内容如下:
#!/bin/bash # 启动PostgreSQL服务 pg_ctlcluster 12 main start # 启动Apache并保持前台运行(Docker需要前台进程防止容器退出) /usr/sbin/apache2ctl -D FOREGROUND
给脚本添加执行权限:
chmod +x start.sh
步骤2:修改Dockerfile
更新Dockerfile,复制启动脚本并设置为容器启动命令:
FROM ubuntu:20.04 RUN apt-get update && apt-get upgrade -y RUN apt-get install -y software-properties-common RUN add-apt-repository -y ppa:ondrej/php RUN apt-get update RUN apt-get install -y sudo vim postgresql postgresql-contrib RUN apt-get install -y apache2 php8.0 php8.0-cli php8.0-common php8.0-opcache php8.0-pgsql php8.0-zip php8.0-gd libapache2-mod-php8.0 RUN a2enmod rewrite RUN a2enmod php8.0 RUN sed -i 's/\/var\/www\/html/\/var\/www\/html\/public/g' /etc/apache2/sites-available/000-default.conf COPY . /var/www/html # 复制启动脚本到容器内 COPY start.sh /usr/local/bin/start.sh WORKDIR /var/www/html/public EXPOSE 80 # 执行启动脚本 CMD ["bash", "/usr/local/bin/start.sh"]
步骤3:重新构建并运行容器
docker build -t lapp-dev . docker run -p 80:80 lapp-dev
可选方案:使用Supervisord管理多进程(更规范)
如果希望更规范地管理多个进程,可以使用Supervisord:
- 在Dockerfile中安装Supervisord:
RUN apt-get install -y supervisor
- 创建Supervisord配置文件
/etc/supervisor/conf.d/lapp.conf:
[supervisord] nodaemon=true [program:postgresql] command=/usr/bin/pg_ctlcluster 12 main start -w user=postgres autostart=true autorestart=true [program:apache2] command=/usr/sbin/apache2ctl -D FOREGROUND autostart=true autorestart=true
- 修改Dockerfile的CMD为:
CMD ["/usr/bin/supervisord"]
容器启动时,Supervisord会同时管理PostgreSQL和Apache的进程,确保二者都正常运行。
内容的提问来源于stack exchange,提问作者ahwelp
相关产品推荐
相关产品推荐

