通过Dockerfile上的Gradle映像触发后,Jooq无法找到数据库 [英] Jooq unable to find database when triggered via a gradle image on Dockerfile

查看:102
本文介绍了通过Dockerfile上的Gradle映像触发后,Jooq无法找到数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Dockerfile,它使用gradle构建我的Spring启动应用程序,就在将其处理到容器中并触发它之前。看起来是这样的:

I have a Dockerfile that uses gradle to build my Spring boot application just before coping it into the container and trigger it. This is how it looks:

FROM gradle:5.4.1-jdk8-alpine AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon

FROM openjdk:8-jdk-alpine
EXPOSE 8080
RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/*.jar yurlapp.jar
ENTRYPOINT ["java","-jar" , "/yurlapp.jar"]

这很简单,它将执行Gradle并且jar将是添加到Docker容器中。到现在为止还挺好。一旦提供了数据库,该Dockerfile便会在docker-compose.yml中使用(应用需要使用DB)。 docker-compose.yml就是这样的:

It's quite simple, it will execute Gradle and the jar will be added into the docker container. So far so good. This Dockerfile will be used inside a docker-compose.yml once the database is provided(the DB is required for the app to work). This is how that docker-compose.yml looks like:

version: '2.1'
services:
  yurldb:
    image: postgres:11
    container_name: yurldb
    networks:
      - yunet
    ports:
      - 5432:5432
    environment:
      - POSTGRES_DB=yurldb
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=somepassword
    volumes:
      - ./init.sql:/docker-entrypoint-initdb.d/
      - yudata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 10s
      retries: 5
  flyway:
    image: boxfuse/flyway
    command: -url=jdbc:postgresql://yurldb:5432/yurldb -schemas=public -user=postgres -password=somepassword migrate
    networks:
      - yunet
    volumes:
      - .:/flyway/sql
    depends_on:
      yurldb:
        condition: service_healthy
  yurlapp:
    container_name: yurlapp
    image: javing/yurlapp:0.0.1
    build:
      context: .
      dockerfile: Dockerfile
    networks:
      - yunet
    ports:
      - 8080:8080
    environment:
      - DB_HOST=yurldb #the name of the DB container is used as url
    depends_on:
      yurldb:
        condition: service_healthy
      flyway:
        condition: service_healthy
networks:
  yunet:
volumes:
  yudata:

如您所见,应用程序图像一旦数据库映像准备好,并且在flyway执行迁移之后,最后一次构建。我在构建应用程序时发生的问题。
因此,一旦gradle开始,它将做所有要做的事情。但是在某一时刻,它需要Jooq根据数据库上的现有表自动生成一些类。在这里出了点问题。该版本会爆炸并告诉我:

As you can see the app image be built last, once the database image is ready and also after flyway performs the migrations. The problem that I have happens during the building of the app. So once gradle starts it will do all it has to do. But at one point it requires Jooq, to autogenerate some classes based on the existing tables on the database. And in here something goes wrong. The build blows up and tells me this:


任务:generateSampleJooqSchemaSource失败

Task :generateSampleJooqSchemaSource FAILED



FAILURE: Build failed with an exception.

* Where:
Build file '/home/gradle/src/build.gradle' line: 81

* What went wrong:
Execution failed for task ':generateSampleJooqSchemaSource'.
> jOOQ source code generation failed:

  Jun 01, 2020 7:37:39 PM org.jooq.tools.JooqLogger info
  INFO: Initialising properties  : /home/gradle/src/build/tmp/generateSampleJooqSchemaSource/config.xml
  Jun 01, 2020 7:37:39 PM org.jooq.tools.JooqLogger error
  SEVERE: Cannot read /home/gradle/src/build/tmp/generateSampleJooqSchemaSource/config.xml. Error : Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
  org.postgresql.util.PSQLException: Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:285)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:211)
    at org.postgresql.Driver.makeConnection(Driver.java:459)
    at org.postgresql.Driver.connect(Driver.java:261)
    at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:342)
    at org.jooq.codegen.GenerationTool.run(GenerationTool.java:221)
    at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:216)
    at org.jooq.codegen.GenerationTool.main(GenerationTool.java:188)
  Caused by: java.net.ConnectException: Connection refused (Connection refused)
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at org.postgresql.core.PGStream.<init>(PGStream.java:81)
    at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:93)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:197)
    ... 8 more

它说它无法连接到数据库。这是为什么?这是我在build.gradle文件中拥有的Jooq配置

It says that it can't connect to the database. Why is that? This is the Jooq configuration I have in my build.gradle file

jooq {
    sample(sourceSets.main) {
        jdbc {
            driver = 'org.postgresql.Driver'
            url = 'jdbc:postgresql://localhost:5432/yurldb'
            user = 'postgres'
            password = 'somepassword'
        }
        generator {
            database() {
                name = 'org.jooq.meta.postgres.PostgresDatabase'
                inputSchema = 'public'
                includes = '.*'
            }
            target {
                packageName = 'com.javing.yurl'
                directory = 'build/generated/java'
            }
        }
    }
}

tasks.generateSampleJooqSchemaSource.with {
    def out = new ByteArrayOutputStream()
    javaExecSpec = { JavaExecSpec s ->
        s.standardOutput = out
        s.errorOutput = out
        s.ignoreExitValue = true
        s.jvmArgs '-Xmx512M'
    }
    execResultHandler = { ExecResult r ->
        if (r.exitValue != 0) {
            throw new RuntimeException('jOOQ source code generation failed:\n\n' + out.toString())
        }
    }
}

我很困惑,我不确定我明白什么是发生。如果我要使用docker-compose单独启动数据库映像,然后从终端手动运行gradle(而不是docker的gradle),则将毫无问题地生成这些类。因此,我不知道何时在Dockerfile中使用gradle时,Jooq无法找到数据库。任何的想法?
我是否还需要以某种方式从Dockerfile触发Jooq,就像触发gradle一样?有人可以帮我吗,我有点卡住了。

I am very confused, I am not sure I understand what is happening. If I was to use docker-compose to just boot the database image just by itself and then I run gradle manually from my terminal(not the gradle from docker), those classes will be generated without problem. So I don't know when the gradle is used from the Dockerfile Jooq fails to find the DB. Any idea? Do i also need to trigger Jooq maybe from the Dockerfile somehow, in the same way that I triggered gradle? Can someone help me with this please, I am a bit stuck.

更新
我试图在jooq配置中更改网址使用yurldb而不是localhost,因为也许在容器内部联网时,URL重绘为容器的名称,但这没有用。这是怎么回事:

Update I tried changing the url in the jooq config to use yurldb instead of localhost since maybe when networking inside the container the url resloves to the name of the container, but that didn't work. What happens is this:

FAILURE: Build failed with an exception.

* Where:
Build file '/home/gradle/src/build.gradle' line: 81

* What went wrong:
Execution failed for task ':generateSampleJooqSchemaSource'.
> jOOQ source code generation failed:

  Jun 01, 2020 8:29:57 PM org.jooq.tools.JooqLogger info
  INFO: Initialising properties  : /home/gradle/src/build/tmp/generateSampleJooqSchemaSource/config.xml
  Jun 01, 2020 8:30:08 PM org.jooq.tools.JooqLogger error
  SEVERE: Cannot read /home/gradle/src/build/tmp/generateSampleJooqSchemaSource/config.xml. Error : The connection attempt failed.
  org.postgresql.util.PSQLException: The connection attempt failed.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:297)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:211)
    at org.postgresql.Driver.makeConnection(Driver.java:459)
    at org.postgresql.Driver.connect(Driver.java:261)
    at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:342)
    at org.jooq.codegen.GenerationTool.run(GenerationTool.java:221)
    at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:216)
    at org.jooq.codegen.GenerationTool.main(GenerationTool.java:188)
  Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
    at java.net.Socket.connect(Socket.java:589)
    at org.postgresql.core.PGStream.<init>(PGStream.java:81)
    at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:93)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:197)
    ... 8 more


推荐答案

问题是您有 localhost build.gradle 中的 jooq 插件的配置中作为数据库主机。

The problem is that you have localhost as the database host in the configuration of your jooq plugin in build.gradle.

您已经在其他地方为 DB_HOST 正确设置了环境变量,因此我假设您理解服务的名称是可以使用的DNS名称。当它们连接到COM时引用其他服务星期一网络。您应该更改

You have correctly set environment variables for DB_HOST in other places so I assume you understand that name of the service is the DNS name that you can use to refer to other services when they are connected to a common network. You should change

url = 'jdbc:postgresql://localhost:5432/yurldb'

url = 'jdbc:postgresql://yurldb:5432/yurldb'

或者您可以在环境中获取数据库主机应用服务的变量,然后从 build.gradle 读取它:

or you can get the host of db in environment variable for application service and then read it from build.gradle :

def db = System.getenv('DB_HOST')
url = "jdbc:postgresql://${db}:5432/yurldb"

这篇关于通过Dockerfile上的Gradle映像触发后,Jooq无法找到数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆