使用 spring boot 和 postgres 正确设置 docker compose

Posted

技术标签:

【中文标题】使用 spring boot 和 postgres 正确设置 docker compose【英文标题】:Proper setup of docker compose with spring boot and postgres 【发布时间】:2021-07-09 11:58:30 【问题描述】:

我有一个 docker compose 文件,其中有两个服务,flamup 服务用于构建我的 Spring Boot 应用程序,并链接到由 db 服务定义的 postgres 映像。

这是 docker-compose.yml 文件

version: '3.8'


volumes:
  postgres_data:

services:

  flamup:
    build: .
    container_name: flamup
    environment:
      - DB_SERVER=db
      - POSTGRES_DB=flamup
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    ports:
      - "8080:8080" # Forward the exposed port 8080 on the container to port 8080 on the host machine
    depends_on:
      - db
    links:
      - db



  db:
    image: "postgres:9.6-alpine"
    container_name: postgres_container
    restart: always

    volumes:
      - postgres_data:/var/lib/postgresql/data

    ports:
      - "5432:5432"

    environment:
      - POSTGRES_DB=flamup
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - PGDATA=/var/lib/postgresql/data/pgdata

这是 Spring Boot 应用程序的 Dockerfile

FROM maven:3.6.1-jdk-8-slim AS build
RUN mkdir -p workspace
WORKDIR workspace
COPY pom.xml /workspace
COPY src /workspace/src
COPY frontend /workspace/frontend
COPY data2.csv /workspace
RUN mvn -f pom.xml clean package
#RUN ./mvnw clean package -DskipTests

#FROM adoptopenjdk/openjdk11:alpine-jre
FROM openjdk:8-alpine
COPY --from=build /workspace/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]

我正在使用frontend-maven-plugin 来使用 Spring Boot 应用程序引导前端。在本地一切正常。

但是,当我尝试通过 docker-compose 运行它时,我在 application-properties.yml 中进行了一些更改

server:
  error:
    include-message: always
    include-binding-errors: always


spring:
  datasource:
    url : jdbc:postgresql://$DB_SERVER/$POSTGRES_DB
    username : $POSTGRES_USER
    password : $POSTGRES_PASSWORD

  jpa:
    hibernate:
      ddl-auto: create
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
        jdbc:
          lob:
            non_contextual_creation: true
    show-sql: true

  session:
    store-type: jdbc
    jdbc:
      table-name: SPRING_SESSION
      initialize-schema: never

但是构建每次都失败,因为这个

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
Caused by: java.net.UnknownHostException: $DB_SERVER

我尝试过的事情

硬编码DB_SERVER 变量并替换为localhost:5432dbdb:5432。这些似乎都不起作用。 添加依赖于flamup服务中的字段。 在两个服务中添加网络字段并通过网桥连接它们。 尝试了不同版本的 postgres 和 maven

似乎没有什么解决办法,任何帮助将不胜感激。

【问题讨论】:

docs.docker.com/compose/environment-variables 【参考方案1】:

因此,该问题的有效解决方案(尽管可能效率不高)是通过跳过测试来运行 maven 构建。显然休眠会导致运行 JPA 语句,这会导致 JDBC postgres 异常失败,因为还没有运行 postgres 的容器。

因此将 dockerfile 更改为

RUN mvn -f pom.xml clean install -DskipTests=true

而不是

RUN mvn -f pom.xml clean package

导致成功创建可以作为 docker 容器运行的 jar 文件。

【讨论】:

以上是关于使用 spring boot 和 postgres 正确设置 docker compose的主要内容,如果未能解决你的问题,请参考以下文章

带有用户名和密码的 Zonky + Spring Boot + Postgres + Flyway

如何使用 Spring Boot JPA 在 Postgres 中存储几何点?

序列不存在 - Postgres/Spring Boot

在 Spring Boot 的同一个 pom.xml 中管理 H2 和 Postgres

在带有 Spring-boot 的 postgres 中使用整数数组

Liquibase / Spring Boot / Postgres - 模式名称不起作用