web-dev-qa-db-ja.com

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:サーバーに接続できませんでした:そのようなファイルまたはディレクトリはありません

/docker-entrypoint-initdb.d/フォルダ内のコマンドはpostgresが起動する前に実行されているようです。私の質問は、どうやったら公式のpostgresコンテナを使ってプログラム的にユーザー/データベースをセットアップすることができるのですか?スクリプトでこれを行う方法はありますか?

156
pech0rin

編集 - 2015年7月23日以降

公式postgres docker image.sqlフォルダにある/docker-entrypoint-initdb.d/スクリプトを実行します。

だからあなたが必要とするすべては次の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日以降、ユーザーとデータベースを作成するだけでよい場合、単にPOSTGRES_USERPOSTGRES_PASSWORDおよびPOSTGRES_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イメージのドキュメンテーション 、と言われています

[...]そのディレクトリ[/docker-entrypoint-initdb.d]にあるすべての* .shスクリプトを呼び出して、サービスを開始する前にさらに初期化を行います。

ここで重要なことは"サービスを開始する前"です。これはあなたのスクリプトmake_db.shがpostgresサービスが開始される前に実行されることを意味します、それゆえエラーメッセージ"は接続できませんでしたデータベースpostgres "

その後に別の有用な情報があります。

初期化の一環としてSQLコマンドを実行する必要がある場合は、Postgresシングルユーザーモードの使用を強くお勧めします。

一見するとこれはちょっと不思議に思うかもしれないことに同意した。つまり、初期化スクリプトはそのアクションを実行する前にpostgresサービスをシングルモードで起動する必要があります。それで、あなたは以下のようにあなたのmake_db.kshスクリプトを変更することができました、そしてそれはあなたが望むものにあなたを近づけるようにするべきです:

NOTE、これは最近変更されました 次のコミットで 。これは最新の変更で動作します。

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
292
Thomasleveil

これで、initディレクトリ内に.sqlファイルを配置できます。

ドキュメントから

このイメージから派生したイメージで追加の初期化を行いたい場合は、/docker-entrypoint-initdb.dの下に* .sqlまたは* .shスクリプトを1つ以上追加します(必要に応じてディレクトリを作成します)。エントリポイントがinitdbを呼び出してデフォルトのpostgresユーザーとデータベースを作成した後、* .sqlファイルを実行し、そのディレクトリにある* .shスクリプトをすべてソースして、サービスを開始する前にさらに初期化を行います。

だからあなたの.sqlファイルをコピーすることはうまくいくでしょう。

13
m0meni

私はサービスを開始した後に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>

7
Rondo

ユーザーを作成する前にデータベースを実行しておく必要があります。これには複数のプロセスが必要です。シェルスクリプトのサブシェル(&)でpostgresを起動するか、またはsupervisordのようなツールを使用してpostgresを実行してから初期化スクリプトを実行することができます。

Supervisordとdockerのガイド https://docs.docker.com/articles/using_supervisord/

3
seanmcl

あなたはこのコマンドを使用することができます:

docker exec -it yournamecontainer psql -U postgres -c "CREATE DATABASE mydatabase ENCODING 'LATIN1' TEMPLATE template0 LC_COLLATE 'C' LC_CTYPE 'C';"

docker exec -it yournamecontainer psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE postgres TO postgres;"
1
Gabriel