我有连接到mysql数据库的spring boot应用程序。如果我以经典方式在本地运行它,则效果很好。但是,当我尝试对其进行dockerise时-数据库成功启动,但应用程序看不到数据库。
我的Dockerfile:
FROM openjdk:11-jdk-slim
ADD start-local.sh /start-local.sh
RUN chmod +x start-local.sh
ENTRYPOINT [ "sh", "-c", "./start-local.sh" ]
我的start-local.sh(我添加了它,以便我的应用程序等待数据库启动):
#!/bin/sh
echo "Waiting for the database server to start"
echo "********************************************************"
apt-get update && apt-get install -y netcat
while ! nc -z mysql 3306; do sleep 3; done
echo "******** Database Server has started"
echo "Starting account service"
java -jar /mnt/service-2.4.0.jar
最后是我的docker-compose.yml文件:
version: '2'
services:
mysql:
image: mysql:5.7.23
environment:
- MYSQL_ROOT_PASSWORD=root
entrypoint:
sh -c "echo 'CREATE DATABASE IF NOT EXISTS books; CREATE DATABASE IF NOT EXISTS notifications' > /docker-entrypoint-initdb.d/init.sql;/usr/local/bin/docker-entrypoint.sh --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --sql_mode="""
ports:
- "3306:3306"
account_app:
image: service_img
environment:
- "SPRING_PROFILES_ACTIVE=local"
ports:
- "8083:8083"
volumes:
- "/build/libs/:/mnt"
我执行的操作:
| 2019-09-23 09:51:14.006调试[帐户服务,,,] 286 --- [
main] c.m.l.c.c.d.p.DatasourceConfiguration:创建数据源
account_app_1 | 2019-09-23 09:51:14.014 INFO [帐户服务,,,] 286 --- [main] com.zaxxer.hikari.HikariDataSource: HikariPool-1-正在启动... account_app_1 | 2019-09-23 09:51:15.222 错误[帐户服务,,] 286 --- [main] com.zaxxer.hikari.pool.HikariPool:HikariPool-1-异常 在池初始化期间。 account_app_1 | account_app_1 | com.mysql.cj.jdbc.exceptions.CommunicationsException:通讯 链接失败account_app_1 | account_app_1 |最后发送的数据包 成功到服务器的时间是0毫秒前。司机还没有 从服务器接收到任何数据包。 account_app_1 |在 com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl。(ConnectionImpl.java:455) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15]发送的最后一个数据包 成功到服务器的时间是0毫秒前。司机还没有 从服务器接收到任何数据包。 account_app_1 |在 com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl。(ConnectionImpl.java:455) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136) 〜[HikariCP-3.2.0.jar!/:na] account_app_1 |在 com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369) 〜[HikariCP-3.2.0.jar!/:na] account_app_1 |在 com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198) 〜[HikariCP-3.2.0.jar!/:na] account_app_1 |在 com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467) 〜[HikariCP-3.2.0.jar!/:na] account_app_1 |在 com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541) 〜[HikariCP-3.2.0.jar!/:na] account_app_1 | ... 206共 框架省略account_app_1 |造成原因: com.mysql.cj.exceptions.CJCommunicationsException:通信链接 失败account_app_1 | account_app_1 |最后发送的数据包 成功到服务器的时间是0毫秒前。司机还没有 从服务器接收到任何数据包。 account_app_1 |在 java.base / jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native 方法)〜[na:na] account_app_1 |在 java.base / jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 〜[na:na] account_app_1 |在 java.base / jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 〜[na:na] account_app_1 |在 java.base / java.lang.reflect.Constructor.newInstance(Constructor.java:490) 〜[na:na] account_app_1 |在 com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.NativeSession.connect(NativeSession.java:152) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:955) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |
...省略了214个常见框架account_app_1 |造成原因: java.net.ConnectException:连接被拒绝(连接被拒绝) account_app_1 |在 java.base / java.net.PlainSocketImpl.socketConnect(本机方法) 〜[na:na] account_app_1 |在 java.base / java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399) 〜[na:na] account_app_1 |在 java.base / java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242) 〜[na:na] account_app_1 |在 java.base / java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224) 〜[na:na] account_app_1 |在 java.base / java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403) 〜[na:na] account_app_1 |在 java.base / java.net.Socket.connect(Socket.java:591)〜[na:na] account_app_1 |在 com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:155) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |在 com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65) 〜[mysql-connector-java-8.0.15.jar!/:8.0.15] account_app_1 |
...省略了217个通用框架account_app_1 |
有什么建议吗?
答案 0 :(得分:1)
运行组合“堆栈”时,docker使用其自己的DNS机制。
这意味着,如果您在account_app
容器内对主机名mysql
执行DNS查询,则查询将返回名为mysql
的容器的IP地址(可能前缀为堆栈名称)
简而言之:将您的Spring应用程序配置为连接到不在localhost上但在mysql
上的mysql数据库,
您可能可以设置一些环境变量来配置它。
答案 1 :(得分:0)
对端口映射有一个误解:您将所有流量从主机端口3306传递到容器端口3306,但这不是双向的。
要处理您的情况,如果您使用的是Linux(在Windows和Mac上不起作用),则可以在docker-compose.yml中添加此配置,以允许容器使用主机服务。
network_mode: "host"
否则,您可以将本地MySql设置为接受来自外部IP的连接,并将容器数据库指向您的IP地址。
请注意,此解决方案仅在本地开发计算机上才能正常工作,我强烈建议在任何生产环境中都避免这种情况。
答案 2 :(得分:0)
我认为您使用“ localhost”作为mysql服务器主机名,
jdbc:mysql://localhost:3306
尝试将其更改为
jdbc:mysql://host.docker.internal:3306
您不能在docker容器内进行localhost。 最好的方法是将jdbc url作为环境变量传递。
SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3306/code_master
请检查此sh文件的最后5行https://github.com/keaz/code_master/blob/develop/build_docker.sh