Ich habe eine neue Lösung für dieses Problem entwickelt, die auf einem neuen Ansatz basiert. Alle Ansätze, die ich gefunden habe, basieren auf einem Skript, das immer wieder versucht, eine Verbindung zur Datenbank herzustellen oder eine TCP-Verbindung mit dem Container herzustellen. Die vollständigen Details finden Sie im waitdb- Repository. Meine Lösung besteht jedoch darin, sich auf das aus dem Container abgerufene Protokoll zu verlassen. Das Skript wartet, bis das Protokoll die Nachricht auslöst, die für Verbindungen bereit ist . Das Skript kann feststellen, ob der Container zum ersten Mal gestartet wird. In diesem Fall wartet das Skript, bis das erste Datenbankskript ausgeführt und die Datenbank neu gestartet wurde, und wartet erneut auf eine neue verbindungsbereite Nachricht. Ich habe diese Lösung unter MySQL 5.7 und MySQL 8.0 getestet.
Das Skript selbst ( 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!"
Das Skript kann in Docker Compose oder in Docker selbst verwendet werden. Ich hoffe, die folgenden Beispiele machen die Verwendung klar:
Beispiel 01: Verwenden mit Docker Compose
SERVICE_NAME="mysql" && \
docker-compose up -d $SERVICE_NAME && \
./wait_db.sh docker-compose --no-color $SERVICE_NAME
Beispiel 02: Verwenden mit 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
Beispiel 3: Ein vollständiges Beispiel (der Testfall)
Ein vollständiges Beispiel finden Sie im Testfall des Repositorys . Dieser Testfall startet ein neues MySQL, erstellt eine Dummy-Datenbank, wartet, bis alles gestartet ist, und löst dann eine Auswahl aus , um zu überprüfen, ob alles in Ordnung ist. Danach wird der Container neu gestartet und auf den Start gewartet. Anschließend wird eine neue Auswahl ausgelöst, um zu überprüfen, ob die Verbindung hergestellt werden kann.