PostgreSQLのコンテナを作る Docker実践-1
DBのコンテナを作ってみる。 PostgreSQLの14.xで作成することにする。カレントディレクトリを mpses とする。 Dockerfileはpostgresフォルダを作りその中に入れる
mpses/postgres/
Dockerfileを作る
FROM postgres:14-alpine ENV LANG ja_JP.utf8
debian版とalpine版があるが、alpineのほうががサイズが小さい
次に docker-compose.yaml で起動時の初期設定を書く。Dockerfile 内で docker run しないのは、起動時の設定を覚えるのが大変だから。
docker-compose.yaml にその設定を書いてしまえばよい。
version: '3' services: db: build: ./postgres ports: - 5432:5432 environment: POSTGRES_USER: admin POSTGRES_PASSWORD: admin
dbという名称は任意に付けたもの。ユーザ名を指定しないとデフォルトのpostgresになる。
コンテナを起動する
$ docker-compose up -d ←デタッチモード
面倒なパラメータはdocker-composeに入っているので何も指定しなくてよい。起動されているか確認してみる。
$ docker container exec -it mpses_postgres_1 /bin/bash bash-5.1# psql -U admin psql (14.2) Type "help" for help. admin=# select version(); version -------------------------------------------------------------------------------------------------------------- PostgreSQL 14.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit (1 row) admin=# \q bash-5.1# exit $ docker-compose down
version14.2が稼働していることが確認できた。
次はコンテナ起動時にDBにデータを入れてみる。なお、adminというユーザを登録した場合はadminというデータベースも作られているので、データベースをcreateする必要はない。
postgres の docker image は、docker-entrypoint-initdb.d 内に.sh を置いておくと起動時にその内容を実行してくれる。
postgresフォルダ内に docker-entrypoint-initdb.d フォルダを作り、以下のinit.shファイルを置いてみる。
init.sh
set -e psql -U admin admin <<EOF CREATE TABLE m_user( id TEXT PRIMARY KEY, name TEXT, password TEXT ); EOF
docker-composeファイルに、volume設定を定義してこのファイルを参照させる。
version: '3' services: db: build: ./postgres ports: - 5432:5432 environment: POSTGRES_USER: admin POSTGRES_PASSWORD: admin volumes: - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
コンテナを立ち上げて、DBを確認してみる。
$ docker-compose up -d $ docker container exec -it mpses_postgres_1 /bin/bash bash-5.1# psql -U admin psql (14.2) Type "help" for help. admin=# \d List of relations Schema | Name | Type | Owner --------+--------+-------+------- public | m_user | table | admin (1 row) admin=# \d m_user Table "public.m_user" Column | Type | Collation | Nullable | Default ----------+------+-----------+----------+--------- id | text | | not null | name | text | | | password | text | | | Indexes: "m_user_pkey" PRIMARY KEY, btree (id) admin=#
指定した通りに生成できているようだ。 ここで一旦コンテナを削除する。
$ docker-compose down
次に、既存のDBをリストアしてみる。
バックアップファイルを docker-entrypoint-initdb.d フォルダに data.out というファイル名で用意する。init.shは不要なので削除しておく。
また、データを永続的に保存するため、ホスト側のディレクトリをマウントしたい。ところが、ホスト側(Windows)をマウントしても、書き込み権限エラーやSYNCエラーが多発する。おそらくLinuxが仮想ファイルシステムをWindows上で動かしているとおもわれるがこれが良くないみたいだ。そこでdockerでvolumeを作り、それを利用することにする。
$ docker volume create mps-db-data
docker-compose.yamlは以下の通り
version: '3' services: db: build: ./postgres ports: - 5432:5432 environment: POSTGRES_USER: admin POSTGRES_PASSWORD: admin volumes: - mps-db-data:/var/lib/postgresql - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d volumes: mps-db-data: external:true
コンテナに入り、バックアップデータをリストアする。
$ docker-compose up -d $ docker-compose exec db bash # cd /docker-entrypoint-initdb.d # psql -U admin < data.out ...(snip)... # psql -U admin admin=# \d テーブルやレコードの存在することを確認する admin=# \q # exit
これでデータベースの内容はvolume内に保存されたはずである。確認のため、コンテナを削除してから再構築し、データが保存されていることを確認してみる。
$ docker-compose down $ docker container ls ←消えている $ docker network ls ←消えている $ docker volume ls ←volumeは残っている DRIVER VOLUME NAME local mps-db-data $ docker-compose up -d $ docker-compose exec db bash # psql -U admin admin=# \d テーブルやレコードの存在することを確認する admin=# \q # exit $ docker-compose down
DBデータの永続化ができた。くれぐれもdocker volume prune で消しませんように......