我正在尝试使用docker compose在ubuntu(22.04)vm上部署应用程序。应用程序的一部分是Spring Boot映像,用于后端目的。它链接到MySQL数据库容器。在启动Spring Boot应用程序时,应用Liquibase更改日志,其中包含数据库模式和一些数据。
当在我的本地机器(macOS)上运行docker compose时,一切都很好。但是在虚拟机上运行docker compose时,会出现一系列错误消息,这些错误消息与Liquibase无法应用changelog文件有关(据我所知)。我只添加了例外,以节省整个堆栈跟踪。请参见下文。
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
ConfigServletWebServerApplicationContext :
Exception encountered during context initialization -
cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'liquibase' defined in class path resource
[org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]:
Invocation of init method failed;
nested exception is liquibase.exception.DatabaseException:
com.mysql.cj.jdbc.exceptions.CommunicationsException:
Communications link failure
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'liquibase' defined in class path resource
[org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration$LiquibaseConfiguration.class]:
Invocation of init method failed; nested exception is liquibase.exception.DatabaseException:
com.mysql.cj.jdbc.exceptions.CommunicationsException:
Communications link failure
由于提到他们是一个"通信链接故障",我的第一个想法是,这应该是一个错误的端口Map或一些IP相关的问题之间的Spring Boot容器无法连接到MySQL容器。在后一种情况下,我会想象另一个例外,虽然,提到了一些关于连接无法建立的事情。我在我的/etc/hosts文件中添加了以下行:
172.17.0.1 host.docker.internal
正如在其他帖子中提到的那样,这是"通信链接失败"错误的可能解决方案。然而,错误仍然存在,我最好的猜测是,这与Spring Boot映像缺乏实际的Liquibase更改日志信息有关。我正在尝试将此更改日志信息添加到Dockerfile中,它看起来像这样:
FROM openjdk:17-jdk-slim
WORKDIR /usr/app
ARG JAR_FILE=/build/libs/*.jar
ARG LIQUIBASE=/build/resources/main/db/
COPY $JAR_FILE .
COPY $LIQUIBASE .
ENTRYPOINT ["java", "-jar", "player-pass-backend-0.0.1-SNAPSHOT.jar"]
当运行这个Dockerfile时,在容器的工作目录中会创建一个changelog目录,其中包含liquibase changelog文件。我调整了Spring Boot应用程序的www.example.com中的liquibase类路径url,使其指向这个位置。application.properties文件如下所示:application.properties of the Spring Boot application to point to this location. The application.properties file looks like this:
spring.application.name=player-pass-backend
server.port=3001
spring.datasource.url=jdbc:mysql://host.docker.internal:3306/play_pass_db
spring.datasource.username=someuser
spring.datasource.password=somesecretpassword
spring.liquibase.change-log=classpath:changelog/db.changelog-master.xml
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
构建应用程序是通过Docker合成文件完成的:
version: "3"
services:
player-pass-database:
container_name: player-pass-db
image: mysql:8.0.32
networks:
- local_net
env_file:
- .env-database
ports:
- "3306:3306"
volumes:
- player-pass-db:/var/lib/mysql
restart: always
healthcheck:
test: ["CMD","mysqladmin","ping","-h","localhost","-uroot","-prootsecretpassword"]
interval: 5s
timeout: 5s
retries: 20
player-pass-backend:
container_name: player-pass-backend
image: jdf90/play-pass-backend
networks:
- local_net
ports:
- "3001:3001"
depends_on:
player-pass-database:
condition: service_healthy
restart: on-failure
player-pass-frontend:
container_name: player-pass-frontend
image: jdf90/play-pass
networks:
- local_net
ports:
- "5173:5173"
links:
- player-pass-backend
volumes:
player-pass-db:
networks:
local_net:
name: local_net
我希望有可能将Liquibasechangelog作为SpringBoot应用程序容器启动的一部分来应用。
另一个解决方案是建立一个单独的Liquibase容器,负责应用变更日志,但我更希望尽可能地保持本地环境和虚拟机环境的平衡。
1条答案
按热度按时间gcmastyq1#
您应该在container中正确定义数据库的地址。
如果上面的方法不起作用,那么就尝试修改你的
application.properties
,使用如下的默认链接将env变量作为第一个:有了上面的配置,它应该为您的docker env和mac env都工作。