0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PostgreSQLのDockerコンテナ起動時に指定したSQLファイルを実行する

Posted at

目的

開発環境用の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スクリプトを実行してくれる仕組みがあるので、これを利用します。

init-user-db.sh
#!/bin/sh 
set -e

psql -f test.sql -U postgres

sqlファイルを直接置いても実行できるのですが、順番制御を考えるとシェル経由で実行した方が良いと思います。
改行コードはLFにします。

test.sql

実行したいSQLを記述します。

test.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でログを見るのを怠らないようにしましょう。(自戒を込めて)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?