首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dockerized /Java应用程序不能与本地主机对话

问Dockerized /Java应用程序不能与本地主机对话
EN

Stack Overflow用户
提问于 2018-03-07 20:33:08
回答 2查看 863关注 0票数 3

MacOS + Docker ( 17.12.0-ce-mac49 (21995)版)我正在尝试文档化一个现有的Spring应用程序。这是我的Dockerfile

代码语言:javascript
复制
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 application.yml配置文件。如您所见,它希望Docker从env文件中注入环境变量:

代码语言:javascript
复制
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文件:

代码语言:javascript
复制
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,它们在下面都会产生相同的错误。

然后我构建容器:

代码语言:javascript
复制
docker build -t myapp .

成功!然后我运行容器:

代码语言:javascript
复制
docker run -it -p 9200:9200 --net="host" --env-file myapp-local.env --name myapp myapp

...and --我看着容器很快就死掉了,MySQL连接相关的异常(不能连接到本地运行的MySQL机器)。我可以确认Spring应用程序在作为一个可执行的("fat") jar在Docker之外运行时连接到MySQL没有问题,并且我可以确认本地MySQL实例已经启动并运行,并且非常健康。

代码语言:javascript
复制
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)

当我打开跟踪级别日志时,我看到它试图连接到:

代码语言:javascript
复制
url=jdbc:mysql://localhost:3306/myapp?useSSL=false&nullNamePatternMatchesAll=true

因此,看起来Docker正确地将env文件的vars注入到基于Spring的配置中。因此,这并不像配置问题,而且容器与在Docker主机上运行的MySQL端口对话的isse。

,有人能看到我要出错的地方吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-14 13:00:48

不建议从容器中访问主机。通常,可以通过将服务包装到容器中并通过容器名称访问它来解决这个问题。

没有解决方案,只有解决办法,可以使用其中之一:

在Mac上,您可以使用docker.for.mac.host.internal DNS名称访问主机服务。

您需要像这样设置环境变量:

代码语言:javascript
复制
DB_HOST=docker.for.mac.host.internal

并引用连接字符串中的DB_HOST。

有关更多细节,见文件

从17.12开始,我们的建议是连接到专门的Mac专用DNS名称docker.for.mac.host.internal,它解析到主机使用的内部IP地址。

注意:拥有--net="host"的不允许您通过localhost到达主机。localhost总是指向本地机器,但是如果从容器中调用它,它就指向容器本身。

票数 1
EN

Stack Overflow用户

发布于 2018-03-07 21:16:22

基本上,Docker应用程序与您运行它的主机不在同一个网络中,这就是为什么您不能通过指向本地主机来访问MySQL (因为从Docker的角度来看,这是另一个网络)。您可以尝试使用--net=" host“选项运行docker,然后它将与其主机共享网络。

您可以在本主题从Docker容器内部,如何连接到机器的本地主机?中找到有关此问题的更好解释。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49160721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档