Shipping Kotlin: Deployment and CI/CD
Prerequisites: Back-end development with Ktor, Android app architecture
Getting code from your machine to users — reliably, repeatably, and with tests checked on the way — is the last step of building real software.
Continuous integration
CI builds and tests every change automatically. With GitHub Actions:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew build detekt
./gradlew build compiles, runs the tests, and packages the result. The
Gradle action caches dependencies between runs.
Deploying a Ktor (or Spring Boot) service
Package the server as a single runnable fat JAR containing all
dependencies — Ktor's Gradle plugin provides ./gradlew buildFatJar —
and run it in a container:
# Dockerfile
FROM gradle:8-jdk21 AS build
WORKDIR /app
COPY . .
RUN gradle buildFatJar --no-daemon
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=build /app/build/libs/*-all.jar app.jar
RUN useradd --create-home app
USER app
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
- The multi-stage build keeps Gradle and the source code out of the final image; only a JRE and the JAR remain.
- Running as a non-root user limits the damage if the service is compromised.
- Configure the service with environment variables, log to standard
output, and expose a
/healthendpoint for the platform to check.
For very fast startup and low memory, a Kotlin service can also be compiled to a native executable with GraalVM.
Releasing an Android app
- Build a signed Android App Bundle (
.aab) with./gradlew bundleRelease, with R8 enabled to shrink and optimize the code. Keep the signing key safe and backed up — enrolling in Play App Signing lets Google manage the final key. - Upload it in the Google Play Console, starting with an internal testing track, then closed or open testing.
- Complete the store listing, content rating, and the Data safety form describing what data the app collects.
- Roll out to production gradually — a staged rollout to a small percentage of users first — while watching crash reports in the Play Console (Android vitals).
Tools such as fastlane or the Gradle Play Publisher plugin automate uploads from CI.
After release
- Monitor crashes and performance (Play Console, Firebase Crashlytics, or an error tracker on the server).
- Ship small updates often, and keep Kotlin, the Android Gradle plugin, and libraries up to date.
Congratulations
You've reached the end of Level 3. Build one of the Advanced Projects, then read What You Should Know Now — and What's Next for where to go from here.