在 CircleCi 中从 Spring Boot 访问 PostgreSQL 9.6

Posted

技术标签:

【中文标题】在 CircleCi 中从 Spring Boot 访问 PostgreSQL 9.6【英文标题】:Accessing PostgreSQL 9.6 from Spring Boot in CircleCi 【发布时间】:2018-02-22 01:23:25 【问题描述】:

我有一个 Spring Boot 应用程序,目前在 Heroku 的 CI 中构建和运行测试,我正试图让它在 Circle CI 中也能工作。我的配置文件如下所示:

version: 2
jobs:
  build:
    docker:
      - image: circleci/jdk8:0.1.1
      - image: postgres:9.6
    working_directory: ~/repo

    environment:
      # Customize the JVM maximum heap limit
      JVM_OPTS: -Xmx3200m
      TERM: dumb

    steps:
      - checkout
      - run: chmod +x gradlew

      # Download and cache dependencies
      - restore_cache:
          keys:
          - v1-dependencies- checksum "build.gradle" 
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      - run: ./gradlew dependencies

      - save_cache:
          paths:
            - ~/.m2
          key: v1-dependencies- checksum "build.gradle" 

      # run tests!
      - run: ./gradlew test

我尝试了各种定义 DATABASE_URL 的方法都没有效果:

jobs:
  build:
    docker:
      - image: circleci/jdk8:0.1.1
        environment:
        - DATABASE_URL=postgresql://dashman_test@localhost:5433/dashman_test
      - image: postgres:9.6
        environment:
        - POSTGRES_USER=dashman_test
        - POSTGRES_DB=dashman_test

jobs:
  build:
    docker:
      - image: circleci/jdk8:0.1.1
        environment:
        - DATABASE_URL=postgresql://dashman_test@localhost:5434/dashman_test
      - image: postgres:9.6
        environment:
        - POSTGRES_USER=dashman_test
        - POSTGRES_DB=dashman_test

jobs:
  build:
    docker:
      - image: circleci/jdk8:0.1.1
        environment:
          DATABASE_URL: postgresql://dashman_test@localhost:5434/dashman_test
      - image: postgres:9.6
        environment:
          POSTGRES_USER: dashman_test
          POSTGRES_DB: dashman_test


TEST_DATABASE_URL: postgresql://ubuntu@localhost/circle_test?sslmode=disable        
DATABASE_URL: postgresql://ubuntu@localhost/circle_test?sslmode=disable

DATABASE_URL: postgres://ubuntu:@127.0.0.1:5433/circle_test

DATABASE_URL: postgres://localhost:5433/dashman_test

DATABASE_URL: postgresql://ubuntu@localhost:5434/circle_test?sslmode=disable

DATABASE_URL: postgres://dashman_test:KnDnHtzneyTzps0WuYr35r9@localhost:5433/dashman_test

似乎没有任何效果,我总是以这个错误结束:

tech.dashman.dashmanserver.models.AccountTest > create FAILED
    java.lang.IllegalStateException
        Caused by: org.springframework.beans.factory.BeanCreationException
            Caused by: org.springframework.beans.BeanInstantiationException
                Caused by: org.springframework.beans.factory.BeanCreationException
                    Caused by: org.springframework.beans.BeanInstantiationException
                        Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException

tech.dashman.dashmanserver.models.UserTest > create FAILED
    java.lang.IllegalStateException
        Caused by: org.springframework.beans.factory.BeanCreationException
            Caused by: org.springframework.beans.BeanInstantiationException
                Caused by: org.springframework.beans.factory.BeanCreationException
                    Caused by: org.springframework.beans.BeanInstantiationException
                        Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException

tech.dashman.dashmanserver.DashmanserverApplicationTests > contextLoads FAILED
    java.lang.IllegalStateException
        Caused by: org.springframework.beans.factory.BeanCreationException
            Caused by: org.springframework.beans.BeanInstantiationException
                Caused by: org.springframework.beans.factory.BeanCreationException
                    Caused by: org.springframework.beans.BeanInstantiationException
                        Caused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException

配置数据库的正确方法是什么?我有点迷茫。

【问题讨论】:

你的 DATABASE_URL 是什么? @StanislavL:我添加了我尝试过的每个 DATABASE_URL 的列表。你问的是这个吗? 难道 postgree 在 docker 容器中运行,所以你需要容器​​ IP(或名称)而不是 localhost? @StanislavL:也许,我不知道,但这似乎表明并非如此:circleci.com/docs/2.0/postgres-config 您是否尝试过 dbl 引用- DATABASE_URL="postgresql://dashman_test@localhost:5434/dashman_test" 如上面的链接?...您是否还尝试按照文档中的示例添加POSTGRES_PASSWORD: "some password"?... 【参考方案1】:

以下几点可以帮助您解决问题。


(1) 您在 cmets (this one) 中提到的文档要么已过时,要么完全具有误导性。这个:

PostgreSQL 9.6 的默认用户、端口、测试数据库如下: postgres://ubuntu:@127.0.0.1:5432/circle_test

...不正确

postgres:9.6 的实际默认值是:

用户名:postgres 密码:<empty> 端口:5432 数据库:postgres

您可以通过127.0.0.1 上的应用程序访问 postgres 实例。

您可以找到有关默认值 here 的更多信息,但在设置它们时有一个问题(更多信息请参见 (3))。


(2) 据我所知,there is no way to pass usrename\password 在 jdbc url 中用于 postgres 连接器,因此您可能不仅要告诉您的应用程序 DATABASE_URL,还要告诉您的应用程序 DATABASE_USER 和 @ 987654337@。

这部分取决于您的应用程序的具体情况,但对于具有默认数据库设置的典型 Spring Boot 应用程序,您希望以以下设置结束:

spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=

(3) 或者,如果您的连接设置是硬编码的,您可能需要为 postgres 实例配置凭据。

不幸的是,即使在使用docker run 运行容器时设置POSTGRES_* 环境变量可以正常工作,但在.circleci/config.yml 中设置它们不起作用。很少有公开的错误报告(1、2)描述了这个或类似的问题,我的钱是在这个错误上。

幸运的是,您仍然可以通过安装 psql 并在构建期间创建所需的用户凭据来解决此问题(默认凭据仍然有效)。添加类似:

  - run: apt-get update -qq && apt-get install -y postgresql
  - run:
      command: |
        psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE databasename;"
        psql -h 127.0.0.1 -U postgres -c "CREATE USER username WITH PASSWORD 'password'; GRANT ALL PRIVILEGES ON DATABASE databasename TO username;"

...您的steps 应该可以解决问题(请参阅full example here)。

使用machine executor 手动运行postgres(参见this page 上的最后一个示例)也可能是一种选择,但我自己没有尝试过。


(4) 我实际上尝试为自己配置此功能,您可以使用working version here 查看 repo。构建output example here。

我使用了这个spring boot sample 并让它使用了postgres,只留下了相关的测试,添加了circle ci 以及其他一些小的调整。它演示了通过 env 配置应用程序。变量和配置 postgres 实例。

最有趣的部分是.circleci/config.yml(其中定义了凭据环境变量,并且在 postgres 实例中创建了 user\db):

版本:2 工作: 建造: 码头工人: - 图片:maven:3.5.0-jdk-8 环境: DATABASE_URL: jdbc:postgresql://127.0.0.1:5432/databasename DATABASE_USER:用户名 DATABASE_PASSWORD:密码 - 图片:postgres:9.6 工作目录:~/repo 脚步: - 退房 - 运行:apt-get update -qq && apt-get install -y postgresql - 跑步: 命令:| psql -h 127.0.0.1 -U postgres -c "CREATE DATABASE 数据库名称;" psql -h 127.0.0.1 -U postgres -c "使用密码'密码'创建用户用户名;将数据库数据库名称上的所有权限授予用户名;" - 运行:mvn 测试

...和application.properties(使用凭据环境变量):

spring.h2.console.enabled=false logging.level.org.hibernate.SQL=错误 spring.datasource.url=$DATABASE_URL spring.datasource.username=$DATABASE_USER spring.datasource.password=$DATABASE_PASSWORD spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.database=POSTGRESQL spring.datasource.platform=postgres spring.jpa.show-sql=true spring.database.driverClassName=org.postgresql.Driver

【讨论】:

谢谢。该示例确实很有帮助,特别是您需要如何设置属性文件,这是我所缺少的。我会将其添加到答案中(以防示例被删除)。 @Pablo 现在没有删除它的计划,但是,是的,好主意。我添加了属性文件以及我在示例中使用的 circleci 配置文件。

以上是关于在 CircleCi 中从 Spring Boot 访问 PostgreSQL 9.6的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中从控制器覆盖 @JsonInclude

在 Spring Boot 中从 JWT 安全检查中排除 URL

如何在apache中从角度调用spring boot api

在 Spring Boot 中从 jwt 获取附加属性

无法在 spring-boot 应用程序中从 Consul 读取配置

如何在 Spring Boot 中从双向表关系生成 DTO