postgres のコンテナ起動時の設定について

コンテナ起動時に初期DBを作成済みにする をモチベーションに environment の設定に関して理解を深めるために動作検証したのでメモ。

ドキュメントの設定値を参考に検証。

今回の検証内容のリポジトリ


TL;DR

  • ローカル開発なのでロールを気にしない
  • カスタムしたDBをコンテナ起動時に作成済みにしておきたい

のであれば、以下の docker-compose.yaml を作成し、

postgres:
  image: postgres:11.10
  container_name: postgres-playground
  ports:
    - 5432:5432
  environment:
    POSTGRES_USER: postgres # この設定は省略可能
    POSTGRES_PASSWORD: password
    POSTGRES_DB: custom

コンテナを起動すれば、カスタムしたDB(custom)を作成可能。

docker-compose up -d

docker-compose exec postgres bash -c 'psql -U postgres -c "\l"'
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 custom    | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(4 rows)

以下は検証。


まずはプレーンな状態

postgres:
  image: postgres:11.10
  container_name: postgres-playground
  ports:
    - 5432:5432
  environment:
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: password
    # POSTGRES_DB: test

起動してコンテナ内部に入って確認すると、

docker-compose up -d

docker-compose ps

docker-compose exec postgres bash

# 指定した role と同じ名前のDBにつなぎに行くため、 psql -U postgres -d postgres と同じ結果になる
psql -U postgres

\l

Owner が postgres で初期DBが作成されている。

                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres

POSTGRES_DB を変更

POSTGRES_DB This optional environment variable can be used to define a different name for the default database that is created when the image is first started. If it is not specified, then the value of POSTGRES_USER will be used.

とのことで、デフォルトのDB名を変更できるようです。先ほどは未指定のため、POSTGRES_USER と同じ名前になってたようです。

postgres:
  image: postgres:11.10
  container_name: postgres-playground
  ports:
    - 5432:5432
  environment:
    POSTGRES_USER: postgres
    POSTGRES_PASSWORD: password
    POSTGRES_DB: test # この値を変更

コンテナ内部から postgres のコマンドを実行し、DBを確認すると、

# 先ほどのコンテナを破棄
docker-compose down

docker-compose up -d

docker-compose ps

docker-compose exec postgres bash

# シェルから postgres 内部のコマンドを実行
psql -Upostgres -c "\l"

test の名前でDBが作成されている。が、postgres のDBも存在している。 Owner の権限でも drop できないため、こちらは基本的には消せないものと思われる。

                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 test      | postgres | UTF8     | en_US.utf8 | en_US.utf8 |

POSTGRES_USER を変更

This variable will create the specified user with superuser power and a database with the same name. If it is not specified, then the default user of postgres will be used.

スーパーユーザ権限を持つユーザと同じ名前のDBを作成する設定項目。

指定しない場合は、デフォルトユーザ postgres が使われる。

postgres:
  image: postgres:11.10
  container_name: postgres-playground
  ports:
    - 5432:5432
  environment:
    POSTGRES_USER: test
    POSTGRES_PASSWORD: password
    # POSTGRES_DB: test

コンテナに入るのもめんどくさいので、 postgres のコマンドをコンテナ内部に渡して結果を確認する。

docker-compose down

docker-compose up -d

docker-compose ps

docker-compose exec postgres bash -c 'psql -Upostgres -c "\l"'

デフォルトのユーザを変更しているため、ロールが無いためエラー。

psql: FATAL:  role "postgres" does not exist

変更したユーザのロールで確認すると、

docker-compose exec postgres bash -c 'psql -Utest -c "\l"'

Owner が test で指定したロールと同様のDBができている。

                             List of databases
   Name    | Owner | Encoding |  Collate   |   Ctype    | Access privileges
-----------+-------+----------+------------+------------+-------------------
 postgres  | test  | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 template1 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 test      | test  | UTF8     | en_US.utf8 | en_US.utf8 |

POSTGRES_USER,POSTGRES_DB を変更

最後は、スーパーユーザ権限を持つユーザとデフォルトのDB名のどちらも指定。

postgres:
  image: postgres:11.10
  container_name: postgres-playground
  ports:
    - 5432:5432
  environment:
    POSTGRES_USER: test
    POSTGRES_PASSWORD: password
    POSTGRES_DB: employee

test ロールで変更したDBを指定すると、

docker-compose down && docker-compose up -d && docker-compose ps

docker-compose exec postgres bash -c 'psql -U test -d employee -c "\l'

以下のようにDBができています。

                             List of databases
   Name    | Owner | Encoding |  Collate   |   Ctype    | Access privileges
-----------+-------+----------+------------+------------+-------------------
 employee  | test  | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres  | test  | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test
 template1 | test  | UTF8     | en_US.utf8 | en_US.utf8 | =c/test          +
           |       |          |            |            | test=CTc/test