如何在 Docker Postgres 的脚本中创建用户/数据库

新手上路,请多包涵

我一直在尝试通过创建自定义用户和数据库来为开发 postgres 实例设置容器。我正在使用 官方的 postgres docker image 。在文档中,它指示您在 /docker-entrypoint-initdb.d/ 文件夹中插入一个 bash 脚本,以使用任何自定义参数设置数据库。

我的 bash 脚本:make_db.sh

 su postgres -c "createuser -w -d -r -s docker"
su postgres -c "createdb -O docker docker"

Dockerfile

 FROM library/postgres

RUN ["mkdir", "/docker-entrypoint-initdb.d"]
ADD make_db.sh /docker-entrypoint-initdb.d/

我从 docker logs -f db (db 是我的容器名称)得到的错误是:

createuser:无法连接到数据库 postgres:无法连接到服务器:没有这样的文件或目录

似乎在启动 postgres 之前正在执行 /docker-entrypoint-initdb.d/ 文件夹中的命令。我的问题是,如何使用官方的 postgres 容器以编程方式设置用户/数据库?有没有办法用脚本做到这一点?

原文由 pech0rin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 977
2 个回答

编辑 - 自 2015 年 7 月 23 日起

官方 postgres docker 镜像 将运行 .sql 脚本在 /docker-entrypoint-initdb.d/ 文件夹中。

因此,您只需要创建以下 sql 脚本:

初始化.sql

 CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;

并将其添加到您的 Dockerfile 中:

Dockerfile

 FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/


但自 2015 年 7 月 8 日起, 如果您只需要创建用户和数据库,则使用 POSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_DB 会更容易 --- 环境变量:

 docker run -e POSTGRES_USER=docker -e POSTGRES_PASSWORD=docker -e POSTGRES_DB=docker library/postgres

或使用 Dockerfile:

 FROM library/postgres
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker


适用于 2015 年 7 月 23 日之前的图像

postgres Docker 映像的文档中,据说

[…] 它将获取在该目录中找到的任何 *.sh 脚本 [ /docker-entrypoint-initdb.d ] 以在启动服务之前进行进一步的初始化

这里重要的是 “在启动服务之前” 。这意味着您的脚本 _makedb.sh 将在 postgres 服务启动之前执行,因此错误消息 “could not connect to database postgres”

之后还有另一个有用的信息:

如果您需要在初始化过程中执行 SQL 命令,强烈建议使用 Postgres 单用户模式。

同意这乍一看可能有点神秘。它说的是您的初始化脚本应该在执行其操作之前以单一模式启动 postgres 服务。所以你可以改变你的 _makedb.ksh 脚本如下,它应该让你更接近你想要的:

注意,这在最近 的提交 中发生了变化。这将适用于最新的更改:

 export PGUSER=postgres
psql <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

以前需要使用 --single 模式:

 gosu postgres postgres --single <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

原文由 Thomasleveil 发布,翻译遵循 CC BY-SA 4.0 许可协议

通过使用 docker-compose

假设您具有以下目录布局:

 $MYAPP_ROOT/docker-compose.yml
           /Docker/init.sql
           /Docker/db.Dockerfile

文件: docker-compose.yml

 version: "3.3"
services:
  db:
    build:
      context: ./Docker
      dockerfile: db.Dockerfile
    volumes:
      - ./var/pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

文件: Docker/init.sql

 CREATE USER myUser;

CREATE DATABASE myApp_dev;
GRANT ALL PRIVILEGES ON DATABASE myApp_dev TO myUser;

CREATE DATABASE myApp_test;
GRANT ALL PRIVILEGES ON DATABASE myApp_test TO myUser;

文件: Docker/db.Dockerfile

 FROM postgres:11.5-alpine
COPY init.sql /docker-entrypoint-initdb.d/

编写和启动服务:

 docker-compose -f docker-compose.yml up --no-start
docker-compose -f docker-compose.yml start

原文由 Vlad 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题