Chapter 5: Deployment

Kotlin Multiplatform Mobile

link Deployment

Introduction

In this section, we will deploy our application using Heroku. Heroku is a platform as a service for deploying and running modern apps. We will create a heroku app, and deploy our application from the command line.

This section will be short and sweet. We will be following the official Heroku Deployment Guide from Ktor's documentation.

link Procfile

Procfiles, or process files, allow us to declare which process Heroku should run when the application deployment is successful.

Create a new file in the root directory called Procile and add the following:

web: java -jar build/libs/example-0.0.1-all.jar

The above Procfile declares a web process that runs our application's pre-built java code.

Jar

In order to let Heroku know what type of application we will be running, we will create a file named app.json file with the following contents:

{
  "name": "Ktor GraphQL",
  "description": "Kotlin GraphQL server",
  "image": "heroku/java"
}

Be sure the give your service a custom name and description.

link Shadow JAR

In order to build the combined application, we will use the Gradle Shadow Plugin to create a single output Jar.

The combined Jar is often referred to a "fat-jar" or "uber-jar".

Shadowing a project output has 2 major use cases:

  1. Creating an executable JAR distribution
  2. Bundling and relocating common dependencies in libraries to avoid classpath conflicts

The JAR file contains all the application code and dependent libraries to execute (not including the standard JVM libraries).

For more information about a shadow Jar, visit the official documentation

To get started with the gradle shadow plugin, add the following to your root build.gradle.kts:

plugins {
    application
    kotlin("jvm") version "1.4.21"
    // Check the shadow plugin manual if you're using an older version of Gradle.
    id("com.github.johnrengelman.shadow") version "6.1.0"
}

tasks {
    // ...
}

application {
    mainClassName = "io.ktor.server.netty.EngineMain"
}

tasks.withType<Jar> {
    manifest {
        attributes(
                mapOf(
                        "Main-Class" to application.mainClassName
                )
        )
    }
}

The above code declares the shadow plugin and version. Shadow performs no configuration on our project, instead it will add a shadowJar as an executable gradle task.

The shadowJar task generates a Manifest that:

  1. Inherits all configuration from the standard jar task.
  2. Adds a Class-Path attribute to the Manifest that appends all dependencies from the shadow configuration

In essence, the shadow jar creates a pre-built application that can be uploaded to Heroku.

link System Properties

In order for Heroku to recognize which java version we are running, we will add a file called system.properties in the root directory:

java.runtime.version=1.8

link Heroku Local

Prior to the deployment, we should verify the application works locally.

We can do so by creating a local configuration file called .env and adding the following contents:

MONGO_URI=mongodb+srv://<dbname>:<password>@cluster0-yvwjx.mongodb.net/<dbname>?retryWrites=true&w=majority
PORT=8080

Be sure to update the MONGO_URI connection string with your connection string value.

To run the server locally, cd into your project directory and run the following command:

heorku local

Once the application runs locally at localhost:8080/graphql, you may proceed with the deployment.

link Heroku

Make sure you download the heroku cli and run heroku login

heroku create your-heroku-app-name
git status
git add .
git commit -m "update project"
git remote add heroku <your-heroku-remote-url>
heroku config:set GRADLE_TASK="shadowJar"
heroku config:set MONGO_URI="xxx"
git push heroku master

Having issues? Debug with the Heroku command heroku logs --tail to see what's happening on the Heroku server.

Test the endpoints!

https://your-heroku-app-name.herokuapp.com/graphql

If everything works as expected, congratulations!

Today we built a Ktor GraphQL server using KMongo and Koin, and deployed the project to Heroku.

Now that we have completed the backend server project, we can switch gears and start building the KMM repository. Stay tuned!

link References

format_list_bulleted
help_outline