Звучит как базовый навык, однако похоже, что API Docker и/или PosgreSQL сильно изменился, поэтому многие команды, которые я гуглил, больше не работают. Итак, начнем со списка версий.
Client: Docker Engine - Community
Version: 25.0.4
API version: 1.44
Go version: go1.21.8
Git commit: 1a576c5
Built: Wed Mar 6 16:32:12 2024
OS/Arch: linux/amd64
Context: default
Что касается Posgres, то изображение postgres
должно быть последним за апрель 2024 года, а именно 16.2.
Скорее всего, для данной темы служба frontserver не имеет значения, но я ее оставил на всякий случай.
version: "3.5"
services:
Database:
image: postgres
container_name: Example-Production-Database
ports: [ "${DATABASE_PORT}:${DATABASE_PORT}" ]
environment:
- POSTGRES_PASSWORD=${DATABASE_PASSWORD}
volumes:
- DatabaseData:/data/example.jp
volumes:
DatabaseData: {}
Postgres требует переменную среды POSTGRES_PASSWORD
, но Docker обнаруживает файл .env
, поэтому я сослался на переменную среды DATABASE_PASSWORD
.
Предположим, что правильный пароль — ACTUAL_PASSWORD
.
DATABASE_ENVIRONMENT_NAME = "STAGING"
DATABASE_HOST = "Database"
DATABASE_PORT = "5432"
DATABASE_USER_NAME = "postgres"
DATABASE_PASSWORD = "ACTUAL_PASSWORD"
sudo docker compose up --build
Поскольку мое приложение должно быть запущено на VPS, хост не является «локальным хостом» — это должен быть IP-адрес VPS, которым я не могу поделиться.
Пытаюсь связаться с ACTUAL_PASSWORD
:
Выход:
Example-Production-Database | 2024-04-07 01:08:24.202 UTC [93] FATAL: password authentication failed for user "postgres"
Example-Production-Database | 2024-04-07 01:08:24.202 UTC [93] DETAIL: Connection matched file "/var/lib/postgresql/data/pg_hba.conf" line 128: "host all all all scram-sha-256"
Может быть пароль установлен не правильно?
К сожалению, если попробовать дефолтный pass1234
, ничего не изменится.
Что я пропустил?
Поэтому убедитесь, что вы не запускаете контейнер на уже существующем томе.
@RabbanKeyak Спасибо за совет. Перед каждым экспериментом я выполняю sudo docker system prune -a
, а затем удаляю все объемы на sudo docker volume rm [VOLUME_NAME1] [VOLUME_NAME2] ... [VOLUME_NAME_N]
. Потому что судя по sudo docker volume list
объемов не осталось, полагаю, я следую вашему совету.
хорошо, если так, одной проблемой меньше.
Переменная среды POSTGRES_PASSWORD
используется для установки пароля.
У меня нет доступа к какой-либо информации вашего front_server
сервиса, но я подменю test
сервис, который будет подключаться к базе данных.
version: "3.5"
services:
Database:
image: postgres
container_name: Example-Production-Database
ports:
- "${DATABASE_PORT}:${DATABASE_PORT}"
environment:
- POSTGRES_USER=${DATABASE_USER_NAME}
- POSTGRES_PASSWORD=${DATABASE_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -d postgres -U ${DATABASE_USER_NAME}"]
interval: 5s
timeout: 5s
retries: 5
test:
image: postgres
environment:
- PGPASSWORD=${DATABASE_PASSWORD}
command: sh -c "psql -h Database -U ${DATABASE_USER_NAME} -c 'SELECT * from pg_user;'"
depends_on:
Database:
condition: service_healthy
Служба test
подключится к базе данных и затем выполнит запрос SELECT * from pg_user;
.
Важным аспектом этой настройки является то, что служба test
ожидает, пока база данных станет «работоспособной». А база данных, в свою очередь, будет «здоровой» только тогда, когда она будет готова принимать соединения. Это важно, иначе сервис test
попытается подключиться до того, как база данных будет готова. Моя гипотеза: это проблема вашего существующего стека.
На скриншоте ниже вы можете увидеть:
test
и.env
).Спасибо за ответ! Ваше решение я проверю завтра, но сейчас мне нужно сообщить, что я попробовал подключение с локального ПК (мой скриншот именно об этом). Полагаю, если нормальное подключение с локального ПК не работает, то и с front_server подключиться не получится. Кроме того, я добавлю FrontServer.Dockerfile
, на который ссылается front_server
.
Благодаря предоставленной мной настройке вы сможете подключаться как с хост-компьютера (вашего «локального ПК»), так и с другой службы Docker Compose. Пожалуйста, попробуйте мою настройку и убедитесь, что она работает для вас. Тогда мы сможем перейти на использование вашего оригинала front_service
.
Извините, что заставил вас ждать. Я удалил front_server
из docker-compose
и повторил эксперименты. Кроме того, я добавил проверку работоспособности в свой docker-compose.yml и получил тот же результат, что и на вашем снимке экрана. К сожалению, мне так и не удалось подключиться к базе данных с локального ПК по IP-адресу VPS, порту 5432, имени пользователя и паролю, которые я не смог опубликовать. Что мне нужно проверить дальше? Может быть postgres
имеет значение? Мне удалось сделать подобное подключение на другом VPS, не трогая postgresql.conf
раньше, но, возможно, API изменился...
Благодаря этой настройке вы сможете подключаться с хоста, используя psql -h 127.0.0.1 -p 5432 -U postgres
. Хост базы данных — 127.0.0.1 (он работает на локальном хосте), поэтому вам следует подключиться к этому IP-адресу. Вы пытаетесь подключиться с того же компьютера, на котором работает стек Docker Compose?
Я попытался запустить эту команду и получил ошибку «Ошибка аутентификации пароля для пользователя postgres» как с фактическим паролем, указанным в .env
, так и с паролем по умолчанию (pass1234
). Хм, что это может быть? Недостаточно просто указать POSTGRES_PASSWORD
в docker-compose.yml
. Или, если пароль содержит запрещенные символы, почему не было выдано ошибки?
Я нашел причину. В пароле были просто запрещенные символы, но никакой ошибки не было . Кроме того, похоже, что разрешенные символы не задокументированы. Согласно этому, следующие символы не допускаются: %
, &
, @
, +
, ^
. В моем пароле их нет, но есть -
, ~
, *
, #
, '
, _
, |
, !
и >
. Хорошо, спасибо за помощь. Я принял и проголосовал за ваш ответ.
Не забывайте, что если на томе уже существует база данных (
DatabaseData
в вашем случае) на момент запуска контейнера, то параметрыPOSTGRES_USER
,POSTGRES_PASSWORD
иPOSTGRES_DATABASE
будут игнорироваться. Другими словами, вы не можете изменить логин и пароль (используяPOSTGRES_USER
иPOSTGRES_PASSWORD
) и не можете создать новую базу данных (используяPOSTGRES_DATABASE
) после завершения инициализации базы данных, это возможно только до инициализации базы данных (когда база данных не существует, сначала запустите ).