エラーの内容
Node.jsアプリを起動すると、即座またはリクエスト処理中にクラッシュし、次のようなエラーが表示されます:
Error: connect ECONNREFUSED 127.0.0.1:5432
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 5432
}
ポート番号は接続先によって異なります:PostgreSQLは5432、MySQLは3306、Redisは6379、MongoDBは27017、またはサービスが使用するカスタムポートです。根本原因は常に同じです:Node.jsが指定したアドレスとポートへのTCP接続を試みたが、応答がなかったということです。
原因
- データベースまたはサービスが起動していない。
- サービスは起動しているが、設定とは異なるポートで動作している。
- サービスが別のインターフェースにバインドされている(例:
127.0.0.1(IPv4)ではなく::1(IPv6))。 - ファイアウォールまたはDockerネットワークが接続をブロックしている。
- データベースの起動が完了する前にアプリが開始された(Docker Composeにおける競合状態)。
- 接続文字列または
.envファイルのホスト/ポートが間違っている。
ステップ1 — サービスが起動しているか確認する
これで90%の問題は解決します。
Linux / macOS
# 対象ポートでリッスンしているプロセスを確認
sudo ss -tlnp | grep 5432
# または
sudo lsof -i :5432
出力がない場合、サービスは停止しています。起動してください:
# PostgreSQL
sudo systemctl start postgresql
# MySQL / MariaDB
sudo systemctl start mysql
# Redis
sudo systemctl start redis
Windows
netstat -ano | findstr :5432
何も表示されない場合は、サービス管理ツール(services.msc)を開いて該当するサービスを起動するか、アプリケーション固有の起動コマンドを使用してください。
ステップ2 — 接続設定を確認する
サービスが起動している場合、アプリが正しい接続先を向いているか確認しましょう。古い.envファイルや1文字のタイポだけで接続が壊れることがあります。
# .env の例
DB_HOST=127.0.0.1
DB_PORT=5432
DB_USER=myuser
DB_PASSWORD=secret
DB_NAME=mydb
接続コードの実際の値と照合してください:
// pg (node-postgres)
const { Pool } = require('pg');
const pool = new Pool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
接続前に解決された値をログ出力して確認しましょう — 推測は禁物です:
console.log('Connecting to', process.env.DB_HOST, ':', process.env.DB_PORT);
ステップ3 — バインドアドレスを確認する(IPv4 vs IPv6)
インストール環境によっては::1(IPv6ループバック)のみにバインドされている場合がありますが、アプリは127.0.0.1(IPv4)で接続しようとします。見た目は同じに見えても、実際には全く別のソケットです。
sudo ss -tlnp | grep 5432
# *:5432 または :::5432 と表示される場合はIPv6のみです
簡単な対処法:ホストをlocalhostに変更してNode.jsに解決させるか、::1を直接指定します:
DB_HOST=localhost # Node が利用可能なインターフェースに解決します
または、postgresql.confを編集してPostgreSQLが両方のインターフェースにバインドするよう設定します:
listen_addresses = 'localhost' # 127.0.0.1 と ::1 の両方でリッスン
ステップ4 — Docker Composeの競合状態
Docker ComposeでNode.jsとデータベースを一緒に実行していますか?アプリコンテナはほぼ確実にDBの準備完了前に起動します。depends_onはここでは役に立ちません — コンテナの起動を待つだけで、PostgreSQLの起動完了は待ちません。
ヘルスチェックとcondition: service_healthyを組み合わせて解決します:
services:
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
app:
build: .
depends_on:
db:
condition: service_healthy
environment:
DB_HOST: db
DB_PORT: 5432
注意:Docker Composeでは、ホストとして127.0.0.1ではなくサービス名(db)を使用してください。
ステップ5 — アプリにリトライロジックを追加する
ECONNREFUSEDが1回発生しただけでプロセス全体を終了させるべきではありません。リトライループを組み込みましょう — 約15行で書けて、オンコール対応の手間を大幅に省けます:
const { Pool } = require('pg');
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
async function connectWithRetry(retries = 5, delay = 2000) {
for (let i = 0; i setTimeout(r, delay));
}
}
throw new Error('Could not connect to database after multiple retries');
}
connectWithRetry();
動作確認
アプリ全体を再起動する前に、TCPレベルで接続が正常か確認しましょう:
# TCP接続を直接テスト
nc -zv 127.0.0.1 5432
# 期待される結果: Connection to 127.0.0.1 5432 port [tcp/postgresql] succeeded!
# PostgreSQL: ログインテスト
psql -h 127.0.0.1 -p 5432 -U myuser -d mydb -c 'SELECT 1;'
# MySQL:
mysql -h 127.0.0.1 -P 3306 -u myuser -p mydb -e 'SELECT 1;'
# Redis:
redis-cli -h 127.0.0.1 -p 6379 ping
# 期待される結果: PONG
ポート別クイックリファレンス
5432— PostgreSQL:sudo systemctl start postgresql3306— MySQL/MariaDB:sudo systemctl start mysql6379— Redis:sudo systemctl start redis27017— MongoDB:sudo systemctl start mongod
補足情報
コンテナやカスタムネットワーク環境で問題が発生していますか?ToolCraftのSubnet Calculatorを使えば、CIDRレンジを確認し、コンテナIPが期待するネットワーク内に収まっているか検証できます。すべてブラウザ上で動作し、データのアップロードは不要です。

