【问题标题】:initialize postgres container from docker-compose file从 docker-compose 文件初始化 postgres 容器
【发布时间】:2026-01-23 16:55:03
【问题描述】:

我正在尝试从 docker-compose 文件中启动一个 postgres 容器并对其进行初始化。

docker-compose.yml

version: "3"
  postgres:
  image: "postgres"
  command: bash -c "
   postgres &&
   createuser -l \"auser\"
   "

我的目标是: 1)启动postgres容器 2) 创建用户

当前实现失败并出现以下错误

"root" execution of the PostgreSQL server is not permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromise.  See the documentation for
more information on how to properly start the server.

【问题讨论】:

  • 请参阅hub.docker.com/_/postgres 上的“如何扩展此图像”部分。该镜像支持通过环境变量创建用户,甚至可以运行任意脚本。这可能比试图用 CMD 搞砸要容易得多。

标签: postgresql docker docker-compose dockerfile


【解决方案1】:

不允许“root”执行 PostgreSQL 服务器。

您不应使用root 用户运行数据库容器。最好运行postgres用户。

一种方法是在 docker-compose 中指定用户。

postgres:
  image: postgres
  container_name: postgres
  user: postgres
  ports:
    - "5432:5432"
  command: 'postgres'

但又一次

  command: bash -c "
   postgres &&
   createuser -l \"auser\"
   "

在创建用户命令期间,可能会出现数据库包含未准备好接受连接的情况。

所以你有两个最佳选择。

  • 使用环境变量

POSTGRES_USER

此可选环境变量与 POSTGRES_PASSWORD 设置用户及其密码。 这个变量 将创建具有超级用户权限的指定用户和数据库 使用相同的名称。 如果未指定,则默认用户为 postgres 将被使用。

postgres:
  image: postgres
  container_name: postgres
  environment:
    POSTGRES_USER: test
    POSTGRES_PASSWORD: password
    POSTGRES_DB: myapp
  user: postgres
  ports:
    - "5432:5432"

第二个选项

初始化脚本

如果您想在派生的图像中进行额外的初始化 从这个,在下面添加一个或多个*.sql, *.sql.gz, or *.sh scripts /docker-entrypoint-initdb.d(必要时创建目录)。 入口点调用 initdb 后创建默认 postgres 用户 和数据库,它将运行任何*.sql files,运行任何可执行文件*.sh 脚本,并获取其中找到的任何不可执行的*.sh 脚本 目录在启动服务之前做进一步的初始化。

例如,要添加其他用户和数据库,请将以下内容添加到/docker-entrypoint-initdb.d/init-user-db.sh

#!/bin/bash
set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

【讨论】: