🐂
ミニPCでマルチサーバー構築 [PostgreSQLコンテナ]
ミニPCでマルチサーバー構築シリーズのPostgreSQLコンテナ構築の記録メモです。
シリーズ
- N100搭載ミニPCでマルチサーバーの構想と構築準備
- ミニPCでマルチサーバー構築 [OS等インストール]
- ミニPCでマルチサーバー構築 [Sambaコンテナ]
- ミニPCでマルチサーバー構築 [PostgreSQLコンテナ] この記事
- ミニPCでマルチサーバー構築 [Nginxコンテナ]
- ミニPCでマルチサーバー構築 [Immichコンテナ]
- ミニPCでマルチサーバー構築 [VaultwardenコンテナとTailscale]
- ミニPCでマルチサーバー構築 [AdGuard Homeコンテナ]
- ミニPCでマルチサーバー構築 [GUI環境整備]
簡単な要件
- Port5432で通信する
- スキーマ単位ロジカルレプリケーションを使用する
- 暗号化はscram-sha-256を使用する
- デフォルトエンコードにUTF8を使用する
- ロケールにはCを使用する
コンテナ化
- 公式のDocker imageが存在するためそれを使用する
-
pg_hba.conf
は環境変数経由で変更可能
-
Docker Compose周り作成
ディレクトリ構成
$ tree .
.
├── compose.yaml
└── pgsql
├── etc
│ └── pgsql.conf
└── secrets
└── credential
compose.yaml
compose.yaml
services:
pgsql:
image: postgres:latest
restart: unless-stopped # Stop only once with err when initdb in order to use hash pass
shm_size: 1gb
ports:
- "5432:5432"
configs:
- source: common-user
target: /etc/passwd
- source: common-group
target: /etc/group
- source: pgsql-config
target: /etc/postgresql.conf
secrets:
- source: pgsql-secrets
target: /run/secrets
environment:
- TZ=Asia/Tokyo
- POSTGRES_PASSWORD_FILE=/run/secrets/credential
- POSTGRES_HOST_AUTH_METHOD=scram-sha-256
- "POSTGRES_INITDB_ARGS=-E UTF8 --no-locale -A scram-sha-256"
volumes:
- /srv/pgsql:/var/lib/postgresql/data
- /var/log/pgsql:/var/log/pgsql
networks:
- pgnet
command: postgres -c config_file=/etc/postgresql.conf
configs:
common-user:
file: /etc/passwd
common-group:
file: /etc/group
pgsql-config:
file: ./pgsql/etc/pgsql.conf
secrets:
pgsql-secrets:
file: ./pgsql/secrets
networks:
pgnet:
設定
実際の設定ファイル
pgsql.conf
有効項目を抜粋
listen_addresses = '*'
port = 5432
max_connections = 30
shared_buffers = 256MB
work_mem = 8MB
maintenance_work_mem = 256MB
temp_buffers = 32MB
effective_io_concurrency = 200
random_page_cost = 1.1
default_statistics_target = 500
timezone = 'Asia/Tokyo'
wal_level = logical
log_destination = 'jsonlog'
logging_collector = on
log_directory = '/var/log/pgsql'
log_filename = 'postgresql_%Y%m%d_%H%M%S.log
log_line_prefix = '%t %u@%d(%p) '
log_rotation_age = 0
log_autovacuum_min_duration = 5min
log_min_duration_statement = 60000
log_timezone = 'Asia/Tokyo'
各設定値
-
listen_addresses
: 外から接続受け付けるため'*'
-
max_connections
: 自分しか使用しないため多めで30
-
shared_buffers
: 大きくしすぎても無意味らしいのでまず256MB
-
work_mem
: 接続毎に確保されるため8MB
-
maintenance_work_mem
: 参考文献の値そのまま256MB
-
temp_buffers
: 一時テーブル多用する予定のため32MB
-
effective_io_concurrency
: SSDのため多めの値200
-
random_page_cost
: SSDのため1に近い値1.1
-
default_statistics_target
: そこそこの実行計画精度のため500
-
wal_level
: ロジカルレプリケーションを使用するためlogical
ユーザー管理
スーパーユーザー名
- 環境変数で設定可能
-
POSTGRES_USER
: デフォルトはpostgres
-
POSTGRES_PASSWORD
: 指定必須項目-
POSTGRES_PASSWORD_FILE
: ファイルで指定可能
-
-
パスワード設定
Docker Composeで扱う際にパスワードを平文で管理したくないため、暗号化されたハッシュ状態のパスワードを取り扱うようにする。
- ハッシュ状態のパスワードで取り扱う方法
- 予めSandbox環境のPostgreSQLでユーザを作成する
- 以下SQLでハッシュ状態のパスワードを出力しファイルに保存
select rolpassword from pg_catalog.pg_authid where rolname='username_to_create_a_hashpass';
-
compose.yaml
の環境変数POSTGRES_PASSWORD_FILE
にそのファイルを指定する - 以下SQLでその他のユーザも作成可能
create role myuser login createdb createrole encrypted password '$hashpass';
- ただし上記方法でコンテナ作成すると初期化スクリプトは動作しない
- 初期化スクリプト動作前にエラーが発生し初回起動はコンテナ作成に失敗する
- データベースクラスタは正しく作成されている
- 初期化スクリプト実行時にDB接続する際、渡したパスワードを認証に使用する模様
- ハッシュ化されているためログイン失敗 -> コンテナ作成失敗
- 何も変更せず再度コンテナを立ち上げると正常に動作する
Discussion