Я розробив нове рішення цього питання на основі нового підходу. Усі підходи, які я знайшов, покладаються на сценарій, який знову і знову намагається підключитися до бази даних або намагається встановити TCP-з'єднання з контейнером. Повну інформацію можна знайти у сховищі waitdb , але моє рішення полягає в тому, щоб покластись на отриманий журнал із контейнера. Сценарій чекає, поки журнал не запустить повідомлення, готове до з'єднань . Сценарій може визначити, чи контейнер запускається вперше. У цьому випадку сценарій чекає, поки початковий сценарій бази даних не буде виконаний і база даних перезапущена, знову чекаючи нового повідомлення про готовність до з'єднань . Я тестував це рішення на MySQL 5.7 та MySQL 8.0.
Сам сценарій ( wait_db.sh ):
#!/bin/bash
STRING_CONNECT="mysqld: ready for connections"
findString() {
($1 logs -f $4 $5 $6 $7 $8 $9 2>&1 | grep -m $3 "$2" &) | grep -m $3 "$2" > /dev/null
}
echo "Waiting startup..."
findString $1 "$STRING_CONNECT" 1 $2 $3 $4 $5 $6 $7
$1 logs $2 $3 $4 $5 2>&1 | grep -q "Initializing database"
if [ $? -eq 0 ] ; then
echo "Almost there..."
findString $1 "$STRING_CONNECT" 2 $2 $3 $4 $5 $6 $7
fi
echo "Server is up!"
Сценарій можна використовувати в Docker Compose або в самому Docker. Я сподіваюся, що наведені нижче приклади дозволяють зрозуміти використання:
Приклад 01: Використання з Docker Compose
SERVICE_NAME="mysql" && \
docker-compose up -d $SERVICE_NAME && \
./wait_db.sh docker-compose --no-color $SERVICE_NAME
Приклад 02: Використання з Docker
CONTAINER_NAME="wait-db-test" && \
ISO_NOW=$(date -uIs) && \
docker run --rm --name $CONTAINER_NAME \
-e MYSQL_ROOT_PASSWORD=$ROOT_PASSWORD \
-d mysql:5.7 && \
./wait_db.sh docker --since "$ISO_NOW" $CONTAINER_NAME
Приклад 3: Повний приклад (тест-кейс)
Повний приклад можна знайти на тестовому прикладі сховища . Цей тестовий приклад запустить новий MySQL, створить фіктивну базу даних, зачекає, поки все запуститься, а потім запускає select, щоб перевірити, чи все в порядку. Після цього він перезапустить контейнер і зачекає його запуску, а потім запускає новий вибір, щоб перевірити, чи готовий він до підключення.