Open2

PostgreSQLのDocker環境、ログ出力

HoraiHorai

最終のファイル構成

.
├── Docker
│   └── postgres
│       ├── Dockerfile
│       ├── log
│       │   └── postgresql.log
│       ├── log-test
│       │   └── postgresql.log
│       └── postgresql.conf
└── docker-compose.yml

Dockerfile 作成

Docker/postgres/Dockerfile 作成

FROM postgres:16 

ENV TZ=Asia/Tokyo

docker-compose.yml 作成

ポイント

  • ${POSTGRES_DB:-postgres} の形式でデフォルト値を指定しつつ手元で変更できるようにする
  • configファイルを配置して読み込ませてあげる
    • command: -c 'config_file=/etc/postgresql/postgresql.conf'
    • ./Docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf
  • ログファイルは後述のconfファイルの log_directory = '/log' により /log に出しつつホスト側にmountさせる
    • この時デフォルトだと log_directory = 'log' になっていてnamed volume配下(pgdata)に作成されてnon rootユーザーによる作成となってややこしい
    • host側にログ出力させたいディレクトリをDocker側の /log にbind mountさせてそこにログ出力させる(これでnon rootユーザー問題はおきない)
  • 起動時に実行したいファイルが複数あればDocker側のファイル名先頭に番号をつけることで順番を保証する
    • ./schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
version: "3.8"

services:
  db:
    build: ./Docker/postgres
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-root}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secret}
      POSTGRES_DB: ${POSTGRES_DB:-postgres}
    ports:
      - "${DB_PORT:-5432}:5432"
    command: -c 'config_file=/etc/postgresql/postgresql.conf'
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./Docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf
      - ./Docker/postgres/log:/log
      # 起動時に実行したいsql。アルファベット順で実行されるため実行順に数字をつける。
      - ./schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
      - ./seeder.sql:/docker-entrypoint-initdb.d/02-seeder.sql
  test-db:
    build: ./Docker/postgres
    restart: always
    environment:
      POSTGRES_USER: ${TEST_POSTGRES_USER:-root}
      POSTGRES_PASSWORD: ${TEST_POSTGRES_PASSWORD:-secret}
      POSTGRES_DB: ${TEST_POSTGRES_DB:-postgres}
    ports:
      - "${TEST_DB_PORT:-5433}:5432"
    command: -c 'config_file=/etc/postgresql/postgresql.conf'
    volumes:
      - test_pgdata:/var/lib/postgresql/data
      - ./Docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf
      - ./Docker/postgres/log-test:/log
      # 起動時に実行したいsql。アルファベット順で実行されるため実行順に数字をつける。
      - ./schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
volumes:
  pgdata:
  test_pgdata:

postgres.conf 作成

ポイント

  • log_truncate_on_rotation = on でローカルにログを溜め込みすぎないよう消えるようにする
  • log_filename = 'postgresql.log' で常に同名のファイルに作成させる
    • デフォルトでは日時が入ったファイル名になるが開発目的のため簡略化
  • 極力色々ログを出す
    • log_connections, log_disconnections, log_lock_waitsをon
  • listen_addresses = '*' は唯一コンテナ内のデフォルトのconfで有効されているものなので書いておく
# サンプルファイル: https://github.com/postgres/postgres/blob/master/src/backend/utils/misc/postgresql.conf.sample
# コンテナ内のsample: /usr/share/postgresql/postgresql.conf.sample

# ログファイルの管理を有効にする
logging_collector = on
log_timezone = 'Asia/Tokyo'
log_directory = '/log'
log_statement = 'all'
log_filename = 'postgresql.log'
log_truncate_on_rotation = on
log_line_prefix = '%m [%p-%l] ' # ex) 2024-01-31 06:47:28.363 JST [1-7]
log_connections = on
log_disconnections = on
log_lock_waits = on # deadlock_timeout(デフォルト1s)を超えたロック待ちをログに出力する

# 開発用のため、すべてのhostからの接続を許可する
listen_addresses = '*'

References

  1. https://hub.docker.com/_/postgres
  2. https://qiita.com/suin/items/067b7883c038b363b2d7
HoraiHorai

余談

細かい設定値の説明を日本語でできる限り公式の情報を探すのは下記のように検索する。
site:https://www.postgresql.jp/ log_truncate_on_rotation

最新のドキュメントは下記より見れるが、新しいバージョンだと細かい説明がなくなっていたりする模様。
https://www.postgresql.jp/document/current/index.html

とはいえconfigに関して言えばmirrorリポジトリにあるconfigのsampleファイルを直接見るのが早い。
https://github.com/postgres/postgres/blob/9d1a5354f58cf61d9be6733d5ad0b36936af5af3/src/backend/utils/misc/postgresql.conf.sample