AWS EC2, Jenkins, Docker, Spring-boot+mysql 我怀疑我的 spring.datasource.url 是错误的?
AWS EC2, Jenkins, Docker, Spring-boot+mysql I suspect my spring.datasource.url is wrong?
我是 Docker 的新手,我已经尝试了所有我能想到的方法,但已经绝望了。我真的希望你们中的一个人知道可能会发生什么。我正在开发一个项目,其中我使用 Jenkins 和 Docker.
创建了一个 CI 管道
我用 spring.datasource.url 尝试了很多东西。
- 使用名称 'db' 因为这是服务在 docker-compose.yml
中的名称
- 使用 grep 查找我的 docker0 服务、我的 docker 容器等的 IP 地址
- 按原样尝试本地主机
- 尝试在 docker-compose 文件中使用不同的环境变量。 (使用用户名和密码,而不是使用它。)
- 正在尝试环境变量。我不记得确切的格式,但它是这样的:jdbc:mysql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}? createDatabaseIfNotExist=true&useSSL=false
- 正在尝试在 EC2 机器上安装 mysql。
- 许多其他事情(今晚尝试 30 次,昨晚大约 60 次)。如果它在 Whosebug 上,我可能试过了。
作为一个菜鸟,我很可能只是不知道一些非常基本的东西。老实说,我要放弃了,只是尝试 运行 使用 H2 数据库。我希望这会更容易工作,但我仍然抱有一丝希望这可能会有所帮助。
我的项目在我的 spring.datasource.url.
中使用 localhost 在我的本地计算机上运行
localhost success on mysql
然而,在 EC2 上,我得到了 'refused to connect' 错误的变体。
docker sad times
在 spring-boot 中我得到类似的错误:
- 如果我尝试在主机的连接字符串中使用硬编码名称:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source) ~[na:na]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.NativeSession.connect(NativeSession.java:120) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
... 57 common frames omitted
Caused by: java.net.UnknownHostException: db
at java.base/java.net.InetAddress$CachedAddresses.get(Unknown Source) ~[na:na]
at java.base/java.net.InetAddress.getAllByName0(Unknown Source) ~[na:na]
at java.base/java.net.InetAddress.getAllByName(Unknown Source) ~[na:na]
at java.base/java.net.InetAddress.getAllByName(Unknown Source) ~[na:na]
at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:133) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
... 60 common frames omitted
我得到的最接近的是在主机插槽中使用类似于此的 IP 地址:
jdbc:mysql://172.17.0.0:3306/foodboxdb?createDatabaseIfNotExist=true&useSSL=false
我尝试了 172.17.0.0、172.18.0.2、172.18.0.3,根据我所知道的一点寻找:
using docker inspect
route on the ec2 root
此方法会超时,因此再次失败 - 但不会像其他方法那样给出明显的失败错误,提示密码错误或主机错误。
我确实找到了一条评论,说有人像这样更改了他们的 运行 命令:
java -Dspring.profiles.active=dockerembbed,oauth-security -jar myapp.jar
但是我的命令格式非常不同,我不能 100% 确定如何尝试将该命令放入我的 Docker 文件中。这就是我现在拥有的:
ENTRYPOINT ["java","-jar","foodbox-service-rest-0.0.1-SNAPSHOT.jar"]
如果有人知道此人使用 -Dspring.profiles.active=dockerembbed
命令做什么以及将其放入 ENTRYPOINT 命令的正确方法,我很乐意看到它。
无论如何,下面是我的代码。我很确定这是所有相关的东西。我的 github 仓库在这里:https://github.com/samparsons/pg6-backend
提前谢谢您 - 我真的不确定现在还能尝试什么!
我的 application.properties 文件如下所示:
# Application Properties
server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/foodoxdb?createDatabaseIfNotExist=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.defer-datasource-initialization=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database=mysql
spring.jpa.show-sql=true
我的 Jenkinsfile 看起来像这样:
pipeline {
agent any
triggers {
pollSCM('* * * * *')
}
stages {
stage('Docker compose build') {
steps {
echo '----------------- This is a docker-compose phase ----------'
sh 'docker-compose up -d --force-recreate --remove-orphans --build'
}
}
}
}
我的 docker-compose.yml 文件如下所示:
version: '3.8'
services:
db:
image: mysql:8
environment:
- MYSQL_ROOT_PASSWORD=
- MYSQL_DATABASE=foodboxdb
- MYSQL_USER=root
- MYSQL_PASSWORD=pw
restart: always
ports:
- 3306:3306
volumes:
- foodboxdb:/var/lib/mysql
foodbox-service-rest:
container_name: foodbox-service-rest
restart: on-failure
image: foodbox-service-rest
build:
context: ./
dockerfile: Dockerfile
depends_on:
- db
ports:
- 8081:8081
environment:
- DATABASE_HOST=db
- DATABASE_USER=root
- DATABASE_PASSWORD=pw
- DATABASE_NAME=foodboxdb
- DATABASE_PORT=3306
volumes:
foodboxdb:
最后我的 Docker 文件如下所示:
# code below is from medium tutorial by Wynn Teo,
https://medium.com/geekculture/dockerizing-a-spring-boot-application-with-maven-122286e9f582
# it has been modified slightly for my use case.
# AS <NAME> to name this stage as maven
FROM maven:3.6.3 AS maven
RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
EXPOSE 8081
EXPOSE 3306
WORKDIR /usr/src/app
COPY . /usr/src/app
# Compile and package the application to an executable JAR
RUN mvn package -DskipTests
RUN echo "running in root"
RUN ls
RUN echo "running in /usr/src/app"
RUN ls /usr/src/app
RUN echo "running in /usr/src/app/target"
RUN ls /usr/src/app/target
# For Java 11,
FROM adoptopenjdk/openjdk11:alpine-jre
ARG JAR_FILE=foodbox-service-rest-0.0.1-SNAPSHOT.jar
WORKDIR /opt/app
# Copy the foodbox-service-rest-0.0.1-SNAPSHOT.jar from the maven stage to the /opt/app directory of the current stage.
COPY --from=maven /usr/src/app/target/${JAR_FILE} /opt/app/
ENTRYPOINT ["java","-jar","foodbox-service-rest-0.0.1-SNAPSHOT.jar"]
我让它工作了。这是我为解决这个问题所做的工作。
- 确保 docker-compose 运行 我想要 运行 的服务。如果您定义需要 运行 的服务,它将首先创建所有依赖项。所以,我改变了我的命令
docker-compose up -d --force-recreate --remove-orphans --build
至
docker-compose up -d --force-recreate --remove-orphans --build <PUT_SERVICE_NAME_HERE>
这是我在 docker-compose 帮助文档中阅读的内容,它给了我这个提示:https://docs.docker.com/compose/compose-file/compose-file-v2/#depends_on
- 执行此操作后,我注意到在 运行 宁
docker ps -a
观察我的容器状态时我遇到了一个新问题 - 我的数据库不断重启。显然,如果数据库关闭,该服务将无法运行。因此,为了排除故障,我发现您可以使用以下命令获取 Docker 中的容器日志:docker logs -f <db_container_name>
使用这个命令,我能够弄清楚如何为我的数据库设置“让它工作”。请注意 - 不要复制我的环境设置,这太糟糕了!我真的只需要它工作,这样我就可以完成我的项目。由于这是针对学校的,他们并没有诚实地对安全性甚至最佳实践进行评分(这个程序充其量是有问题的!)。
- 最后,一旦数据库开始工作,我就切换回这里显示的格式
对于我的 spring.datasource.url:
jdbc:mysql://db:3306/foodboxdb?createDatabaseIfNotExist=true&useSSL=false
使用 db 作为数据库名称,这是我在 docker-compose.yml 文件中启动的 db 服务的名称。
根据上述注意事项,请随意重用我的存储库。
我是 Docker 的新手,我已经尝试了所有我能想到的方法,但已经绝望了。我真的希望你们中的一个人知道可能会发生什么。我正在开发一个项目,其中我使用 Jenkins 和 Docker.
创建了一个 CI 管道我用 spring.datasource.url 尝试了很多东西。
- 使用名称 'db' 因为这是服务在 docker-compose.yml 中的名称
- 使用 grep 查找我的 docker0 服务、我的 docker 容器等的 IP 地址
- 按原样尝试本地主机
- 尝试在 docker-compose 文件中使用不同的环境变量。 (使用用户名和密码,而不是使用它。)
- 正在尝试环境变量。我不记得确切的格式,但它是这样的:jdbc:mysql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}? createDatabaseIfNotExist=true&useSSL=false
- 正在尝试在 EC2 机器上安装 mysql。
- 许多其他事情(今晚尝试 30 次,昨晚大约 60 次)。如果它在 Whosebug 上,我可能试过了。
作为一个菜鸟,我很可能只是不知道一些非常基本的东西。老实说,我要放弃了,只是尝试 运行 使用 H2 数据库。我希望这会更容易工作,但我仍然抱有一丝希望这可能会有所帮助。
我的项目在我的 spring.datasource.url.
中使用 localhost 在我的本地计算机上运行localhost success on mysql
然而,在 EC2 上,我得到了 'refused to connect' 错误的变体。
docker sad times
在 spring-boot 中我得到类似的错误:
- 如果我尝试在主机的连接字符串中使用硬编码名称:
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source) ~[na:na]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:89) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.NativeSession.connect(NativeSession.java:120) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:948) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:818) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
... 57 common frames omitted
Caused by: java.net.UnknownHostException: db
at java.base/java.net.InetAddress$CachedAddresses.get(Unknown Source) ~[na:na]
at java.base/java.net.InetAddress.getAllByName0(Unknown Source) ~[na:na]
at java.base/java.net.InetAddress.getAllByName(Unknown Source) ~[na:na]
at java.base/java.net.InetAddress.getAllByName(Unknown Source) ~[na:na]
at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:133) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:63) ~[mysql-connector-java-8.0.27.jar!/:8.0.27]
... 60 common frames omitted
我得到的最接近的是在主机插槽中使用类似于此的 IP 地址:
jdbc:mysql://172.17.0.0:3306/foodboxdb?createDatabaseIfNotExist=true&useSSL=false
我尝试了 172.17.0.0、172.18.0.2、172.18.0.3,根据我所知道的一点寻找:
using docker inspect
route on the ec2 root
此方法会超时,因此再次失败 - 但不会像其他方法那样给出明显的失败错误,提示密码错误或主机错误。
我确实找到了一条评论,说有人像这样更改了他们的 运行 命令:
java -Dspring.profiles.active=dockerembbed,oauth-security -jar myapp.jar
但是我的命令格式非常不同,我不能 100% 确定如何尝试将该命令放入我的 Docker 文件中。这就是我现在拥有的:
ENTRYPOINT ["java","-jar","foodbox-service-rest-0.0.1-SNAPSHOT.jar"]
如果有人知道此人使用 -Dspring.profiles.active=dockerembbed
命令做什么以及将其放入 ENTRYPOINT 命令的正确方法,我很乐意看到它。
无论如何,下面是我的代码。我很确定这是所有相关的东西。我的 github 仓库在这里:https://github.com/samparsons/pg6-backend
提前谢谢您 - 我真的不确定现在还能尝试什么!
我的 application.properties 文件如下所示:
# Application Properties
server.port=8081
spring.datasource.url=jdbc:mysql://localhost:3306/foodoxdb?createDatabaseIfNotExist=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.defer-datasource-initialization=true
spring.jpa.hibernate.ddl-auto=create
spring.jpa.database=mysql
spring.jpa.show-sql=true
我的 Jenkinsfile 看起来像这样:
pipeline {
agent any
triggers {
pollSCM('* * * * *')
}
stages {
stage('Docker compose build') {
steps {
echo '----------------- This is a docker-compose phase ----------'
sh 'docker-compose up -d --force-recreate --remove-orphans --build'
}
}
}
}
我的 docker-compose.yml 文件如下所示:
version: '3.8'
services:
db:
image: mysql:8
environment:
- MYSQL_ROOT_PASSWORD=
- MYSQL_DATABASE=foodboxdb
- MYSQL_USER=root
- MYSQL_PASSWORD=pw
restart: always
ports:
- 3306:3306
volumes:
- foodboxdb:/var/lib/mysql
foodbox-service-rest:
container_name: foodbox-service-rest
restart: on-failure
image: foodbox-service-rest
build:
context: ./
dockerfile: Dockerfile
depends_on:
- db
ports:
- 8081:8081
environment:
- DATABASE_HOST=db
- DATABASE_USER=root
- DATABASE_PASSWORD=pw
- DATABASE_NAME=foodboxdb
- DATABASE_PORT=3306
volumes:
foodboxdb:
最后我的 Docker 文件如下所示:
# code below is from medium tutorial by Wynn Teo,
https://medium.com/geekculture/dockerizing-a-spring-boot-application-with-maven-122286e9f582
# it has been modified slightly for my use case.
# AS <NAME> to name this stage as maven
FROM maven:3.6.3 AS maven
RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
EXPOSE 8081
EXPOSE 3306
WORKDIR /usr/src/app
COPY . /usr/src/app
# Compile and package the application to an executable JAR
RUN mvn package -DskipTests
RUN echo "running in root"
RUN ls
RUN echo "running in /usr/src/app"
RUN ls /usr/src/app
RUN echo "running in /usr/src/app/target"
RUN ls /usr/src/app/target
# For Java 11,
FROM adoptopenjdk/openjdk11:alpine-jre
ARG JAR_FILE=foodbox-service-rest-0.0.1-SNAPSHOT.jar
WORKDIR /opt/app
# Copy the foodbox-service-rest-0.0.1-SNAPSHOT.jar from the maven stage to the /opt/app directory of the current stage.
COPY --from=maven /usr/src/app/target/${JAR_FILE} /opt/app/
ENTRYPOINT ["java","-jar","foodbox-service-rest-0.0.1-SNAPSHOT.jar"]
我让它工作了。这是我为解决这个问题所做的工作。
- 确保 docker-compose 运行 我想要 运行 的服务。如果您定义需要 运行 的服务,它将首先创建所有依赖项。所以,我改变了我的命令
docker-compose up -d --force-recreate --remove-orphans --build
至
docker-compose up -d --force-recreate --remove-orphans --build <PUT_SERVICE_NAME_HERE>
这是我在 docker-compose 帮助文档中阅读的内容,它给了我这个提示:https://docs.docker.com/compose/compose-file/compose-file-v2/#depends_on - 执行此操作后,我注意到在 运行 宁
docker ps -a
观察我的容器状态时我遇到了一个新问题 - 我的数据库不断重启。显然,如果数据库关闭,该服务将无法运行。因此,为了排除故障,我发现您可以使用以下命令获取 Docker 中的容器日志:docker logs -f <db_container_name>
使用这个命令,我能够弄清楚如何为我的数据库设置“让它工作”。请注意 - 不要复制我的环境设置,这太糟糕了!我真的只需要它工作,这样我就可以完成我的项目。由于这是针对学校的,他们并没有诚实地对安全性甚至最佳实践进行评分(这个程序充其量是有问题的!)。 - 最后,一旦数据库开始工作,我就切换回这里显示的格式
对于我的 spring.datasource.url:
jdbc:mysql://db:3306/foodboxdb?createDatabaseIfNotExist=true&useSSL=false
使用 db 作为数据库名称,这是我在 docker-compose.yml 文件中启动的 db 服务的名称。
根据上述注意事项,请随意重用我的存储库。