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

如何在官方PostgreSQL Docker镜像中配置sshd服务自动启动

问题描述

我正尝试在多台Docker主机上搭建PostgreSQL-Pgpool集群,已在postgres:13-bullseye镜像中安装openssh-server,但无法在容器启动时自动启动sshd服务。尝试过以下配置:

entrypoint: ["bash -c '/usr/local/bin/docker-entrypoint.sh postgres && service ssh start'"]

也试过将PostgreSQL入口命令与service ssh start一同写入Dockerfile的entrypoint,或在Dockerfile配置entrypoint后在docker-compose中设置command,但这些操作都会影响PostgreSQL的正常启动。目前集群配置未完成,希望先解决sshd服务自动启动的问题。


我的配置文件

Dockerfile

FROM postgres:13-bullseye AS build

USER root

ENV http_proxy="http://gateway.zscloud.net:9480" ENV https_proxy="http://gateway.zscloud.net:9480" ENV no_proxy="127.0.0.1, localhost, 192.168., 10."

COPY postgres-*.sh /docker-entrypoint-initdb.d/

RUN mkdir /run/sshd && apt-get update && apt-get install -y openssh-server pgpool2 gosu sudo && apt-get clean && echo "postgres ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/postgres && mkdir /var/lib/postgresql/.ssh && chown postgres:postgres /var/lib/postgresql/.ssh && chmod 755 /docker-entrypoint-initdb.d/postgres-*.sh

docker-compose.yml

version: '3.1'
services:
  postgresql:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: pg_${HOSTNAME}
    hostname: pg_${HOSTNAME}
    environment:
      - http_proxy=http://gateway.zscloud.net:9480
      - https_proxy=http://gateway.zscloud.net:9480
      - no_proxy=127.0.0.1, localhost, 192.168.*, 10.*
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - PGDATA=/var/lib/postgresql/data
    ports:
      - '2345:5432'
    volumes: 
      - postgres_home:/var/lib/postgresql
      - postgres_data:/var/lib/postgresql/data
      - pgpool_etc:/etc/pgpool2
    networks:
      postgresql:
        ipv4_address: 10.0.3.1
volumes:
  postgres_home:
    driver: local
  postgres_data:
    driver: local
  pgpool_etc:
    driver: local
networks:
  postgresql:
    external: true

postgres-init.sh

#!/bin/sh
set -e

cat << EOF >> /var/lib/postgresql/data/pg_hba.conf
host replication replicator 10.0.3.1/32 trust
host replication replicator 10.0.3.2/32 trust
host replication replicator 10.0.3.3/32 trust
host replication replicator 10.0.3.4/32 trust
host all         all        all         scram-sha-256
EOF

cat << EOF >> /var/lib/postgresql/.bash_profile
export http_proxy="http://gateway.zscloud.net:9480"
export https_proxy="http://gateway.zscloud.net:9480"
export no_proxy="127.0.0.1, localhost, 192.168.*, 10.*"
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=postgres
export PGDATA=/var/lib/postgresql/data
export PGPASSFILE="~/.pgpass"
EOF

cd ~/.ssh ; ssh-keygen -t rsa -b 2048 -q -N "" -f ~/.ssh/id_rsa

cat << EOF >> /var/lib/postgresql/.pgpass
*:*:*:pgpool:pgpool
*:*:*:replicator:replicator
*:*:*:postgres:postgres
EOF

cd ~/data

cat << EOF >> /var/lib/postgresql/data/openssl.conf 
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C=DE
ST=BW
L=Stuttgart
O=Vector Informatik GmbH
OU=Postgres
CN=$HOSTNAME.vi.vector.int

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = $HOSTNAME.vi.vector.int
DNS.2 = $HOSTNAME
EOF

openssl req -new -x509 -nodes -out server.crt -newkey rsa:2048 -keyout server.key -config /var/lib/postgresql/data/openssl.conf 

cat << EOF >> /var/lib/postgresql/data/postgresql.conf
listen_addresses = '*'
password_encryption = scram-sha-256
ssl = on

archive_mode = on
archive_command = 'cp "%p" "/var/lib/postgresql/data/wal_archive/%f"'
max_wal_senders = 100
max_replication_slots = 10
wal_level = replica
hot_standby = on
wal_log_hints = on
primary_conninfo = 'user=replicator password=replicator host=10.0.3.3 port=5432 sslmode=prefer sslcompression=1'
primary_slot_name = '$HOSTNAME'
wal_keep_size = 100

synchronous_commit = on
synchronous_standby_names = 'ANY 1(*)'
  
EOF

mkdir /var/lib/postgresql/data/wal_archive

psql << END_OF_SQL
    SET password_encryption = 'scram-sha-256';
    ALTER USER postgres PASSWORD 'postgres';
    CREATE ROLE pgpool WITH LOGIN;
    CREATE ROLE replicator WITH REPLICATION LOGIN;
    ALTER USER pgpool PASSWORD 'pgpool';
    ALTER USER replicator PASSWORD 'replicator';
    GRANT pg_monitor TO pgpool;
END_OF_SQL

解决方案

核心问题是:/usr/local/bin/docker-entrypoint.sh postgres是前台阻塞命令,用&&连接时会卡住后续的sshd启动;同时容器的PID 1进程必须保持前台运行,否则容器会直接退出。以下是两种可靠的解决方法:

方法一:自定义启动脚本(轻量方案)

  1. 在项目目录创建start-services.sh脚本:
#!/bin/bash
set -e

# 后台启动sshd
/usr/sbin/sshd

# 执行PostgreSQL官方entrypoint并保持前台运行(容器PID 1)
exec /usr/local/bin/docker-entrypoint.sh postgres
  1. 给脚本添加执行权限:
chmod +x start-services.sh
  1. 修改Dockerfile,复制脚本并设置为entrypoint:
FROM postgres:13-bullseye AS build

USER root

ENV http_proxy="http://gateway.zscloud.net:9480" 
ENV https_proxy="http://gateway.zscloud.net:9480" 
ENV no_proxy="127.0.0.1, localhost, 192.168., 10."

COPY postgres-*.sh /docker-entrypoint-initdb.d/
COPY start-services.sh /usr/local/bin/

RUN mkdir /run/sshd && apt-get update && apt-get install -y openssh-server pgpool2 gosu sudo && apt-get clean && echo "postgres ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/postgres && mkdir /var/lib/postgresql/.ssh && chown postgres:postgres /var/lib/postgresql/.ssh && chmod 755 /docker-entrypoint-initdb.d/postgres-*.sh && chmod +x /usr/local/bin/start-services.sh

ENTRYPOINT ["start-services.sh"]
  1. 移除docker-compose中的entrypoint配置,让镜像使用自定义入口。

方法二:用Supervisord管理多进程(稳定方案)

如果需要监控进程状态、自动重启服务,推荐用Supervisord:

  1. 修改Dockerfile安装Supervisord:
FROM postgres:13-bullseye AS build

USER root

ENV http_proxy="http://gateway.zscloud.net:9480" 
ENV https_proxy="http://gateway.zscloud.net:9480" 
ENV no_proxy="127.0.0.1, localhost, 192.168., 10."

COPY postgres-*.sh /docker-entrypoint-initdb.d/
COPY supervisord.conf /etc/supervisor/conf.d/

RUN mkdir /run/sshd && apt-get update && apt-get install -y openssh-server pgpool2 gosu sudo supervisor && apt-get clean && echo "postgres ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/postgres && mkdir /var/lib/postgresql/.ssh && chown postgres:postgres /var/lib/postgresql/.ssh && chmod 755 /docker-entrypoint-initdb.d/postgres-*.sh

ENTRYPOINT ["/usr/bin/supervisord", "-n"]
  1. 创建supervisord.conf配置文件:
[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D
user=root
autostart=true
autorestart=true

[program:postgresql]
command=/usr/local/bin/docker-entrypoint.sh postgres
user=postgres
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

额外注意事项

  • 需确保sshd允许登录:检查/etc/ssh/sshd_config,必要时在Dockerfile中添加修改(比如设置PasswordAuthentication yes、PermitRootLogin no)。
  • 在docker-compose的ports中添加- '2222:22',暴露sshd端口(避免与主机22端口冲突)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:44:58