How to build Kotlin apps in the cloud with Gradle.
Kotlin is Java reinvented, incorporating 20 years of hard-learned lessons.
It was built with all the features of a modern programming language that Java is slowly gaining, but which cannot be fully retrofitted such as:
- Type inference
- Lambdas
- Pattern matching
- Non-method functions
- Null safety
- Smart casts
- …and much more.
Kotlin easily interoperates with Java for a huge selection of libraries and minimal transition cost.
Though Kotlin is better known as an official language for Android, it is a general-purpose language, and I was curious about using Kotlin in the cloud — in a Docker container, of course. So I decided to try that out, drawing on my background in Java.
Though I have more experience with Maven as a tool for gathering dependencies and building Java code, I also set out to learn some Gradle, as it is slightly favored over Maven for building Kotlin apps.
Read further to see how to make this happen.

Instructions
- Install Docker.
- Install Gradle. Your OS’s package manager will help you with that: On Mac, that is just
brew install
- From here on, feel free to just copy my simple project and work with that. Or follow these steps to get there.
- Set up your Gradle/Kotlin project. This guide from the Kotlin side is useful, as is this one from Gradle. I’ll put them together and lay out how to set up a new app as easily as possible.
- Create your directory and switch to it. E.g.,
mkdir multicloud_pubsub && cd multicloud_pubsub
. - Run
gradle init
, then enter these in the interactive menus: 2 (application), 4 (Kotlin), 1 (no: only one application project), 1 (build scripts in Groovy),Enter
andEnter
for default project and sample source package names. - Type
gradle run
for a beautiful “Hello World!” - To add your own code, move on as in my sample project at Github here — which is a small part of an asynchronous app designed for maximum decoupling and robustness in the fact of cloud instability. I’m planning to write a separate article on that soon.
- Put code in a package-based subdirectory under
src/main/kotlin
, and delete the sample code insrc/main/kotlin
andsrc/test/kotlin
. - Delete the sample
guava
inbuild.gradle
, and add your dependencies. These are just the same artifact identifiers that you use in Maven, with a more readable syntax.
compile 'com.google.cloud:google-cloud-pubsub:1.42.0' compile 'com.google.cloud:google-cloud-storage:1.42.0'
- Add the Kotlin standard runtime library to
build.gradle
with the following standard library in thedependencies
section. There are multiple versions of this, sorted out in this article, but this is the one to use. Thejdk8
suffix does not mean that you can’t use higher Java language or bytecode levels when mixing Java and Kotlin code; it’s just that the Kotlin runtime is itself compiled at Java 8 bytecode level.
compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
- Edit the
mainClass
inbuild.gradle
, in this case'com.doitintl.mulicloud.ProcessorKt'
. Note theKt
suffix on the filename, for a synthetic class giving access to themain
function. - Add the following to the end of
build.gradle
. It builds an all-in-one jar file usable withjava -jar app.jar
jar
{
manifest
{
attributes 'Main-Class': mainClass
}
from
{
configurations.implementation.collect
{
it.isDirectory() ? it : zipTree(it)
} } }
- Test that with
gradle clean run
. - Now, on to the cloud! Put this
Dockerfile
in the directory. - Note that we use a separate Gradle image at build-time, allowing us to use a lightweight, clean image at runtime.
- We use using OpenJDK’s Java image. The Kotlin standard runtime library is built with the application, so there is no need for a Kotlin image.
- Build the image. Don’t forget the dot at the end to designate the build directory.
docker build -t pubsubapp .
Now run it.
docker run pubsubapp
That’s it! Since Docker images are so wonderfully self-contained, your knowledge gained in apps built with any other technologies will apply equally to one built with Kotlin and Gradle. There is more to do, like service accounts to create and roles to grant, as usual; I’ve created a script for that. (See the README.)
Enjoy!