Ktor 3.0.2 Help

Docker Compose

In this topic, we'll show you how to run a server Ktor application under Docker Compose. We'll be using a project created in the Integrate a Database tutorial, which uses Exposed to connect to a PostgreSQL database where the database and the web application run separately.

Get the application ready

Extract database settings

The project created in the Integrate a Database tutorial uses hardcoded attributes to establish a database connection.

Let's extract connection settings for the PostgreSQL database to a custom configuration group.

  1. Open the application.yaml file in src/main/resources and add the storage group outside the ktor group as follows:

    ktor: application: modules: - com.example.ApplicationKt.module deployment: port: 8080 storage: driverClassName: "org.postgresql.Driver" jdbcURL: "jdbc:postgresql://localhost:5432/ktor_tutorial_db" user: "postgres" password: "password"

    These settings will be configured later in the docker-compose.yml file.

  2. Open the Databases.kt file in src/main/kotlin/com/example/plugins/ and update the configureDatabases() function to load storage settings from the configuration file:

    fun Application.configureDatabases(config: ApplicationConfig) { val url = config.property("storage.jdbcURL").getString() val user = config.property("storage.user").getString() val password = config.property("storage.password").getString() Database.connect( url, user = user, password = password ) }

    The configureDatabases() function now accepts ApplicationConfig and uses config.property to load custom settings.

  3. Open the Application.kt file in src/main/kotlin/com/example/ and pass environment.config to configureDatabases() to load connection settings on application startup:

    fun Application.module() { val repository = PostgresTaskRepository() configureSerialization(repository) configureDatabases(environment.config) configureRouting() }

Configure the Ktor plugin

In order to run on Docker, the application needs to have all the required files deployed to the container. Depending on the build system you're using, there are different plugins to accomplish this:

In our example, the Ktor plugin is already applied in the build.gradle.kts file.

plugins { application kotlin("jvm") id("io.ktor.plugin") version "3.0.2" id("org.jetbrains.kotlin.plugin.serialization") version "2.0.0" }

Configure Docker

Prepare the Docker image

To dockerize the application, create a new Dockerfile in the root directory of the project and insert the following content:

# Stage 1: Cache Gradle dependencies FROM gradle:latest AS cache RUN mkdir -p /home/gradle/cache_home ENV GRADLE_USER_HOME /home/gradle/cache_home COPY build.gradle.* gradle.properties /home/gradle/app/ COPY gradle /home/gradle/app/gradle WORKDIR /home/gradle/app RUN gradle clean build -i --stacktrace # Stage 2: Build Application FROM gradle:latest AS build COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle COPY . /usr/src/app/ WORKDIR /usr/src/app COPY --chown=gradle:gradle . /home/gradle/src WORKDIR /home/gradle/src # Build the fat JAR, Gradle also supports shadow # and boot JAR by default. RUN gradle buildFatJar --no-daemon # Stage 3: Create the Runtime Image FROM amazoncorretto:22 AS runtime EXPOSE 8080 RUN mkdir /app COPY --from=build /home/gradle/src/build/libs/*.jar /app/ktor-docker-sample.jar ENTRYPOINT ["java","-jar","/app/ktor-docker-sample.jar"]

Configure Docker Compose

In the root directory of the project, create a new docker-compose.yml file and add the following content:

services: web: build: . ports: - "8080:8080" depends_on: db: condition: service_healthy db: image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data environment: POSTGRES_DB: ktor_tutorial_db POSTGRES_HOST_AUTH_METHOD: trust ports: - "5432:5432" healthcheck: test: [ "CMD-SHELL", "pg_isready -U postgres" ] interval: 1s
  • The web service is used to run the Ktor application packaged inside the image.

  • The db service uses the postgres image to create the ktor_tutorial_db database for storing tasks.

Build and run services

  1. Run the following command to create the fat JAR containing your Ktor application:

    ./gradlew :tutorial-server-docker-compose:buildFatJar
  2. Use the docker compose up command to build the images and start containers:

    docker compose --project-directory snippets/tutorial-server-docker-compose up
  3. Wait until Docker Compose has finished building the images.

  4. Navigate to http://localhost:8080/static/index.html to open the web application. You should see the Task Manager Client page displaying three forms for filtering and adding new tasks,as well as a table of tasks.

    A browser window showing the Task Manager Client
Last modified: 19 September 2024