Docker で PostgreSQL コンテナを作る方法

この記事は最終更新日から 1年以上 が経過しています。

データベースのソフトウェアとしては MySQL(MariaDB)が人気だと思いますが、 PostgreSQL を使用しているサービスを見かけることもあるでしょう。 Docker で PostgreSQL のコンテナを作成してみましょう。

Docker で PostgreSQL コンテナを作る

コンテナのイメージは、下記の公式イメージを使用します。 イメージのバージョン(タグ)はいろいろありますが、 特にこだわりが無いなら最新版(latest)で良いと思います。

PostgreSQL はデフォルトで「postgres」というスーパーユーザーが作成されます。 MySQL(MariaDB)でいうところの「root」ユーザーみたいなものですね。 その「postgres」ユーザーのパスワードは、環境変数の POSTGRES_PASSWORD で指定することができます。

例:PostgreSQL の "postgres" ユーザーのパスワードを "password" にする場合
docker-compose.yml
version: "3.8"
services:

  # PostgreSQL コンテナ
  postgresql:
    image: postgres:latest
    environment:
      POSTGRES_PASSWORD: password

ポートを公開する

PostgreSQL のデフォルトのポート番号は 5432 番です。

ホスト側から pgAdmin などの管理ツールで接続したい場合は、コンテナ側のポート 5432 番へのマッピングを設定しましょう。 ホスト側のポート番号は、他で使用されていないものなら何番でも良いと思います。

なお、ホスト側から接続しないのであれば、この設定は必要はありません。 pgAdmin などの管理ツールをホストにインストールするのが面倒なのであれば、 後述の Adminer コンテナを作成して利用してみましょう。

例:ホスト側のポート 15432 番と、コンテナ側のポート 5432 番をマッピングする場合
docker-compose.yml
version: "3.8"
services:

  # PostgreSQL コンテナ
  postgresql:
    image: postgres:latest
    ports:
      - 15432:5432
    environment:
      POSTGRES_PASSWORD: password

ロケールを変更する

デフォルトの状態だと PostgreSQL のロケールが "en_US" になります。 変更したい場合は環境変数の POSTGRES_INITDB_ARGS を使用します。

例:ロケールを "C" に変更する(つまり、ロケールを設定しない)場合
docker-compose.yml
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 にも反映されます。

例:タイムゾーンを "Asia/Tokyo" に変更する場合
docker-compose.yml
version: "3.8"
services:

  # PostgreSQL コンテナ
  postgresql:
    image: postgres:latest
    environment:
      TZ: Asia/Tokyo
      POSTGRES_PASSWORD: password

データが消えないようにする

コンテナが再作成された際などに、PostgreSQL コンテナのデータが消えてしまっては困ると思いますので、データが消えないようにボリュームを設定しておきましょう。 ボリュームを設定しない場合は、勝手にハッシュ名のボリュームが作成されるようなのですが、わかりづらいのでちゃんと設定した方が良いと思います。

PostgreSQL のデータは、デフォルトでは "/var/lib/postgresql/data" ディレクトリ配下に保存されています。

例:名前付きボリュームを使用して、Docker 内部のボリューム "postgresql-data" にデータを保存する場合
docker-compose.yml
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 にバインドマウントする方法を検討してみてください。

例:バインドマウントを使用して、ホストの "./postgresql-data" にデータを保存する場合
docker-compose.yml
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" ファイルも使用できるようです。

複数のファイルがある場合は、ファイル名のアルファベット順に実行されます。

例:ホストの "./postgresql-init" ディレクトリの中の SQL ファイルを、初期データとして投入する場合
docker-compose.yml
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 のデータディレクトリの中にあるので注意してください。 バインドマウントや名前付きボリュームしていた場合は、その中のファイルを直接編集する必要があります。

例:ログをファイルに出力する場合
postgresql.conf
logging_collector = on

もし、設定ファイルがデータディレクトリの中にあると困る場合は、 設定ファイルの場所を起動時のコマンドで指定してあげましょう。 方法は下記の2つです。

方法1:docker-compose.yml ファイルの command で指定する

1つ目の方法は、docker-compose.yml ファイルの command 項目を使用する方法です。 PostgreSQL の設定ファイルをバインドマウントしてコンテナ内に配置し、 PostgreSQL がその設定ファイルを使用するように command 項目で指定します。 なお、PostgreSQL の設定ファイルを変更した場合は、反映させるためにコンテナの再起動(正確には PostgreSQL サーバーの再起動)が必要になります。

例:ホストの "./postgresql.conf" を、コンテナの "/etc/postgresql/postgresql.conf" にバインドマウントする場合
docker-compose.yml
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 の設定ファイルを変更した場合は、反映させるためにコンテナをビルドし直す必要があります。

例:ホストの "./postgresql-custom/postgresql.conf" を、コンテナの "/etc/postgresql/postgresql.conf" にコピーする場合
./postgresql-custom/Dockerfile
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"]
docker-compose.yml
version: "3.8"
services:

  # PostgreSQL コンテナ
  postgresql:
    build: ./postgresql-custom

Docker で Adminer コンテナを作る

PostgreSQL のコンテナが作成できたので、今度はその PostgreSQL を管理するためのツールである Adminer のコンテナを作成してみましょう。

adminer.png

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 コンテナの後に起動するように設定しておくと良いでしょう。

例:ホスト側のポート 18080 番と、コンテナ側のポート 8080 番をマッピングする場合
docker-compose.yml
version: "3.8"
services:

  # PostgreSQL コンテナ
  postgresql:
    (省略)

  # Adminer コンテナ
  adminer:
    image: adminer:latest
    ports:
      - 18080:8080
    depends_on:
      - postgresql

接続情報を入力する

Adminer コンテナを起動するとログイン画面が表示されますので、 PostgreSQL コンテナへの接続情報を入力しましょう。 「サーバ」欄で、接続先のホストを指定します。 ホスト名には docker-compose.yml で定義しているサービス名(つまり、services 項目で指定しているキー)を使用できます。 上記の例では、ホスト名として "postgresql" が使用できます。

adminer_login.png

参考サイト

関連記事

ほとんどの Web アプリではデータを保存する際に、データベースを使用しています。XAMPP では、データベースとして MySQL と互換性のある MariaDB が採用されていますが、Docker を使用するのであればせっかくなので MySQL のコンテナを作成してみましょう。Docker で MySQL コンテナを ...
Web アプリではキャッシュやセッションを保存する際に、Redis がよく使われていたりします。Docker で Redis のコンテナを作成してみましょう。XAMPP では Redis をインストールするのはかなり大変でしたが、Docker なら簡単に作成することができます。Docker で Redis コンテナを作 ...
Docker で開発環境を作るのって結構大変です。構成を気軽に組み替えたりできるため自由度が高いですが、その分必要になる知識も多いですし、必要な作業も多いです。まずは、XAMPP でおなじみの Apache と PHP を組み合わせた Web サーバーを作るところから始めてみましょう。Docker で Apache + ...
Docker は、構成を気軽に組み替えたりできるので、とても便利ですよね。Windows で Docker を使って開発している方も多いと思うのですが、個人的にはどうしても気が乗らない理由がありました。それは処理速度です。遅い。遅すぎる。めちゃくちゃ遅い。つらい。耐えられない。。。ということで調査しました。いろいろと調 ...
最近では、アプリケーションの実行環境の構築に Docker を使うことも珍しくなくなりました。Docker は便利ではあるのかもしれませんが、難しく感じて敬遠されている人もいるのではないでしょうか。その感覚はおそらく間違っていません。実際、知れば知るほど奥が深い技術だと感じてしまいます。もはや沼というか深淵を覗いている ...

お知らせ

記事検索

最新記事

人気記事

RSSフィード

フィードバック

要望などあれば、お気軽にどーぞ。 不具合やバグを発見した場合も、連絡をいただけると助かります。

匿名でフィードバックする
匿名でフィードバックする

要望などあれば、お気軽にどーぞ。 不具合やバグを発見した場合も、連絡をいただけると助かります。

なお、このフォームから入力された内容について、管理者から返信はできませんので注意してください。 もし、管理者からの返信が必要であれば、X(旧 Twitter) もしくは、お問い合わせより、お願いします。