Dockerと公式のPostgreSQLの公式イメージを用いてコンテナを作成した時にハマったのでメモ。
環境: Ubuntu 18.04.1 LTS
やりたいこと
- コンテナ作成時にSQLを実行してテーブルを作成したい
- USERとDBも指定したい
- データの永続化をしたい
docker-compose.yml
結果的に以下のようになった。
VolumeはDocker上に作成した領域をマウントしている。
version: "3"
services:
appdb:
image: postgres:10
container_name: "appdb"
environment:
- POSTGRES_USER
- POSTGRES_PASSWORD
- POSTGRES_DB
ports:
- "15432:5432"
volumes:
- database:/var/lib/postgresql/data
- ./initdb:/docker-entrypoint-initdb.d
volumes:
database:
driver: local
environmentについて
ユーザ情報については環境変数で定義すると良い。
docker-compose
で使う変数は.env
ファイルに記入する。
$ cat .env
POSTGRES_USER=test01
POSTGRES_PASSWORD=test01
POSTGRES_DB=test01
初期化SQL
公式イメージの初期化機能を使う。
/docker-entrypoint-initdb.d
に置かれた.sql/.shファイルが1度だけ実行される。
したがって./initdb
などのディレクトリを作ってそこにsqlファイルを置いてvolumeにマウントする。
ファイル名の先頭に連番をつけると順番に実行されるらしい。
create table users
(
user_id text UNIQUE,
password text,
insert_date timestamp with time zone,
update_date timestamp with time zone
);
実行結果
docker-composeで起動する。
$ sudo docker-compose up -d
Creating volume "publicapp_database" with local driver
Creating appdb ...
Creating appdb ... done
execで入って中身を見る。
$ sudo docker exec -it appdb /bin/bash
# root@f1d78bb0b87e:/# psql -U test01
psql (10.5 (Debian 10.5-2.pgdg90+1))
Type "help" for help.
test01=# \dt
List of relations
Schema | Name | Type | Owner
--------+----------+-------+--------
public | users | table | test01
(1 rows)
とりあえず期待通り動いているようだ。
外部からの接続
ホストOS側から接続する時は、docker-compose.yml
で書いたポートの指定が必要。
psql -h localhost -p 15432 -U test01
別コンテナから接続する時は、コンテナ名のみ指定する。
psql -h appdb -U test01
※links
が書いてあるdocker-compose.yml
を見かけるがversion
が2以上の場合、自動的にリンクが貼られるので不要とのこと(docker-compose depends_onとlinksの違い)。