🐕

WSL2上にUbuntuでPostgreSQL15サーバー構築

2022/09/06に公開

WSL2上にUbuntuでPostgreSQL15サーバー構築

理解を間違っている可能性がありますが、一応構築できたため備忘しておきます。
追記1: 私の記事の中では閲覧されている方のようなので、ver15に更新した際に手順更新したものに差し替えておきます。本当はpostgresイメージを使用する形にしたかったのですが、wsl起動時に環境変数を指定できないためうまくいきませんでした。
追記2: そろそろ15は最新版じゃなくなるので、誤解を避けるために15表記に変更しました。

目標

WindowsからWSL2上に構築したPostgreSQLサーバーに接続しDBとして運用する。主となるPostgreSQLサーバーが他にあり、それをレプリケーションする想定のため、PC買い替えやバージョンアップ時の再構築を簡単にするためDockerイメージから構築する。

作業の流れ

  1. Docker上で環境構築試行
  2. Dockerfile作成、ビルド
  3. WSLにインポート

作成したDockerfile

FROM ubuntu:latest

ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Tokyo
RUN apt update \
    && apt -y install wget gnupg2 sudo tzdata \
    && adduser user1 \
    && --mount=type=secret,id=secret_key echo -n 'user1:' | cat - /run/secrets/secret_key | chpasswd \
    && gpasswd -a user1 sudo \
    && echo 'Asia/Tokyo' > /etc/timezone \
    && sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
    && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
    && apt update \
    && apt -y install postgresql-15 \
    && --mount=type=secret,id=secret_key echo -n 'postgres:' | cat - /run/secrets/secret_key | chpasswd \
    && echo "postgres ALL=(ALL:ALL) NOPASSWD: ALL" | tee "/etc/sudoers.d/dont-prompt-postgres-for-sudo-password" \
    && gpasswd -a postgres sudo

USER postgres
RUN /usr/lib/postgresql/15/bin/initdb -E UTF8 --no-locale -A scram-sha-256 -W \
    && sed -i -e 's:127.0.0.1/32:all         :' /var/local/postgresql/db/pg_hba.conf \
    && sed -i -e "/^#listen_addresses/ a listen_addresses = '*'" /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^max_connections/ s/100/10/' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^shared_buffers/ s/128MB/512MB/' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#work_mem/ a work_mem = 512MB' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#maintenance_work_mem/ a maintenance_work_mem = 512MB' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#effective_io_concurrency/ a effective_io_concurrency = 200' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#wal_buffers/ a wal_buffers = 16MB' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#checkpoint_timeout/ a checkpoint_timeout = 10min' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#checkpoint_completion_target/ a checkpoint_completion_target = 0.9' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#random_page_cost/ a random_page_cost = 1.1' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#effective_cache_size/ a effective_cache_size = 6GB' /etc/postgresql/15/main/postgresql.conf \
    && sed -i -e '/^#default_statistics_target/ a default_statistics_target = 500' /etc/postgresql/15/main/postgresql.conf \
    && sudo service postgresql start \
    && psql -c "create role user1 noinherit login;" \
    && psql -c "create role replica noinherit login replication;" \
    && psql -c 'create database ticker owner postgres;' \
    && psql ticker -c 'create schema master authorization replica;' \
    && psql ticker -c 'create schema dev authorization user1;' \
    && psql ticker -c 'grant all on schema master to user1;' \
    && sudo rm /etc/sudoers.d/dont-prompt-postgres-for-sudo-password

Dockerfile操作一部説明

ENV TZ=Asia/Tokyo
    && echo 'Asia/Tokyo' > /etc/timezone \

PostgreSQLインストール時にタイムゾーンをAsia/Tokyoとするために予めタイムゾーン設定

    && apt -y install wget gnupg2 sudo tzdata \

最新版PostgreSQLを取得するためのレポジトリ登録や後続処理に必要となるプログラムインストール

    && sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
    && wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
    && apt update \
    && apt -y install postgresql-15 \

最新版PostgreSQL取得用レポジトリ登録とバージョン指定インストール
(lsb_release実行結果の部分を展開後のテキスト'jammy'に固定しているためUbuntuバージョンが変わった場合変更する必要あり)
Linux downloads (Ubuntu)

    && --mount=type=secret,id=secret_key echo -n 'user1:' | cat - /run/secrets/secret_key | chpasswd \
    && --mount=type=secret,id=secret_key echo -n 'postgres:' | cat - /run/secrets/secret_key | chpasswd \

ユーザのパスワードを--mount=type=secretで渡して設定

    && echo "postgres ALL=(ALL:ALL) NOPASSWD: ALL" | tee "/etc/sudoers.d/dont-prompt-postgres-for-sudo-password" \

PostgreSQLインストール時に作成されたpostgresユーザでsudoする際にパスワードを要求されないように設定

    && sed -i -e 's:127.0.0.1/32:all         :' /var/local/postgresql/db/pg_hba.conf \
    && sed -i -e "/^#listen_addresses/ a listen_addresses = '*'" /etc/postgresql/15/main/postgresql.conf \

Windowsから接続可能なように設定変更(localhost内運用前提のためセキュリティ考慮無し)

WSLインポート手順

# Dockerfileのパスは $Env:USERPROFILE\docker\pgsql\Dockerfile の想定
cd $Env:USERPROFILE\docker\pgsql
docker build -t name:tag .
docker run --name name_tag -t name:tag ls /
docker export name_tag -o $Env:USERPROFILE\wsl\export.tar.gz
# WSL_NAME は任意の名称, $Env:USERPROFILE\wsl はwsl実体保存場所
wsl --import WSL_NAME $Env:USERPROFILE\wsl $Env:USERPROFILE\wsl\export.tar.gz

# インポートしたwsl環境を削除する場合
wsl --unregister WSL_NAME

自動起動

wsl -d WSL_NAME -u root -- service postgresql start

参考文献

Discussion