Deploy of Spring Boot/PostgreSQL project with Gradle and Docker

Scrobot Source

everyone. I have some problems with project deployment, and i already spent few days to solve it. I developing mobile backend on stack:

  1. Spring Boot 1.5 + Dev Tools
  2. PostgreSQL
  3. Docker
  4. Gradle

docker-compose.yml

version: '3'
services:
    web:
      image: mobilebackend      
      ports:
          - 8088:8080
      depends_on:
          - db
      links:
         - db
    db:
        container_name: transneft_db
        image: postgres
        restart: always
        volumes:
            - transneft_db:/var/lib/postgresql/data
        environment:
            - POSTGRES_PASSWORD=pass
            - POSTGRES_USER=user
            - POSTGRES_DB=db
            - PGDATA=/var/lib/postgresql/data/pgdata
        ports:
            - 54320:5432
    adminer:
        image: adminer
        restart: always
        ports:
            - 8082:8080
volumes:
    transneft_db: {}

application.properties

spring.datasource.url=jdbc:postgresql://localhost:54320/db
spring.datasource.username=user
spring.datasource.password=pass
spring.datasource.platform=postgres
spring.datasource.driver-class-name=org.postgresql.Driver

spring.jpa.database=POSTGRESQL
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

jwt.secret =aotransneftsibir

logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

build.gradle

buildscript {
    ext {
        springBootVersion = '1.5.10.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath('se.transmode.gradle:gradle-docker:1.2')
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'docker'
apply plugin: 'application'

repositories {
    mavenCentral()
}

compileJava {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    mainClassName       = "com.backend.MobilebackendApplication"
}

jar {
    baseName = "backend-api"
    group    = "com.backend"
    version  = "0.0.1-SNAPSHOT"
    manifest { attributes "Main-Class": "com.backend.mobilebackend.MobilebackendApplication" }
}

docker {
    baseImage "frolvlad/alpine-oraclejdk8:slim"
    maintainer 'Alex Scrobot "[email protected]"'
}

dependencies {
    // spring boot
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-data-rest')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime('org.springframework.boot:spring-boot-devtools')

    //postgresql
    runtime('org.postgresql:postgresql')

    //gson
    compile group: 'com.google.code.gson', name: 'gson', version: '2.7'

    // JWT
    compile 'io.jsonwebtoken:jjwt:0.9.0'

    //test env
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.security:spring-security-test')
}

On localhost working good, project are building with DevTools and working fine. Docker container with postgresql is up, i can access connection to it with localhost:port, all fine.

Problems started, then i tried to call:

./gradlew build distDocker --refresh-dependencies

In this case property spring.datasource.url have to contain localhost value, of build will fail. I put localhost value, get success message, that image is built. So, then i try to run container with Spring Boot .jar i get 'Connection Refused Error'. I have some thoughts about this case: container with .jar is running up, it tries to get database access by localhost:db_port, but inside this container cannot be db connection to its localhost. So, then i put in application.property

spring.datasource.url=jdbc:postgresql://db:54320/db

but then, i cannot build updated image. Then gradle try to boot assembled .jar, it cannot access to db:54320, because boot is running not in container, and right connections localhost:54320. Do you feel the vicious circle of how I feel it?))

I don't understand, what i'm doing wrong... please, help me to solve this problem.. Thank you.

javapostgresqldockerspring-bootdocker-compose

Answers

answered 3 months ago Hendrik M Halkow #1

The quick and dirty solution would be putting 127.0.0.2 db into your /etc/hosts file, and use jdbc:postgresql://db:54320/db as database URL and thing would work.

The nicer solution is using a build container for your application. So your docker-compose would look like this:

version: '3'
services:
  web:
    image: mobilebackend
    # The value of build refers to a directory at where your compose file is.
    build: mobilebackend
    ...

Within the mobilebackend directory, you create a Dockerfile like this:

FROM gradle AS build
RUN gradle build ...

FROM openjdk
COPY --from=build mobilebackend.jar .
RUN java -jar mobilebackend.jar

As you don't need to expose your database port for this, you can even use the standard port: jdbc:postgresql://db/db

Now you can compile and run your whole application with

docker-compose build
docker-compose up

comments powered by Disqus