私はカスタムユーザとデータベースを作成することによって開発postgresインスタンス用のコンテナを設定しようとしています。私は 公式postgres docker image を使っています。ドキュメントの中では、/docker-entrypoint-initdb.d/
フォルダの中にbashスクリプトを挿入して、カスタムパラメータでデータベースを設定するように指示されています。
su postgres -c "createuser -w -d -r -s docker"
su postgres -c "createdb -O docker docker"
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コンテナを使ってプログラム的にユーザー/データベースをセットアップすることができるのですか?スクリプトでこれを行う方法はありますか?
公式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_USER
、POSTGRES_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
から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
これで、initディレクトリ内に.sqlファイルを配置できます。
このイメージから派生したイメージで追加の初期化を行いたい場合は、/docker-entrypoint-initdb.dの下に* .sqlまたは* .shスクリプトを1つ以上追加します(必要に応じてディレクトリを作成します)。エントリポイントがinitdbを呼び出してデフォルトのpostgresユーザーとデータベースを作成した後、* .sqlファイルを実行し、そのディレクトリにある* .shスクリプトをすべてソースして、サービスを開始する前にさらに初期化を行います。
だからあなたの.sqlファイルをコピーすることはうまくいくでしょう。
私はサービスを開始した後に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>
。
ユーザーを作成する前にデータベースを実行しておく必要があります。これには複数のプロセスが必要です。シェルスクリプトのサブシェル(&)でpostgresを起動するか、またはsupervisordのようなツールを使用してpostgresを実行してから初期化スクリプトを実行することができます。
Supervisordとdockerのガイド https://docs.docker.com/articles/using_supervisord/
あなたはこのコマンドを使用することができます:
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;"