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:
- Creating an executable JAR distribution
- 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:
- Inherits all configuration from the standard jar task.
- 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!
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!