Create your Ktor server and deploy it to Heroku

Rishiraj Randive
5 min readOct 10, 2023

--

Till now I have been using NodeJS for creating servers for my side projects because I found it easy and I have a little bit of experience with Javascript. For my job, I work as an Android Engineer so Kotlin has become my preferred language (previously it was Java). When I found out about Ktor I was excited to try it out and see how easy it would be for me to start using Ktor for creating servers/backend for side projects. My experience so far with Ktor has been great and since Kotlin is the language I am most comfortable in, it was quicker for me to get the backend setup with Ktor. I also found the official docs very helpful, however, there were a few gotchas which I figured out as I was working with Ktor, hence thought of sharing with y’all.

In this article, we will go through the steps to deploy a simple Ktor server on Heroku.

Prerequisites:

  1. Experience with using Kotlin
  2. IntelliJ IDEA (I use the community edition because it’s free) as an IDE
  3. Heroku account
  4. Heroku CLI

TLDR: If you don’t want to read, check the complete project here

Setting up the project

  1. Only folks using IntelliJ IDEA Community Edition need to generate the project from here https://start.ktor.io/, otherwise, you create a new project directly in the IDE. I obviously generated the project.
  2. You can specify the project name, package name, Ktor Version (leave it as it is if not sure), Engine (Netty), and configuration file (Code). Below is a screenshot for my setup, also you can add plugins as per your requirement but it’s possible to add them later as well.
  1. Now just hit the generate project button and it will start downloading the project zip. Unzip it and open the project in IntelliJ. Everything should be built and compiled.

Updating the generated project

For the Ktor server, there are two ways of creating a server

  1. As a self-contained package (we will be using this)
  2. Servlet

Self-contained package servers also have two approaches, the generated project probably will be using EmbeddedServer which is one approach but the second approach i.e. using Engine a lot more easier and flexible (read this for more info)

  1. Let’s update the project to use Engine by adding application.conf file under the resources folder and add below:
ktor {
deployment { port = 8080 }
application {
modules = [ <your-project-package>.ApplicationKt.module ]
}
}

and update the Application.kt ‘s main function following

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

2. If you added the Routing plugin when generating the project you should have this already set up. Otherwise, you can add it by creating a few file Routing.kt under plugins package and add the below code. All this is doing is responding Hello World! when you hit the root URL.

fun Application.configureRouting() {     
routing {
get("/") {
call.respondText("Hello World!")
}
}
}

3. Now, in your Application.kt file add below

fun Application.module() {     
configureRouting()
}

Now go ahead and run the project by clicking the green arrow shown against the main method. If your setup is exactly the same as mentioned here you should see http://0.0.0.0:8080 URL in the console and if you open it you should see Hello World! on the browser. Just for reference below is how my project structure looked at this stage

If it works so far your local setup is all done and now we can move on to deploying the project to Heroku.

Setting up the project for Heroku

  1. Update your application.conf so that Heroku can specify the port and for local you can continue using 8080 or anything else
ktor {   
deployment {
#LOCAL
port = 8080

port = ${?PORT}
}
application {
modules = [<package>.ApplicationKt.module]
}
}

2. Open build.gradle.kts the file and add stage a task that comes with an application plugin that we should already have

tasks {     
create("stage").dependsOn("installDist")
}

3. Create a Procfile in the root directory of your project and add something similar to this. Make sure to grab the <root-project-name> from settings.gradle.kts file. In my case it was com.login.sample

web: ./build/install/<root-project-name>/bin/<root-project-name>

Once these 3 steps are done we can deploy the app to Heroku using CLI. Before you start make sure the git is initialized for the project.

Deploy to Heroku

  1. Commit the changes made above
git add . 
git commit -m "commit-message"

2. Log in to Heroku and create the project on it

heroku login heroku create <project-name>

3. Push the changes to Heroku that will trigger the deployment and if everything is successful you will get the generated link for your app. A sample log is shown here:

git push heroku main  



remote: -----> Compressing...
remote: Done: 82.8M
remote: -----> Launching...
remote: Released v9
remote: <https://ktor-sample-login-a867e88e63ba.herokuapp.com/> deployed to Heroku
remote:
remote: Verifying deploy... done. To <https://git.heroku.com/ktor-sample-login.git>

NOTE: Watch out for Java version mismatch between your local and Heroku, if you see an error during deployment, you can force Heroku to use the same version by specifying that in system.properties file which you need to create in your root directory. Check this link for more details

That’s it! now you have the Ktor server deployed on the Heroku. Watch out for more step-by-step guides as I continue to build on this project.

Hope it helped and please share if there’s any feedback.

Thanks for reading!

--

--