Отказ в соединении означает, что контейнеры знают, как связаться друг с другом, но целевой контейнер не имеет ничего, принимающего соединения на выбранном порту. Скорее всего, это означает, что вы запускаете приложение до завершения инициализации базы данных. Я рекомендую обновить / создать приложение или создать точку входа в контейнере приложения, которая опрашивает базу данных на предмет ее работоспособности и сбоя через несколько минут, если она не запускается. Я бы также рекомендовал использовать сети, а не ссылки, поскольку ссылки устарели и не обрабатывают изящно контейнеры, которые создаются заново.
Поведение, которое вы видите, задокументировано на изображении mysql :
Нет подключений до завершения инициализации MySQL
Если при запуске контейнера база данных не инициализирована, будет создана база данных по умолчанию. Хотя это ожидаемое поведение, это означает, что он не будет принимать входящие соединения, пока такая инициализация не завершится. Это может вызвать проблемы при использовании средств автоматизации, таких как docker-compose, которые запускают несколько контейнеров одновременно.
Если приложение, которое вы пытаетесь подключить к MySQL, не обрабатывает время простоя MySQL или не ожидает, что MySQL будет запущен изящно, тогда может потребоваться установка цикла connect-retry до запуска службы. Для примера такой реализации в официальных изображениях см. WordPress или Bonita.
Из связанного примера wordpress вы можете увидеть их код повторения:
$maxTries = 10;
do {
$mysql = new mysqli($host, $user, $pass, '', $port, $socket);
if ($mysql->connect_error) {
fwrite($stderr, "\n" . 'MySQL Connection Error: (' . $mysql->connect_errno . ') ' . $mysql->connect_error . "\n");
--$maxTries;
if ($maxTries <= 0) {
exit(1);
}
sleep(3);
}
} while ($mysql->connect_error);
Пример сценария точки входа для ожидания mysql без изменения самого приложения может выглядеть следующим образом:
#!/bin/sh
wait-for-it.sh mysql:3306 -t 300
exec "$@"
wait-for-it.sh
происходит от vishnubob / wait-for-it , а exec "$@"
в конце заменяет pid 1 на команду, которую вы передали (например, bundle exec rake db:setup
). Недостатком этого подхода является то, что база данных потенциально может прослушивать порт до того, как она действительно будет готова принимать соединения, поэтому я все же рекомендую выполнить полный вход в систему с вашим приложением в цикле повторов.