首页 文章

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

提问于
浏览
145

我一直在尝试通过创建自定义用户和数据库来为开发postgres实例设置容器 . 我正在使用official 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容器以编程方式设置用户/数据库?有没有办法用脚本执行此操作?

4 回答

  • 3

    编辑 - 自2015年7月23日起

    official postgres docker image将运行 /docker-entrypoint-initdb.d/ 文件夹中的 .sql 脚本 .

    所以你需要的是创建以下sql脚本:

    init.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日 if all you need is to create a user and database 以来,更容易使用 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日之前的图片

    the documentation of the postgres Docker image,据说

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

    这里最重要的是"before starting the service" . 这意味着您的脚本make_db.sh将在postgres服务启动之前执行,因此错误消息"could not connect to database postgres" .

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

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

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

    NOTE ,最近发生了变化in the following commit . 这将适用于最新的变化:

    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
    
  • 273

    您现在可以将.sql文件放在init目录中:

    From the docs

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

    因此,复制.sql文件将起作用 .

  • 13

    我在启动服务之后将自定义命令添加到CMD中引发的环境中...我没有使用postgres,而是使用Oracle:

    #set up var with noop command
    RUN export POST_START_CMDS=":"
    RUN mkdir /scripts
    ADD script.sql /scripts
    CMD service oracle-xe start; $POST_START_CMDS; tail -f /var/log/dmesg
    

    并开始

    docker run -d ... -e POST_START_CMDS="su - oracle -c 'sqlplus @/scripts/script' " <image>
    

    .

  • 6

    在创建用户之前,您需要运行数据库 . 为此,您需要多个流程 . 您可以在shell脚本的子shell(&)中启动postgres,也可以使用supervisord之类的工具来运行postgres,然后运行任何初始化脚本 .

    supervisord和docker指南https://docs.docker.com/articles/using_supervisord/

相关问题