You already know how to create the simplest Ktor application and access its routes in the browser. Today, we will learn how to deploy our application on any server that supports Java.
Deployment
We have a simple Ktor application. It runs on port 8080 and displays "Hello Ktor!" when accessing the "/" address.
Application.kt:
package com.example
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module)
.start(wait = true)
}
fun Application.module() {
routing {
get("/") {
call.respondText("Hello Ktor!")
}
}
}
To run and test your application, you can click "Run Application.kt" in IntelliJ IDEA:
In a browser, you can go to localhost:8080 and see that the application is running:
This way of launching an application is convenient for development.
But how to launch an application on a real server so that other users can use it? To do this, we need to package the application into a JAR file and run it on a server with Java installed.
Creating JAR with Gradle Shadow plugin
To create the JAR file, we use the Gradle Shadow plugin.
First, let's add it to build.gradle.kts in the plugins section:
plugins {
id("com.github.johnrengelman.shadow") version "7.0.0"
}
Next, add the shadowJar task to the tasks section. If you don't have a tasks section in build.gradle.kts, add this section at the end of the file:
tasks{
shadowJar {
manifest {
attributes(Pair("Main-Class", "com.example.ApplicationKt"))
}
}
}
Here we have specified the main class of our application.
We have the following build.gradle.kts:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
val ktor_version: String by project
val kotlin_version: String by project
val logback_version: String by project
plugins {
kotlin("jvm") version "1.7.0"
id("io.ktor.plugin") version "2.3.2"
id("com.github.johnrengelman.shadow") version "7.0.0"
}
group = "com.example"
version = "0.0.1"
application {
mainClass.set("com.example.ApplicationKt")
val isDevelopment: Boolean = project.ext.has("development")
applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
}
repositories {
mavenCentral()
}
dependencies {
implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
implementation("ch.qos.logback:logback-classic:$logback_version")
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
implementation(kotlin("stdlib-jdk8"))
}
val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions {
jvmTarget = "1.8"
}
val compileTestKotlin: KotlinCompile by tasks
compileTestKotlin.kotlinOptions {
jvmTarget = "1.8"
}
tasks{
shadowJar {
manifest {
attributes(Pair("Main-Class", "com.example.ApplicationKt"))
}
}
}
Next, apply the build.gradle.kts updates by clicking the corresponding popup button in the upper right part of the IDE:
Now we can easily run the created shadowJar task through the terminal.
Go to the root folder of your project and run the appropriate command:
On Windows:
gradlew.bat shadowJar
On Linux/Mac:
./gradlew shadowJar
After running the command, if you have done everything correctly, you will see "BUILD SUCCESSFUL":
Now, if we go to the build/libs folder, we can see our created JAR file:
This way of packaging an application is called Fat JAR because the resulting JAR file contains all the necessary dependencies and is ready to run. Therefore, this method is very convenient.
Creating JAR with Ktor Gradle plugin
In new versions of Ktor, there is a new and more convenient way to create a JAR file using the Ktor Gradle plugin.
By default, this plugin is usually specified in build.gradle.kts, so there is no need for you to manually specify command line tasks for it.
Make sure you have this plugin connected and the main application class configured:
plugins {
id("io.ktor.plugin") version "2.3.2"
}
application {
mainClass.set("com.example.ApplicationKt")
}
These lines were already present by default in our previously provided build.gradle.kts file.
The Ktor plugin provides the buildFatJar task, and doesn't need to be manually specified. It can run in the same way as shadowJar:
On Windows:
gradlew.bat buildFatJar
On Linux/Mac:
./gradlew buildFatJar
After running the command, if you have done everything correctly, you will see "BUILD SUCCESSFUL":
You can also find the resulting JAR in the build/libs folder.
Running Gradle tasks through the IDE interface
If you are using IntelliJ IDEA, you can run Gradle tasks more conveniently. In the upper right part of the IDE window, there is a special "Gradle" tab, which is intended for managing dependencies and launching tasks via UI.
In the "Tasks" drop-down list, you can see all of Gradle's available tasks, including the shadowJar and buildFatJar tasks we discussed earlier.
If you double-click on one of these tasks, the console will open, and the task will be executed.
After that, the finished JAR will be in the build/libs folder.
Running a JAR file
Once our application's JAR file is ready, all we have to do is run it.
To do this, go to the folder with the JAR file and run it using the standard Java command: java -jar <file name>
java -jar ktor-sample-all.jar
After that, our application will start in the terminal:
In a browser, you can go to localhost:8080, and see that the application is running:
We can close the IDE at this point. The application will work until we close the terminal where our JAR file is running.
This way, our application can run on any server that has Java. All you need is to run the JAR file with your application. If our computer had a static IP address and a proper firewall setting, the application could be accessed from the Internet via a link like http://<your computer's ip>:8080/. Later you can buy a domain name and link it to the server's IP address to refer to the site through the name instead of the IP.
To ease the process of setting up such a server, there are ready-made hosting solutions that simplify the deployment process. For example, Heroku. You can read the official tutorial on how to host a Ktor application on Heroku.
Conclusion
In this topic, we learned about deploying a Ktor application.
We've learned:
- The reason why you need to create a JAR file.
- How to create a JAR file with the Gradle Shadow plugin.
- How to create a JAR file with the Ktor Gradle plugin.
- How to run Gradle tasks through the IntelliJ IDEA interface.
- How to run the resulting JAR file on a Java-enabled server.
Now let's put what we've learned into practice.