无法连接到数据库泊坞窗容器

目前正致力于移动我们的应用程序开始使用docker。 这是一个典型的后端和前端应用程序。 前面我没有任何麻烦,但还是不能发回。

我有后端的Docker文件:

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" ] 

和mysql的Docker文件:

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

我使用一个单独的Docker文件的原因,而不是在docker-compose中使用图像是必要的,创build2个数据库开始(否则后端将不会启动)

createDB.sql文件看起来像:

 CREATE DATABASE IE; CREATE DATABASE IE_test; 

现在我有docker-compose.yml文件,它应该启动2个容器,并使后端连接到数据库:

 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: 

当我运行命令docker-compose up数据库容器已启动并在后端失败时运行:

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

不过,我可以login到数据库容器,我看到数据库创build:

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

我看到的唯一原因可能与后端的yml属性文件有关:

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

从前端容器我可以ping数据库(但我可以把属性文件只是链接:数据库 ):

 root@897b187f9042:/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 

所以,我认为它也是从后端容器pingable,但为什么它不能连接到数据库服务器?

MySQL需要几秒钟才能启动。 为了确认这是一个竞赛条件,请尝试以下操作:

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

当/如果这确认了比赛条件,您可以通过数据库映像上的HEALTHCHECK来减轻这种情况。

请参阅: https : //github.com/docker-library/healthcheck/tree/master/mysql

上面的脚本链接:

 #!/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 

最终,我们发现这是一种疏忽的问题。 根本原因是后端dockerfile:

 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" ] 

这个想法是非常简单的:1.采取Java图像2.安装maven 3.从主机复制我的项目的src文件夹4.使用容器中的maven安装5.将jar移到容器内的workdir 6.启动它

然而,选项5看起来不正确,而不是复制jar文件,而是由容器内的maven创build的,我是从主机复制的。

问题解决了简单的replace

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

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

感谢Rawcode的调查!