You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dockerfile中PostgreSQL服务无法启动问题求助

解决Docker容器中PostgreSQL无法随Apache一同启动的问题

你在开发环境尝试构建整合Apache、PostgreSQL、PHP的LAPP架构Docker镜像,容器仅用于开发场景,虽然Apache能正常接收请求,但PostgreSQL始终处于down状态。手动进入容器执行pg_ctlcluster 12 main start可以正常启动服务,但在Dockerfile中通过RUN指令启动无效。

问题原因

  1. RUN指令的执行逻辑:RUN是在镜像构建阶段执行的命令,执行完毕后该层的进程会被终止,不会延续到容器运行阶段。你添加的RUN pg_ctlcluster 12 main start只是在构建镜像时临时启动了一次PostgreSQL,容器启动时这个进程早已不存在。
  2. 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:

  1. 在Dockerfile中安装Supervisord:
RUN apt-get install -y supervisor
  1. 创建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
  1. 修改Dockerfile的CMD为:
CMD ["/usr/bin/supervisord"]

容器启动时,Supervisord会同时管理PostgreSQL和Apache的进程,确保二者都正常运行。

内容的提问来源于stack exchange,提问作者ahwelp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 05:10:54