pgAdminで「Connection refused」に遭遇したとき、テックリードが真っ先に確認すべき5つの急所
開発の現場で、ターミナルから叩くクエリも、CI/CDパイプラインのマイグレーションも順調に進んでいる。しかし、GUIでサクッとデータを視覚的に確認しようとpgAdminを開いた瞬間、あの無慈悲なエラーメッセージが画面に突き刺さる。
> “Connection refused”
このエラーは単なる「繋がらない」という事実を示しているに過ぎない。しかし、その背後にはネットワーク層、OSのセキュリティ層、コンテナの仮想レイヤー、そしてPostgreSQL自体の心臓部である設定ファイルの不整合が複雑に絡み合っている。
本記事では、単なるマニュアルのコピペではなく、修羅場をくぐり抜けてきたエンジニアたちが実践している根本的な原因究明と秒速の解決アプローチ、そしてチーム全体の開発体験(DX)を跳ね上げるための実践知を授ける。
—
1. 接続拒否のメカニズムと「5つの急所」
「Connection refused(接続拒否)」というエラーは、TCP/IPのハンドシェイクの段階で、「指定されたIPアドレスとポートにリスナー(待ち受けているプロセス)が存在しない」、あるいは「アクセスが厳格に遮断されている」場合にOSのネットワークスタックが即座に返す応答だ。
pgAdminからPostgreSQLへの接続において、このエラーを引き起こす5つの急所と、その解決策をロジカルに解説する。
—
急所1: `postgresql.conf` の `listen_addresses` がローカルループバックを向いている
PostgreSQLのデフォルト設定では、セキュリティの観点から外部からの接続を一切受け付けないようになっている。Docker環境や別サーバー、あるいはローカルホストであってもIPバインドが適切でないと、このエラーを踏む。
診断と解決策
設定ファイル(`postgresql.conf`)を開き、`listen_addresses` の値を確認する。
エラーの原因となるデフォルト設定(ローカルからしか繋がらない)
listen_addresses = ‘localhost’
すべてのインターフェースからの接続を許可する場合(開発環境向け)
listen_addresses = ”
特定のネットワークインターフェースのみ許可する場合(本番・ステージング向け)
listen_addresses = ‘localhost, 192.168.1.10’
> ⚠️ 現場の知見:
> 変更後は必ずサービスの再起動(`pg_ctl reload` または `systemctl restart postgresql`)が必要だ。これを忘れて「設定を変えたのに繋がらない」と絶望するエンジニアが後を絶たない。
—
急所2: `pg_hba.conf` によるクライアント認証の拒絶
ネットワーク層(TCP)の壁を突破しても、ホストベースのアクセス制御(HBA)である `pg_hba.conf` が通さなければ、やはり接続は拒絶される。
診断と解決策
`pg_hba.conf` に、pgAdminを実行しているクライアントからのアクセス許可エントリが存在するか確認する。
TYPE DATABASE USER ADDRESS METHOD
Dockerコンテナなど同一ネットワーク内からのパスワード認証を許可する例
host all all 172.16.0.0/12 scram-sha-256
開発用ローカルPCからのすべての接続を許容する場合(セキュアなネットワーク内限定)
host all all 0.0.0.0/0 scram-sha-256
認証方式には古くからある `md5` ではなく、より強固な `scram-sha-256` の使用を強く推奨する。設定反映にはリロード(`SELECT pg_reload_conf();`)を忘れずに。
—
急所3: Docker環境におけるポートフォワーディングの迷宮
PostgreSQLをDockerで稼働させ、ホストマシンのpgAdminから接続する際、最も頻発するのがこのトラブルだ。「コンテナ内では動いているのに、外から見えない」という現象は、ポートマッピングの定義ミスに起因する。
診断と解決策
Docker Composeファイル(`docker-compose.yml`)のポート設定を確認せよ。
version: ‘3.8’
services:
postgres:
image: postgres:15-alpine
container_name: pg_master
environment:
POSTGRES_USER: dev_user
POSTGRES_PASSWORD: secure_password
POSTGRES_DB: app_development
ports:
# [ホスト側ポート]:[コンテナ側ポート]
# 左側を忘れたり、誤ったポートを指定すると Connection refused になる
- “5432:5432”
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
さらに、Dockerネットワーク内部でpgAdminからコンテナにアクセスする場合、`localhost` ではなく サービス名(例: `postgres`) をホスト名として指定しているか確認すること。ホストマシンの `localhost:5432` と、Dockerネットワーク内の `postgres:5432` は全く別物である。
—
急所4: OSファイアウォールおよびクラウドのセキュリティグループ
ローカルのミドルウェア設定に問題がなくても、OSのパケットフィルタリング機能(UFW, firewalld)や、AWSのセキュリティグループ、GCPのファイアウォールルールがポート `5432` をブロックしているケース。
診断と解決策
Linux環境であれば、以下のコマンドでポートのリスニング状態とファイアウォールを確認する。
5432ポートでリスニングしているプロセスがあるか確認
sudo ss -tunlp | grep 5432
UFWの状態確認(Ubuntu)
sudo ufw status
必要に応じて開放
sudo ufw allow 5432/tcp
—
急所5: pgAdmin側の接続プロパティ(SSLモード・タイムアウト)の不整合
サーバー側の準備が完璧であっても、pgAdminの接続ダイアログの設定がミスマッチを起こしていると、接続確立に失敗する。
診断と解決策
pgAdminのサーバープロパティ設定画面([Connection] タブ)を以下のように見直せば、大半の謎エラーは消え去る。
- Host name/address: DockerならホストマシンのIP(または`host.docker.internal`)、リモートなら適切なIP/ドメイン。
- Port: デフォルトの `5432` から変更している場合はそのポート。
- SSL mode: サーバー側がSSLを強制していない環境で `require` や `verify-full` にしているとハンドシェイクに失敗する。まずはお互いの環境に合わせて `prefer` または `disable` から検証を始めよ。
—
2. 開発スピードを劇的に高める pgAdmin の実践テクニック
無事に接続が完了したところで、pgAdminを単なる「データの閲覧ツール」から「最強の開発生産性ブースター」へと昇華させるためのプロの技を授ける。
隠れたキーボードショートカット
マウス操作でメニューを辿る時間は、エンジニアの認知負荷を無駄に高める。以下のショートカットを体に刻み込め。
- `F5`: クエリの実行(Query Tool内)
- `Ctrl + Space`: 自動補完(IntelliSense)の強制呼び出し
- `Shift + Alt + Down`: 選択行の複製(複数行編集のベース)
- `Ctrl + Shift + R`: 接続ツリーの強制リフレッシュ(DDL変更後に即座に反映させる)
チーム開発で役立つ設定の共有化ルール
個人のローカル環境ごとにpgAdminを設定しているようでは、チームの成熟度が低いと言わざるを得ない。pgAdminは、サーバー接続情報のバックアップとインポート機能を備えている。
1. 接続先が安定したら、Objectメニューから 「Backup…」(またはサーバーグループの右クリックから 「Export Servers」)を選択。
2. 出力されたJSONファイルを、リポジトリ(秘匿情報を含まないテンプレート形式)で管理する。
3. 新規参画者はそのファイルをインポートするだけで、一瞬で開発環境のDB接続が完了する。
サーバ定義JSONのベストプラクティス例
チームで共有・配布する際のリファレンスとなるJSON構成案を示す。パスワードなどの機密情報はあえて含めず、接続時にプロンプト入力を促す構成にするのがセキュアなチーム運用の鉄則だ。
{
“Servers”: {
“1”: {
“Name”: “Local Development (Docker)”,
“Group”: “Development”,
“Host”: “localhost”,
“Port”: 5432,
“MaintenanceDB”: “app_development”,
“Username”: “dev_user”,
“SSLMode”: “prefer”,
“PassFile”: “”,
“ConnectNow”: true,
“Color”: “#2b6cb0”
},
“2”: {
“Name”: “Staging Environment”,
“Group”: “Staging”,
“Host”: “staging-db.internal.net”,
“Port”: 5432,
“MaintenanceDB”: “app_staging”,
“Username”: “stg_admin”,
“SSLMode”: “require”,
“PassFile”: “”,
“ConnectNow”: false,
“Color”: “#c53030”
}
}
}
> 🎨 プロの小技:
> サーバー定義ごとに `Color` プロパティでタブやツリーの色(本番は赤系、開発は青系など)を指定しておけ。「本番環境に誤ってDDLを流してしまった」という全エンジニアが恐れるヒューマンエラーを、視覚的に100%防ぐことができる。
—
3. 結び:ツールに振り回されるな、ツールを支配せよ
「Connection refused」というエラーは、システムからのメッセージだ。「ネットワークのどこかに噛み合わせの悪いピースがある」と、正確に現在地を教えてくれている。
パニックになってやみくもに設定ファイルを書き換えるのではなく、「ネットワーク層 → セキュリティ層 → アプリケーション層」という上流から下流への依存関係を冷静に辿ることで、トラブルシューティングの時間は劇的に短縮される。
本記事で紹介した5つの急所とベストプラクティスを武器に、インフラとデータベースの境界線を完全に掌握し、開発のスピードを最高速度へと加速させてほしい。