【发布时间】:2018-08-16 01:48:05
【问题描述】:
MacOS + Docker(版本 17.12.0-ce-mac49 (21995))在这里。我正在尝试 Dockerize 现有的 Spring Boot 应用程序。这是我的Dockerfile:
FROM openjdk:8
RUN mkdir /opt/myapp
ADD build/libs/myapp.jar /opt/myapp
ADD application.yml /opt/myapp
ADD logback.groovy /opt/myapp
WORKDIR /opt/myapp
EXPOSE 9200
ENTRYPOINT ["java", "-Dspring.config=.", "-jar", "myapp.jar"]
这是我的 Spring Boot application.yml 配置文件。如您所见,它希望 Docker 从 env 文件中注入环境变量:
logging:
config: 'logback.groovy'
server:
port: 9200
error:
whitelabel:
enabled: true
spring:
cache:
type: none
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://${DB_HOST}:3306/myapp_db?useSSL=false&nullNamePatternMatchesAll=true
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
testWhileIdle: true
validationQuery: SELECT 1
jpa:
show-sql: false
hibernate:
ddl-auto: none
naming:
physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
properties:
hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
hibernate.cache.use_second_level_cache: false
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: false
hibernate.hbm2ddl.auto: validate
myapp:
detailsMode: ${DETAILS_MODE}
tokenExpiryDays:
alert: 5
jwtInfo:
secret: ${JWT_SECRET}
expiry: ${JWT_EXPIRY}
topics:
adminAlerts: admin-alerts
这是我的myapp-local.env 文件:
DB_HOST=localhost
DB_USERNAME=root
DB_PASSWORD=
DETAILS_MODE=Terse
JWT_SECRET=12345==
JWT_EXPIRY=86400000
值得注意的是,在上面的env文件中,我尝试了localhost、127.0.0.1和172.17.0.1,它们都在下面产生了相同的错误。
然后我构建容器:
docker build -t myapp .
成功!然后我运行容器:
docker run -it -p 9200:9200 --net="host" --env-file myapp-local.env --name myapp myapp
...我看到容器因 MySQL 连接相关异常而迅速死亡(无法连接到本地运行的 MySQL 机器)。我可以确认 Spring Boot 应用程序在作为 Docker 外部的可执行(“胖”)jar 运行时连接到 MySQL 没有问题,并且我可以确认本地 MySQL 实例已启动并运行并且非常健康。
Unable to connect to database. }com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:590)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:57)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:1606)
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:633)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:347)
当我打开 TRACE 级别的登录时,我看到它正在尝试连接到:
url=jdbc:mysql://localhost:3306/myapp?useSSL=false&nullNamePatternMatchesAll=true
所以 确实 看起来 Docker 正在将 env 文件的变量正确地注入到基于 Spring YAML 的配置中。所以这感觉不像是配置问题,而且是容器与 Docker 主机上运行的 MySQL 端口通信的问题。
谁能看出我哪里出错了?
【问题讨论】:
-
尝试
172.17.0.1而不是本地主机 -
谢谢@Robert (+1) 我尝试了你的建议,但得到了相同的结果。
-
mysql服务器在宿主服务器上?尝试使用服务器的ip(如果有公共ip或局域网中的ip),还要检查防火墙。并使用 --net 参数。
-
Docker for Mac 有一些known limitations。您是否尝试过按照 “用例和解决方法” 部分中的建议使用
docker.for.mac.host.internal?