DockerでPostgreSQLを使う

PostgreSQLの公式Dockerイメージの基本的な使い方の紹介です。

Dockerでのファイルマウント方法、ネットワーク仕様については、Dockerまとめを参照してください。

コンソールでの操作はすべてWSL UbuntuのBash上のものです。

起動からpsqlコマンドでのDB操作まで

環境変数でパスワードを設定した状態で起動します。

$ docker run -d --rm --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword postgres:18.3

コンテナのシェルに入り、psqlコマンドが実行できます。

$ docker exec -it some-postgres bash
root@1c416b1591c5:/# psql --version
psql (PostgreSQL) 18.3 (Debian 18.3-1.pgdg13+1)
root@1c416b1591c5:/# psql -h localhost -U postgres
postgres=# create database mydb;
postgres=# \c mydb;
mydb=# \q

bash経由ではなく、直接psqlコマンドでコンテナに入ることもできます。

$ docker exec -it some-postgres psql -h localhost -U postgres

Adminerから接続する

Adminerの公式Dockerイメージを使います。

コンテナ同士で接続できるようにDockerのユーザー定義ネットワークを作成しておきます。

$ docker network create nw1

PostgreSQLのコンテナに作成したネットワークを割り当てて起動します。

$ docker run -d --rm --name some-postgres --network=nw1 -e POSTGRES_PASSWORD=mysecretpassword postgres:18.3

Adminerの設定

  • PostgreSQLコンテナと同じネットワークを割り当てます。
  • Adminerの接続先DBコンテナの名称はdbにする必要があるため、linkオプションでsome-postgresにdbという別名を設定します(PostgreSQLコンテナの名称を元からdbにした場合は、linkオプションの設定は不要です)。
  • ブラウザからアクセスできるようにポートを公開しておきます(今回は8090番使用)。
$ docker run -d --rm --name myadminer --network=nw1 --link some-postgres:db -p 8090:8080 adminer:5.4.2

http://localhost:8090/ にアクセスし、データベースの種類:PostgreSQL、ユーザー名:postgres、パスワード:mysecretpassword、データベース:postgresでログインできます。

DBファイルのマウント

データベースを永続化するためにマウントしてみます。

DBファイルをローカル上に作成

カレントディレクトリに空のディレクトリpostgresqlを作成し起動することで、初回起動時に自動的にDBファイルが作成され、2回目以降は作成済みのDBファイルが読み込まれます。

エラーが出たときに分かりやすいように今回は-itのオプションを付けています。

$ mkdir postgresql
$ docker run -it --rm --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword \
--mount type=bind,src="$(pwd)/postgresql",dst=/var/lib/postgresql postgres:18.3

DBファイルをDocker Volume上に作成

ボリュームが存在しない場合は最初に作成しておきます。

$ docker volume create vol-postgresql

# 作成結果を確認
$ docker volume ls

mountのtypeをvolumeにし、srcに作成したvolume名を指定します。

$ docker run -it --rm --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword \
--mount type=volume,src=vol-postgresql,dst=/var/lib/postgresql postgres:18.3

設定の変更

設定ファイルの適用

コンテナの中に設定ファイルのサンプルが入っているので、それを取り出します。

$ docker run -i --rm postgres:18.3 cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf

この設定ファイルで必要な項目を編集し、マウントして起動することで設定を適用できます。設定項目の詳細は、PostgreSQL: Documentation: 18: Chapter 19. Server Configurationを確認してください。

$ docker run -d --rm --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword \
--mount type=bind,src="$(pwd)/my-postgres.conf",dst=/etc/postgresql/postgresql.conf \
postgres:18.3 -c 'config_file=/etc/postgresql/postgresql.conf'

コマンドオプションでの設定変更

以下の例のように-cのコマンドオプションでパラメータを渡すことで、設定の変更をすることも可能です。

$ docker run -d --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword \
postgres:18.3 -c shared_buffers=256MB -c max_connections=200

DBの初期化処理

コンテナ上の/docker-entrypoint-initdb.dのディレクトリにshやsqlファイルを置いておけば、コンテナ初回起動時に辞書順にそれらが実行されます(ファイルを更新しても2回目以降の起動では実行されません)。

そのため、このディレクトリをマウントしておけば、ローカルファイルに置いたsqlコマンドを実行できます。

以下の例では、postgresql_initディレクトリをカレントディレクトリに作成し、そこに2つのSQLファイルを作成してみました。辞書順の実行なので、ゼロ埋め3桁の数字をプレフィックスに付けています。

001_create-db.sql
create database db1;
-- データベース一覧表示
\l

-- データベース選択
\c db1;

create table tb1(id varchar(10), name varchar(10), age int);

-- テーブル一覧表示
\dt

-- テーブルのカラム一覧表示
\d tb1
002_insert-data.sql
\c db1;
insert into tb1 values('ID001', 'Alice', 10);
insert into tb1 (id, name, age) values
('ID002', 'Bob', 20),
('ID003', 'Corn', 30),
('ID004', '山田', 40)
;
select * from tb1;

Adminerで確認するためのnetworkオプションも付けて起動します。ディレクトリは以下の構成です。

$ tree
.
└── postgresql_init
    ├── 001_create-db.sql
    └── 002_insert-data.sql
$ docker run -it --rm --name some-postgres --network=nw1 -e POSTGRES_PASSWORD=mysecretpassword \
--mount type=bind,src="$(pwd)/postgresql_init",dst=/docker-entrypoint-initdb.d \
postgres:18.3

adminerのコンテナを起動し、DBが正常に作成されていることを確認できます。

adminerでの確認画像