Imansible connettersi al contenitore docker db

attualmente sta lavorando a spostare la nostra applicazione per iniziare ad utilizzare il docker. È un'applicazione tipica con backend e frontend. Non ho problemi con la parte anteriore, mentre ancora non riesco a lanciare.

Ho il file Docker per il backend:

FROM williamyeh/java8 RUN apt-get -y update && apt-get install -y maven WORKDIR /explorerbackend ADD settings.xml /root/.m2/settings.xml ADD pom.xml /explorerbackend ADD src /explorerbackend/src RUN ["mvn", "clean", "install"] ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar RUN sh -c 'touch /explorerbackend/app.jar' ENV JAVA_OPTS="" ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /explorerbackend/app.jar" ] 

e il file Docker per mysql:

 FROM mysql ADD createDB.sql /docker-entrypoint-initdb.d 

Il motivo che sto utilizzando un file separato Docker per mysql invece di utilizzare l'image in compilatore docker è necessità di creare 2 database in fase di avvio (altrimenti il ​​backend non verrà avviato)

il file createDB.sql si presenta come:

 CREATE DATABASE IE; CREATE DATABASE IE_test; 

Ora ho file docker-compose.yml che dovrebbe avviare 2 contenitori e fare backend connettersi al database:

 version: "3.0" services: database: environment: MYSQL_ROOT_PASSWORD: root build: context: *PATH_TO_DIR_WITH_DOCKERFILE* dockerfile: Dockerfile ports: - 3306:3306 volumes: - db_data:/var/lib/mysql backend: build: context: *PATH_TO_DIR_WITH_DOCKERFILE* dockerfile: Dockerfile ports: - 3000:3000 depends_on: - database volumes: db_data: 

Quando eseguo il command docker-compose up il contenitore di database è in esecuzione mentre il backend non riesce:

 backend_1 | java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up. 

Tuttavia sono in grado di accedere al contenitore di database e vedo i database creati:

 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | IE | | IE_test | | mysql | | performance_schema | | sys | +--------------------+ 6 rows in set (0.00 sec) 

L'unico motivo che vedo potrebbe essere correlato al file di properties; yml del backend:

 app: data-base: name: IE link: database port: 3306 ................. 

Dal contenitore frontend sono in grado di eseguire il database ping (ma mi è permesso di mettere nel file di properties; solo il link: database ):

 [email protected]:/frontend# ping database PING database (172.19.0.2): 56 data bytes 64 bytes from 172.19.0.2: icmp_seq=0 ttl=64 time=0.086 ms 64 bytes from 172.19.0.2: icmp_seq=1 ttl=64 time=0.088 ms 

Quindi, suppongo che sia pingable anche dal contenitore di backend, ma perché non è in grado di connettersi al server db?

MySQL richiede alcuni secondi per avviarsi. Per confermare che si tratta di una condizione di gara, provare quanto segue:

 $ docker-compose up -d database && sleep 5 && docker-compose up 

Quando / se questo conferma la condizione di corsa, puoi alleviarla con un HEALTHCHECK sull'image del database.

Vedi: https://github.com/docker-library/healthcheck/tree/master/mysql

Script dal link sopra:

 #!/bin/bash set -eo pipefail if [ "$MYSQL_RANDOM_ROOT_PASSWORD" ] && [ -z "$MYSQL_USER" ] && [ -z "$MYSQL_PASSWORD" ]; then # there's no way we can guess what the random MySQL password was echo >&2 'healthcheck error: cannot determine random root password (and MYSQL_USER and MYSQL_PASSWORD were not set)' exit 0 fi host="$(hostname --ip-address || echo '127.0.0.1')" user="${MYSQL_USER:-root}" export MYSQL_PWD="${MYSQL_PASSWORD:-$MYSQL_ROOT_PASSWORD}" args=( # force mysql to not use the local "mysqld.sock" (test "external" connectibility) -h"$host" -u"$user" --silent ) if select="$(echo 'SELECT 1' | mysql "${args[@]}")" && [ "$select" = '1' ]; then exit 0 fi exit 1 

Alla fine, abbiamo trovato il problema che è una sorta di sorveglianza. La causa principale è stata il backfile di file:

 FROM williamyeh/java8 RUN apt-get -y update && apt-get install -y maven WORKDIR /explorerbackend ADD settings.xml /root/.m2/settings.xml ADD pom.xml /explorerbackend ADD src /explorerbackend/src RUN ["mvn", "clean", "install"] ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar RUN sh -c 'touch /explorerbackend/app.jar' ENV JAVA_OPTS="" ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /explorerbackend/app.jar" ] 

L'idea è abbastanza semplice: 1. Prendi l'image java 2. installa maven 3. copia cartella src del mio progetto dall'host 4. installa con maven nel contenitore 5. sposta il jar al workdir all'interno del contenitore 6. lancia

Tuttavia, l'opzione 5. non sembra corretto, poiché invece di copiare il file jar che è stato appena creato da un contenitore in contenitore, ho copiato dal mio host.

Il problema è stato risolto semplicemente sostituendo

 ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar 

con

 RUN cp /explorerbackend/target/explorer-backend-1.0.jar /explorerbackend/app.jar 

Grazie a Rawcode per esaminarla!