К PostgreSQL не подключиться с другого контейнера или хоста: три разных отказа и что за каждым стоит

Приложение на одной виртуальной машине или в соседнем контейнере не может достучаться до базы. Сообщения об ошибке разные, и каждое указывает на свой слой.

Отказ 1: «Connection refused». До PostgreSQL вообще не дошли: на этом адресе и порту никто не слушает. По умолчанию сервер слушает только localhost (listen_addresses = 'localhost' в postgresql.conf). Для подключений с других адресов нужно listen_addresses = '*' (или конкретный адрес) и перезапуск. В контейнере проверьте проброс порта: -p 5432:5432 делает базу доступной с хоста по localhost, но соседним контейнерам нужен адрес или имя контейнера, а не localhost.

Отказ 2: «pg_hba.conf rejects connection for host …». Сеть в порядке, сервер слушает, но правило доступа для этого адреса, пользователя и базы не найдено или запрещает. В обсуждении трекера официального образа именно так падали подключения с адресов сети Docker (192.0.2.0/24x). Участники выяснили, что стартовый скрипт образа дописывает в pg_hba.conf разрешающее правило только при определённых переменных окружения, а у части пользователей файл был изменён руками или после перезапусков контейнера вёл себя нестабильно; отдельный участник поймал такое же на compose после нескольких перезапусков. Единого подтверждённого объяснения тема не получила.

Лечение всегда одно: явное правило в pg_hba.conf для нужной подсети, например host all app 192.0.2.0/24 scram-sha-256, и перезагрузка конфигурации (SELECT pg_reload_conf();). Правило «trust для всех» удобно в тесте и опасно в любой другой ситуации.

Отказ 3: «password authentication failed». Всё дошло, правило есть, не сошёлся пароль или метод. Частая причина в контейнерах: переменная с паролем действует только при первой инициализации тома; при смене переменной на уже созданном томе пароль не меняется.

Порядок проверки за две минуты.

  1. С машины приложения: nc -zv адрес 5432 (или Test-NetConnection в Windows). Нет соединения → listen_addresses, проброс порта, брандмауэр.
  2. psql -h адрес -U пользователь база: читайте текст отказа, он называет слой.
  3. На сервере: SHOW listen_addresses;, SHOW hba_file;, содержимое pg_hba.conf, журнал PostgreSQL за минуту попытки.
  4. В Docker: подключайтесь к контейнеру по имени сервиса в пользовательской сети, а не по localhost.

Статус. Разбор по типовым ошибкам и документации; в исходном обсуждении итог не подтверждён.

Формат правил описан в документации PostgreSQL.


Служебная карточка (видна только staff)

Источники (внутренний реестр): #74
Статус решения: Предложено участниками, результат не подтверждён
Дата исходного случая: разбор по открытому обсуждению в трекере официального образа PostgreSQL и по документации
Целевой аккаунт: @team_dev · Целевой раздел: dev
Хеш текста: 58d40857d5fca0bb