Courses
セッションを行き来し、構文を暗記し、破壊的なクエリでタイプミスがないことを祈る——そんな作業はすぐに嫌になります。視覚的なクエリプランも、スキーマブラウザも、簡単なバックアップ方法もありません。動くには動きますが、理想からはほど遠いのです。
pgAdmin 4 は、PostgreSQL 専用に作られたブラウザベースの GUI でこれを解決します。Docker で動かせばローカルインストールは不要。コンテナを起動するだけです。
この記事では、Docker Compose を使って PostgreSQL と pgAdmin 4 をセットアップし、2 つのコンテナを接続して、pgAdmin の Query Tool、スキーマブラウザ、バックアップ機能を使う方法を紹介します。
読み進めるには、マシンに Docker をインストールして起動しておいてください。Docker Compose が初めての場合は、マルチコンテナ開発をどう簡素化するかをまとめたガイドをご覧ください。
pgAdmin 4 とは?
pgAdmin 4 は、PostgreSQL のためのオープンソースのブラウザベース管理・開発プラットフォームです。Web ブラウザからアクセスできるため、デスクトップアプリのインストールは不要。GUI でデータベースの管理、クエリの実行、スキーマの確認、バックアップの操作が行え、コマンドラインに触れる必要はありません。
公式の Docker イメージは dpage/pgadmin4 で、pgAdmin の開発チームがメンテナンスしています。
pgAdmin 4 を Docker で動かすと、ローカルインストールに比べて実利的なメリットがいくつかあります。第一に可搬性——データベース環境全体がチームで共有できる docker-compose.yml に収まります。第二にバージョン衝突がないこと——pgAdmin は独立したコンテナで動き、マシン上の他のものから完全に隔離されます。不要になったら docker compose down でクリーンに消せます。
pgAdmin 4 と他の PostgreSQL GUI の比較
データベース管理用の GUI は数多くあります。ここでは、pgAdmin 4 を人気の 2 つの代替ツールと比較します。

pgAdmin 4 と人気の代替ツールの比較
DBeaver と TablePlus は優れたツールですが、どちらも公式の Docker イメージはありません。PostgreSQL がすでに Docker で動いているなら、pgAdmin 4 は絶好の相棒です。docker-compose.yml にサービスを 1 つ追加するだけで、同じネットワーク内で一緒に動作します。
Docker Compose で環境をセットアップする
PostgreSQL と pgAdmin 4 を素早く同時に起動する最短ルートは、1 つの docker-compose.yml にまとめることです。トピックが初めての方は、基本を解説した Docker Compose ガイド をご覧ください。ここでは pgAdmin 固有の設定に焦点を当てます。
以下の完全なファイルをコピー&ペーストしてください。
services:
postgres:
image: postgres:18
container_name: postgres
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
POSTGRES_DB: mydb
volumes:
- postgres_data:/var/lib/postgresql
networks:
- pgnetwork
pgadmin:
image: dpage/pgadmin4:9.13
container_name: pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: you@yourdomain.com
PGADMIN_DEFAULT_PASSWORD: password
PGADMIN_LISTEN_PORT: 5050
ports:
- "5050:5050"
volumes:
- pgadmin_data:/var/lib/pgadmin
depends_on:
- postgres
networks:
- pgnetwork
volumes:
postgres_data:
pgadmin_data:
networks:
pgnetwork:
depends_on フィールドは、Docker Compose に pgadmin より先に postgres コンテナを起動するよう指示します。これがないと、PostgreSQL の準備が整う前に pgAdmin が起動して接続に失敗することがあります。なお、PostgreSQL が「完全にヘルシー」になるのを待つわけではなく、コンテナの起動を待つだけです。それでも多くのレースコンディションは回避できます。
pgAdmin 4 の環境変数
必須の環境変数は 2 つあります。
PGADMIN_DEFAULT_EMAIL- pgAdmin の Web インターフェースにログインする際のメールアドレスPGADMIN_DEFAULT_PASSWORD- そのアカウントのパスワード
3 つ目は任意ですが、指定しておくのがおすすめです。
PGADMIN_LISTEN_PORT- コンテナ内で pgAdmin が待ち受けるポート。デフォルトは 80 ですが、5050に設定するとポートマッピングが分かりやすくなります。
とはいえ、Compose ファイルに認証情報をハードコードするのはよくありません。特にそのファイルがバージョン管理に入る可能性がある場合はなおさらです。.env ファイルに移しましょう。
docker-compose.yml と同じディレクトリに .env ファイルを作成します。
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret
POSTGRES_DB=mydb
PGADMIN_DEFAULT_EMAIL=admin@example.com
PGADMIN_DEFAULT_PASSWORD=secret
次に、Compose ファイルでこれらの変数を参照します。
# postgres
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
# pgadmin
environment:
PGADMIN_DEFAULT_EMAIL: ${PGADMIN_DEFAULT_EMAIL}
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_DEFAULT_PASSWORD}
Docker Compose はコマンド実行時に .env を自動で読み込むため、追加の設定は不要です。.gitignore に .env を追加しておけば、認証情報はリポジトリに含まれません。
ボリュームとデータの永続化
/var/lib/pgadmin にマウントしたボリュームには、セッションデータ、保存したサーバー接続、各種設定など、pgAdmin のデータが保存されます。Compose ファイルからこれを外すと、コンテナを再起動するたびにそれらのデータは失われます。
今回の Compose ファイルでは、ホスト側で Docker が管理する名前付きボリュームを使用しています。明示的に docker volume rm で削除しない限り、コンテナの再起動や再作成、イメージの更新後もデータは保持されます。
スタックの起動と pgAdmin 4 へのアクセス
docker-compose.yml の準備ができたら、スタックの起動はこの 1 コマンドです。
docker compose up -d
-d フラグは両コンテナをデタッチドモードで起動します。バックグラウンドで動き、ターミナルはそのまま使えます。両コンテナが動いているか確認するには次を実行します。
docker ps
postgres と pgadmin の両方が Up ステータスで表示されるはずです。

コンテナのステータス
おかしい点があれば、pgAdmin のログを確認してください。
docker logs pgadmin
正常起動時は次のように表示されます。

pgAdmin の起動ログ
ここでエラーが出ている場合、主な原因は次の 3 つのいずれかです。
-
Password authentication failed:
.envファイル内のPGADMIN_DEFAULT_PASSWORDがない、または不正 -
Port is already allocated: ポート 5050 を別のプロセスが使用中。Compose ファイルでホスト側ポートを変更
-
No such file or directory: ボリュームパスが誤っているか、コンテナに書き込み権限がない
両コンテナが起動し、ログに問題がないことを確認したら、ブラウザで http://localhost:5050 を開きます。

pgAdmin のログインページ
PGADMIN_DEFAULT_EMAIL と PGADMIN_DEFAULT_PASSWORD で設定したメールとパスワードでログインします。pgAdmin のダッシュボードに移動し、PostgreSQL サーバーの登録に進めます。

pgAdmin のホームページ
pgAdmin 4 を PostgreSQL コンテナに接続する
pgAdmin のサイドバーで、Servers を右クリック → Register → Server。General と Connection の 2 つのタブを入力します。
General タブ
サーバーに意味のある名前を付けます(例:local-dev-postgres)。これは pgAdmin 内のラベルに過ぎないので、環境に合う名前なら何でも構いません。

サーバー登録 - General タブ
Connection タブ
ここで localhost を使わないでください。
Docker ネットワーク内では、localhost はそのコンテナ自身を指します——ホストマシンでも、PostgreSQL コンテナでもありません。Docker には独自の内部 DNS があり、docker-compose.yml で定義したサービス名でコンテナ名を解決します。PostgreSQL サービス名が postgres なら、それがホスト名になります。
各フィールドは次のように入力します。
-
Host name/address:
postgres(docker-compose.ymlのサービス名) -
Port:
5432 -
Maintenance database: Compose ファイルの
POSTGRES_DBの値(例:mydb) -
Username:
POSTGRES_USERの値(例:admin) -
Password:
POSTGRES_PASSWORDの値
最後に Save をクリックします。

サーバー登録 - Connection タブ
設定が正しければ、サーバーがサイドバーに表示され、展開してデータベースを確認できるようになります。

サーバー登録の成功
これで接続完了です。
Query Tool を使う
接続できたので、ここからは pgAdmin 4 と Postgres の基本を見ていきます。
上部メニューの Tools - Query Tool をクリックして Query Tool を開きます。インターフェースは 3 つのパネルで構成されています。
- Editor: SQL を記述する場所
- Data Output: クエリ実行後の結果表示
- Messages: PostgreSQL からのステータスメッセージ、エラー、実行情報

クエリツール
SQL の作成と実行
簡単な orders テーブルを作成し、データを追加してみましょう。各ブロックは再生ボタンか、ショートカットの F5 で実行できます。
テーブルを作成します。
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
customer_name VARCHAR(100) NOT NULL,
product VARCHAR(100) NOT NULL,
quantity INT NOT NULL,
order_date DATE DEFAULT CURRENT_DATE
);
数行挿入します。
INSERT INTO orders (customer_name, product, quantity)
VALUES
('Alice Johnson', 'Wireless Keyboard', 2),
('Bob Smith', 'USB-C Hub', 1),
('Carol White', 'Mechanical Keyboard', 3);
データを問い合わせます。
SELECT * FROM orders;

データのクエリ
結果は Data Output パネルに表形式で表示されます。列のソート、サイズ変更、グリッドからの行コピーが可能です。
ビジュアルクエリプランを読む
クエリ実行時の舞台裏を確認するには、SELECT 文に対して EXPLAIN ANALYZE を実行します。
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_name = 'Alice Johnson';

Explain Analyze の結果
Data Output パネルには生の出力が表示されますが、pgAdmin にはより良い方法があります。ツールバーの Explain ボタンをクリックすると、クエリプランがインタラクティブなグラフで表示されます。

グラフとしてのクエリプラン
今回のクエリは単純ですが、テーブルの結合や複雑な集計を行う場合には、より多くの情報が得られます。
これは、EXPLAIN の生出力を読むのは遅く、間違いが起きやすいため重要です。ビジュアルプランなら、大きなテーブルで全表走査が発生している場合や、インデックスがあるのに使われていない場合が一目で分かります。
データベーススキーマを管理する
pgAdmin のサイドバーはデータベース構造を俯瞰でき、GUI から編集も可能です。
サイドバーのツリー構造は、Servers → サーバー名 → Databases → データベース → Schemas → public → Tables という流れです。任意のテーブルを展開すると、Columns、Indexes、Constraints が子ノードとして表示されます。クリックすると右ペインで詳細を確認できます。
テーブルの作成と編集
新しいテーブルを作成するには、スキーマ配下の Tables を右クリックして Create → Table を選びます。複数のタブを持つダイアログが開きます。

テーブルの作成
General タブでテーブル名を設定します。Columns タブに切り替えて列を追加します——各行で列名、データ型、長さ、NULL 可否を設定できます。Constraints タブでは主キー、外部キー、一意制約を設定します。
既存テーブルにインデックスを追加するには、サイドバーでそのテーブルを展開し、Indexes を右クリックして Create → Index を選びます。対象列を選び、インデックスタイプを指定します。btree がデフォルトで、多くのケースに適しています。

インデックスの作成
バックアップとリストア
データベースをバックアップするには、Tools → Backup に進みます。次のいずれかの形式を選びます。
- Custom: 圧縮されたバイナリ形式。柔軟性が最も高く、個々のテーブル単位でリストアできるため多くのケースで最適
- Plain: テキストエディタで読めるプレーンな SQL スクリプト
- Tar: 非圧縮のアーカイブ。使用頻度は低めですが、一部のリストア手順で有用
形式と保存先パスを選ぶと、pgAdmin はバックグラウンドで pg_dump を実行し、ファイルをローカルに保存します。

バックアップの作成
リストアは、Tools → Restore でバックアップファイルを選び、対象データベースを指定します。

バックアップからのリストア
これがなぜ有用かというと、たとえば開発用データベースで破壊的なマイグレーションをテストする場面を想像してください。まずバックアップを取り、マイグレーションを実行し、もし問題が起きたらバックアップをリストアして既知の状態に戻せます。
Docker 上で pgAdmin 4 を運用するためのベストプラクティス
pgAdmin 4 を動かすだけなら簡単ですが、安定して運用するにはいくつか知っておくべきことがあります。実用的なヒントを挙げます。
認証情報は Compose ファイルに書かない
多くの場合、docker-compose.yml はバージョン管理に入ります——ハードコードしたパスワードも一緒に。認証情報は .env に移し、.gitignore に登録してください。本番環境ではさらに踏み込んで Docker secrets を使い、機密値を環境変数ではなくファイルとしてマウントすることを検討しましょう。
pgAdmin のポートをパブリックに公開しない
デフォルトでは、Docker はポートを 0.0.0.0 にバインドします。これは公開インターフェースを含む全てのネットワークインターフェースを意味します。リモートサーバーでは、pgAdmin にインターネットから到達できてしまいます。必ず 127.0.0.1 に明示的にバインドしてください。
ports:
- "127.0.0.1:5050:5050"
これで、そのサーバー自身からしか pgAdmin にアクセスできません。リモートから必要な場合は SSH トンネルや認証付きのリバースプロキシを使用してください。
イメージタグを固定する
dpage/pgadmin4:latest を使うと、誰かが docker compose pull を実行したタイミングで新しいバージョンが取得されます。新バージョンは挙動の変更、設定の破損、予期せぬ変更をもたらす可能性があります。dpage/pgadmin4:9.13 のように特定のタグを使い、チーム全員が全く同じバージョンを実行できるようにしましょう。
servers.json でサーバー接続をプリロードする
チーム全員が同じ Compose 構成を共有しているなら、スタック起動後に各自が PostgreSQL サーバーを登録する手間は不要です。pgAdmin は起動時に接続を事前登録する servers.json をサポートしています。次のようにコンテナへマウントします。
volumes:
- ./servers.json:/pgadmin4/servers.json
最小の servers.json は次の通りです。
{
"Servers": {
"1": {
"Name": "local-dev-postgres",
"Group": "Servers",
"Host": "postgres",
"Port": 5432,
"MaintenanceDB": "mydb",
"Username": "admin",
"SSLMode": "prefer"
}
}
}
pgAdmin の起動時にサーバーが表示され、手動設定は不要になります。
まとめ
この記事では、Docker 上で pgAdmin 4 をゼロからセットアップする方法を解説しました。PostgreSQL と pgAdmin 4 を同時に起動する Docker Compose ファイルを作成し、Docker の内部 DNS を使って 2 つのコンテナを接続し、pgAdmin の中核機能(Query Tool、スキーマブラウザ、バックアップ/リストア)を使いました。
ここでの核心は再現性です。
docker-compose.yml、servers.json、.env の 3 点があれば、完全に構成済みのデータベース環境をチームメイトに渡せます。これで「自分の環境では動く」問題は二度と起きません。
Docker とコンテナ化をさらに深掘りするなら、Intermediate Docker コースをご覧ください。マルチステージビルド、ネットワーキング、Compose の詳細まで実用的な知見を詰め込んでいます。
Docker pgAdmin のよくある質問
Windows や macOS で Docker 上の pgAdmin 4 を実行できますか?
はい。dpage/pgadmin4 イメージは Windows と macOS を含む、Docker をサポートするあらゆるオペレーティングシステムで動作します。セットアップ手順や docker-compose.yml はプラットフォーム間で共通です。
Docker イメージを更新するたびに pgAdmin 4 を再インストールする必要がありますか?
いいえ。/var/lib/pgadmin を名前付きボリュームにマウントしている限り、新しいイメージを取得しても保存済みデータには影響しません。サーバー接続、セッションデータ、設定は、イメージ更新やコンテナ再起動を経ても保持されます。
本番データベースで Docker 上の pgAdmin 4 を使っても安全ですか?
Docker 上の pgAdmin 4 は、開発や社内ツール用途であれば問題なく使えますが、本番データベースに接続する場合は適切な対策が必要です。pgAdmin のポートを公開しない、認証情報は必ず .env もしくは Docker secrets で管理する、リモートアクセスが必要なら認証付きリバースプロキシの背後に置く、といった対策を講じてください。
pgAdmin から PostgreSQL に接続する際、ホスト名に「localhost」を使えないのはなぜですか?
Docker ネットワーク内では、localhost はそのコンテナ自身を指し、ホストマシンや別コンテナを指しません。Docker には独自の内部 DNS があり、docker-compose.yml で定義されたサービス名を使ってコンテナ名を解決します。ホスト名には PostgreSQL サービス名(通常は postgres)を使用してください。
pgAdmin のバックアップ形式「Custom」「Plain」「Tar」の違いは何ですか?
Custom は圧縮済みのバイナリ形式で、最も柔軟です——データベース全体ではなく個々のテーブル単位でリストアできます。Plain は可読な SQL スクリプトを出力し、テキストエディタで開いて確認・編集してからリストアするのに便利です。Tar は非圧縮のアーカイブで、利用頻度は低めですが、pg_restore による選択的なリストアでサポートされています。