目的
開発環境用のPostgreSQLをDockerコンテナとして作って配るのに、テーブルがあらかじめ作ってあって、データも入ってたらよいよねということで、手順をまとめてみました。
準備
こんな感じの構成です。
work
├Dockerfile
├init-user-db.sh
└test.sql
Dockerfile
この記事を書いている時点の最新版13.3をベースにしていますが、任意のpostgresイメージを指定してください。
FROM postgres:13.3
COPY test.sql /
COPY init-user-db.sh /docker-entrypoint-initdb.d
EXPOSE 5432
複数SQLファイルがある場合は、
COPY *.sql /
とかも出来ます。
init-user-db.sh
[https://hub.docker.com/_/postgres]
Initialization scriptsに書いてある通り、コンテナ開始時に/docker-entrypoint-initdb.d配下の*.sql, *.sql.gz, or *.shスクリプトを実行してくれる仕組みがあるので、これを利用します。
#!/bin/sh
set -e
psql -f test.sql -U postgres
sqlファイルを直接置いても実行できるのですが、順番制御を考えるとシェル経由で実行した方が良いと思います。
改行コードはLFにします。
test.sql
実行したいSQLを記述します。
CREATE TABLE test(id int, name varchar(50));
INSERT INTO test VALUES(1, 'hoge');
INSERT INTO test VALUES(2, 'moge');
\COPYコマンドを使ってCSVをロードすることも出来ます。その場合はDockerfileでCSVファイルもコピーしておきましょう。
改行コードはLFにします。
実行
Dockerイメージのビルド
>docker build -t mypostgres .
[+] Building 3.3s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 141B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/postgres:13.3 2.4s
=> CACHED [1/3] FROM docker.io/library/postgres:13.3@sha256:a8f25ca44e98a4846cad176be8017f8f9c34028e4eebbf905dd4 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 116B 0.0s
=> [2/3] COPY test.sql / 0.1s
=> [3/3] COPY init-user-db.sh /docker-entrypoint-initdb.d 0.1s
=> exporting to image 0.2s
=> => exporting layers 0.1s
=> => writing image sha256:52c65adfdab3bcd8193ef08c249a164c9dace17bae8e613e716ca984136ea2c4 0.0s
=> => naming to docker.io/library/mypostgres 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
>
コンテナの実行
>docker run --name=mypostgres -e POSTGRES_PASSWORD=mysecretpassword -d mypostgres
8c9553e5403049dbddf3dd0ed6a2f78a4f11834306f673e1bf61731690b1122f
>
コンテナに入ってSQL結果の確認
>docker exec -it mypostgres /bin/bash
root@8c9553e54030:/# psql -U postgres
psql (13.3 (Debian 13.3-1.pgdg100+1))
Type "help" for help.
postgres=# \dt
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | test | table | postgres
(1 row)
postgres=# select * from test;
id | name
----+------
1 | hoge
2 | moge
(2 rows)
postgres=# exit
root@8c9553e54030:/# exit
exit
>
ちゃんとテーブルもできていて、データも入ってましたね。
トラブルシューティング
- 最もハマったのは、シェルとSQLファイルの改行コードをLFにしていなかったせいで、コンテナが即時終了してしまう事象でした。気を付けましょう。
- docker logsでログを見るのを怠らないようにしましょう。(自戒を込めて)