Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running simple Kotlin Ktor app in docker container with PostgresSql database

I want to create simple Kotlin app that uses PostgresSql and Kotlin Ktor, everything should be embedded in docker container.

So far I managed to run separately PostgresSql and PgAdmin which connected to each other successfully and I created docker-compose.yml file for that that works fine form me. The problem starts when I want to add to it my Kotlin app.

Here is my docker-compose.yml file


version: "3.9"
networks:
  m8network:
    ipam:
      config:
        - subnet: 172.20.0.0/24
services:
  postgres:
    image: postgres
    environment:
      - "POSTGRES_USER=SomeFancyUser"
      - "POSTGRES_PASSWORD=pwd"
      - "POSTGRES_DB=MSC8"
    ports:
      - "5432:5432"
    volumes:
      #           - postgres-data:/var/lib/postgresql/data
      - D:\docker\myApp\data:/var/lib/postgresql/data
    networks:
      m8network:
        ipv4_address: 172.20.0.6
  pgadmin:
    image: dpage/pgadmin4
    depends_on:
      - postgres
    environment:
      - "[email protected]"
      - "PGADMIN_DEFAULT_PASSWORD=pwd"
    #           - "PGADMIN_ENABLE_TLS=False"
    ports:
      - "5001:80"
    networks:
      m8network:
  app:
    build: .
    ports:
      - "5000:8080"
    links:
      - postgres
    depends_on:
      - postgres
    restart: on-failure
    networks:
      m8network:
#volumes:
#    postgres-data:
#        driver: local

And heres is my app source code.


package com.something.m8

import com.squareup.sqldelight.db.SqlDriver
import com.squareup.sqldelight.sqlite.driver.asJdbcDriver
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.ktor.application.*
import io.ktor.html.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.html.*
import java.io.PrintWriter
import java.util.*


fun HTML.index() {
    head {
        title("Hello from Ktor!")
    }
    body {
        div {
            +"Hello from Ktor"
        }
    }
}

fun main() {
    println("starting app")
    val props = Properties()
    props.setProperty("dataSourceClassName", "org.postgresql.ds.PGSimpleDataSource")
    props.setProperty("dataSource.user", "SomeFancyUser")
    props.setProperty("dataSource.password", "pwd")
    props.setProperty("dataSource.databaseName", "M8")
    props.setProperty("dataSource.portNumber", "5432")
    props.setProperty("dataSource.serverName", "172.20.0.6")
    props["dataSource.logWriter"] = PrintWriter(System.out)
    println("a")
    val config = HikariConfig(props)
    println("b")

    val ds = HikariDataSource(config)
    println("c")
    val driver: SqlDriver = ds.asJdbcDriver()
    println("d")
    MSC8.Schema.create(driver)
    println("e")
    embeddedServer(Netty, port = 8080,
       // host = "127.0.0.1"
    ) {
        routing {
            get("/") {
                call.respondHtml(HttpStatusCode.OK, HTML::index)
            }
            get("/m8/{code}") {
                val code = call.parameters["code"]
                println("code $code")
                call.respondRedirect("https://google.com")
            }
        }
    }.start(wait = true)
}

And the Dockerfile for app


#FROM openjdk:8
FROM gradle:6.7-jdk8

WORKDIR /var/www/html
RUN mkdir -p ./app/
WORKDIR /var/www/html/app
COPY build.gradle.kts .
COPY gradle.properties .
COPY settings.gradle.kts .
COPY Redirect/src ./Redirect/src
COPY Redirect/build.gradle.kts ./Redirect/build.gradle.kts
COPY gradlew .
COPY gradle ./gradle
EXPOSE 8080

USER root
WORKDIR /var/www/html
RUN pwd
RUN ls
RUN chown -R gradle ./app
USER gradle
WORKDIR /var/www/html/app
RUN ./gradlew run

With this setup I have two problems

First problem:

When I run docker-compose.exe up --build I receive exception HikariPool$PoolInitializationException: Failed to initialize pool: The connection attempt failed. on line val ds = HikariDataSource(config) I set up static ip for postgres (172.20.0.6) and when I'm using this ip in PGAdmin it works so why my app cannot connect to the postgres?

Second problem:

I tried to test if app is starting properly and everything works fine in most basics. So I commented all source code related to the connection to the DB since that point when I run docker-compose.exe up --build my app displays only letter e from line println("e") and at this point everything seems to be frozen, postgres and PGAdming doesn't startup, and after that container seems to be unresponsive and app doesn't respond on port 5000 or 8080. Is there any way that I can run app so it won't block exectution of other parts?

like image 787
Adam Radomski Avatar asked Oct 16 '25 01:10

Adam Radomski


1 Answers

First problem: I started using host name instead IP adress so now I'm using postgres instead 172.20.0.6. And the rest of it is connected to second problem

Second problem:

The issue was that I was starting the app during build phase of container.

Instead RUN ./gradlew run I used

RUN gradle build
ENTRYPOINT ["gradle","run"]

Also I noticed that I don't have to use gradle wrapper while I'm using FROM gradle:6.7-jdk8

Now everyting is working fine.

like image 104
Adam Radomski Avatar answered Oct 17 '25 15:10

Adam Radomski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!