目前正在努力将我们的应用程序开始使用docker。这是一个典型的应用程序,后端和前端。我前面没有任何麻烦,但仍然无法发回。
我有后端的Docker文件:
Activity
和mysql的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文件而不是仅仅在docker-compose中使用图像的原因是必须在启动时创建2个数据库(否则后端将不会启动)
createDB.sql 文件显示为:
FROM mysql
ADD createDB.sql /docker-entrypoint-initdb.d
现在我有了docker-compose.yml文件,该文件应该启动2个容器并使后端连接到数据库:
CREATE DATABASE IE;
CREATE DATABASE IE_test;
当我运行命令docker-compose up数据库容器启动并运行时后端失败:
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:
但是我能够登录到数据库容器,我确实看到了创建的数据库:
backend_1 | java.sql.SQLNonTransientConnectionException: Could not create connection to database server. Attempted reconnect 3 times. Giving up.
我看到的唯一原因可能与后端的yml属性文件有关:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| IE |
| IE_test |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
从前端容器我可以ping数据库(但我可以将其放入属性文件中 link:database ):
app:
data-base:
name: IE
link: database
port: 3306
.................
所以,我认为它也可以从后端容器ping,但为什么它无法连接到数据库服务器呢?
答案 0 :(得分:1)
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
答案 1 :(得分:0)
最终,我们发现这个问题是一种疏忽。 根本原因是后端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创建的,而是从我的主机复制它。
问题已解决,只需更换
ADD target/explorer-backend-1.0.jar /explorerbackend/app.jar
与
RUN cp /explorerbackend/target/explorer-backend-1.0.jar /explorerbackend/app.jar
感谢Rawcode进行调查!