Docker で PostgreSQL コンテナを作る方法
データベースのソフトウェアとしては MySQL(MariaDB)が人気だと思いますが、 PostgreSQL を使用しているサービスを見かけることもあるでしょう。 Docker で PostgreSQL のコンテナを作成してみましょう。
Docker で PostgreSQL コンテナを作る
コンテナのイメージは、下記の公式イメージを使用します。
イメージのバージョン(タグ)はいろいろありますが、
特にこだわりが無いなら最新版(latest
)で良いと思います。
PostgreSQL はデフォルトで「postgres」というスーパーユーザーが作成されます。
MySQL(MariaDB)でいうところの「root」ユーザーみたいなものですね。
その「postgres」ユーザーのパスワードは、環境変数の POSTGRES_PASSWORD
で指定することができます。
version: "3.8" services: # PostgreSQL コンテナ postgresql: image: postgres:latest environment: POSTGRES_PASSWORD: password
ポートを公開する
PostgreSQL のデフォルトのポート番号は 5432 番です。
ホスト側から pgAdmin などの管理ツールで接続したい場合は、コンテナ側のポート 5432 番へのマッピングを設定しましょう。 ホスト側のポート番号は、他で使用されていないものなら何番でも良いと思います。
なお、ホスト側から接続しないのであれば、この設定は必要はありません。 pgAdmin などの管理ツールをホストにインストールするのが面倒なのであれば、 後述の Adminer コンテナを作成して利用してみましょう。
version: "3.8" services: # PostgreSQL コンテナ postgresql: image: postgres:latest ports: - 15432:5432 environment: POSTGRES_PASSWORD: password
ロケールを変更する
デフォルトの状態だと PostgreSQL のロケールが "en_US" になります。
変更したい場合は環境変数の POSTGRES_INITDB_ARGS
を使用します。
version: "3.8"
services:
# PostgreSQL コンテナ
postgresql:
image: postgres:latest
environment:
POSTGRES_INITDB_ARGS: "--locale=C"
POSTGRES_PASSWORD: password
タイムゾーンを変更する
デフォルトの状態だと PostgreSQL のデータの日時が9時間ずれて表示されます(日本は UTC からの時差が +09:00 なので)。 日本の日時に合わせるためには、タイムゾーンを変更してあげる必要があります。
タイムゾーンを変更するにはいろいろな方法がありますが、環境変数の TZ
を使用する方法が一番簡単だと思います。
これは正確に言えば PostgreSQL ではなく、システム(つまり Linux)のタイムゾーンを変更しているのですが、
PostgreSQL はデフォルトだとシステムのタイムゾーンを使用するようになっているので、PostgreSQL にも反映されます。
version: "3.8"
services:
# PostgreSQL コンテナ
postgresql:
image: postgres:latest
environment:
TZ: Asia/Tokyo
POSTGRES_PASSWORD: password
データが消えないようにする
コンテナが再作成された際などに、PostgreSQL コンテナのデータが消えてしまっては困ると思いますので、データが消えないようにボリュームを設定しておきましょう。 ボリュームを設定しない場合は、勝手にハッシュ名のボリュームが作成されるようなのですが、わかりづらいのでちゃんと設定した方が良いと思います。
PostgreSQL のデータは、デフォルトでは "/var/lib/postgresql/data" ディレクトリ配下に保存されています。
version: "3.8" services: # PostgreSQL コンテナ postgresql: image: postgres:latest volumes: - postgresql-data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: password volumes: postgresql-data:
バインドマウントを使用する
名前付きボリュームを使って Docker 内部にデータを保存しておくこともできますが、 たまに Docker でエラーが発生して、Docker が丸ごと初期化されたりすることがあるので、 バインドマウントを使用してホスト側にデータを保存しておいた方が安全かもしれません。 Windows で処理速度が気になる場合は、「Windows の Docker 環境を高速化する方法」を参考に、WSL 2 にバインドマウントする方法を検討してみてください。
version: "3.8" services: # PostgreSQL コンテナ postgresql: image: postgres:latest volumes: - ./postgresql-data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: password
初期データを投入する
コンテナが作成された直後はデータが空っぽの状態です。 手作業でテーブルを CREATE したり、データを INSTERT していくのはとても面倒だと思います。 その場合、PostgreSQL の初期化時に SQL ファイルを実行してくれる機能を使用すると良いでしょう。
PostgreSQL コンテナの "/docker-entrypoint-initdb.d" ディレクトリに SQL ファイルを置いておくと、 その SQL ファイルを、PostgreSQL の初期化時に実行してくれます。
PostgreSQL の初期化処理は、コンテナを初めて起動する場合や、データを保存しているボリュームを削除して起動した場合など、 データが空っぽな状態の時にコンテナを起動すると実行されます。
なお、ファイルの拡張子は ".sql" もしくは ".sql.gz"(gzip 圧縮した SQL ファイル)である必要があるので注意してください。 もし、初期データを動的に作成して投入したい場合は、".sh" ファイルも使用できるようです。
複数のファイルがある場合は、ファイル名のアルファベット順に実行されます。
version: "3.8"
services:
# PostgreSQL コンテナ
postgresql:
image: postgres:latest
volumes:
- ./postgresql-init:/docker-entrypoint-initdb.d
environment:
POSTGRES_PASSWORD: password
設定ファイルを使用する
PostgreSQL の設定を変更したい場合は、PostgreSQL の設定ファイルである postgresql.conf を使用すると良いでしょう。 なお、デフォルトの設定ファイルの場所は、"/var/lib/postgresql/data/postgresql.conf" です。 上述の「データが消えないようにする」で指定している PostgreSQL のデータディレクトリの中にあるので注意してください。 バインドマウントや名前付きボリュームしていた場合は、その中のファイルを直接編集する必要があります。
logging_collector = on
もし、設定ファイルがデータディレクトリの中にあると困る場合は、 設定ファイルの場所を起動時のコマンドで指定してあげましょう。 方法は下記の2つです。
方法1:docker-compose.yml ファイルの command で指定する
1つ目の方法は、docker-compose.yml ファイルの command
項目を使用する方法です。
PostgreSQL の設定ファイルをバインドマウントしてコンテナ内に配置し、
PostgreSQL がその設定ファイルを使用するように command
項目で指定します。
なお、PostgreSQL の設定ファイルを変更した場合は、反映させるためにコンテナの再起動(正確には PostgreSQL サーバーの再起動)が必要になります。
version: "3.8" services: # PostgreSQL コンテナ postgresql: image: postgres:latest command: postgres -c 'config_file=/etc/postgresql/postgresql.conf' volumes: - ./postgresql.conf:/etc/postgresql/postgresql.conf
解決策2:Dockerfile を使用してビルドする
2つ目の方法は、Dockerfile を使用してコンテナイメージをビルドする方法です。
Dockerfile の中で、PostgreSQL の設定ファイルをコンテナにコピーします。
ついでに chmod
コマンドでパーミッションを設定しておくと良いでしょう。
そして PostgreSQL がその設定ファイルを使用するように CMD
コマンドで指定します。
なお、PostgreSQL の設定ファイルを変更した場合は、反映させるためにコンテナをビルドし直す必要があります。
FROM postgres:latest COPY ./postgresql.conf /etc/postgresql/postgresql.conf RUN chmod 644 /etc/postgresql/postgresql.conf CMD ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
version: "3.8"
services:
# PostgreSQL コンテナ
postgresql:
build: ./postgresql-custom
Docker で Adminer コンテナを作る
PostgreSQL のコンテナが作成できたので、今度はその PostgreSQL を管理するためのツールである Adminer のコンテナを作成してみましょう。
Adminer は、PHP で実装されたデータベース管理ツールです。 MySQL(MariaDB)でいうところの phpMyAdmin のようなツールです。 とはいえ PostgreSQL 専用のツールというわけではなく、MySQL(MariaDB) や SQLite などでも利用できます。
Adminer は、たった1つの PHP のファイルだけで実装されているので、 Apache などの PHP が動くサーバーのドキュメントルートに、 その PHP ファイルをぽいっと置くだけで動きます。 そのため、わざわざ専用のサーバーを作らなくても PHP が動くサーバーであれば動くのですが、 PHP のバージョンが違っていたり、エクステンションが入っていなかったりして、 エラーが発生してしまうことがあると思いますので、Adminer 専用のコンテナを作成した方が良いでしょう。 Docker に公式のイメージが用意されているのでそれを使用しましょう。
コンテナのイメージは、下記の公式イメージを使用します。
イメージのバージョン(タグ)はいろいろありますが、特にこだわりが無いなら最新版(latest
)で良いと思います。
Adminer は Web サーバー上で動作しますのが、コンテナ側のポート番号は 8080 番です。 80 番ではないので注意してください。 ホスト側から Web ブラウザ(Chrome など)で接続できるよう、コンテナ側のポート 8080 番へのマッピングを設定しましょう。 ホスト側のポート番号は、他で使用されていないものなら何番でも良いと思います。
Adminer コンテナは、接続先の PostgreSQL コンテナが起動していない状態だと意味が無いと思いますので、
depends_on
の項目で、PostgreSQL コンテナの後に起動するように設定しておくと良いでしょう。
version: "3.8" services: # PostgreSQL コンテナ postgresql: (省略) # Adminer コンテナ adminer: image: adminer:latest ports: - 18080:8080 depends_on: - postgresql
接続情報を入力する
Adminer コンテナを起動するとログイン画面が表示されますので、
PostgreSQL コンテナへの接続情報を入力しましょう。
「サーバ」欄で、接続先のホストを指定します。
ホスト名には docker-compose.yml で定義しているサービス名(つまり、services
項目で指定しているキー)を使用できます。
上記の例では、ホスト名として "postgresql" が使用できます。