How to Deploy Kotlin Microservice to AWS App Runner: Complete Tutorial
By Braincuber Team
Published on April 2, 2026
Hello, everyone. In this step-by-step tutorial, I would like to show you how to deploy a Kotlin Microservice using Docker and AWS App Runner. Together, we will learn what exactly is AWS App Runner, how to configure AWS Command Line Interface on your local machine, how to push Docker images to Amazon Elastic Container Registry (ECR), and finally, how to deploy our containerized application with AWS App Runner. I know, it might sound like a tremendous amount of work. But I am convinced that you will find out how simple it can be with the above tech stack. This complete tutorial provides a beginner guide with a step by step guide to deploying your Kotlin applications to the cloud.
What You'll Learn:
- What AWS App Runner is and when to use it
- How to create a simple Kotlin Ktor REST API microservice
- How to containerize your Kotlin application with Docker
- How to configure AWS CLI and create an IAM user
- How to push Docker images to Amazon ECR
- How to deploy your containerized app with AWS App Runner
Managed Deployment
AWS App Runner handles load balancing, scaling, and infrastructure so you can focus on writing Kotlin code.
Docker Containerization
Package your Kotlin Ktor application into a Docker image for consistent, reproducible deployments anywhere.
Secure ECR Registry
Store your Docker images in Amazon Elastic Container Registry with IAM-based access control and encryption.
Kotlin Ktor Framework
Build lightweight, asynchronous REST APIs with Kotlin and Ktor, perfect for microservice architectures.
Prerequisites
Before we start, make sure that you have Docker already installed on your local machine. We will need to containerize our application.
If you do not have Docker, then the official Docker documentation will help you set it up in a few minutes.
Additional Requirements
You will also need an AWS account, AWS CLI installed on your machine, and Gradle (or the Gradle Wrapper included in the project). An IDE like IntelliJ IDEA is recommended but not required.
What Exactly Is AWS App Runner?
First, let us take a minute to understand what exactly AWS App Runner is.
To put it simply, it is a fully managed service which allows you to build and deploy containerized web applications and APIs with ease. It takes care of plenty of things, like traffic load balancing, or scaling, which helps developers like you and me focus on the code.
AWS App Runner oftentimes is a great choice when creating a demo or proof of concept, but it is also worth considering for smaller teams without a dedicated person working on infrastructure.
Step 1: Create a Simple Kotlin Microservice
With that being said, let us prepare a simple REST API using Kotlin and Ktor.
If you are not interested in the Ktor implementation, then you can simply clone this GitHub repository and proceed to the How to Build the Docker Image step.
If you are using the IntelliJ IDEA Ultimate Edition, then you can create a Ktor project using the app. Otherwise, you can use the Ktor Project Generator tool and download the project to your local machine.
Regardless of your choice, make sure to import the following plugins:
- ContentNegotiation
- kotlinx.serialization
- Routing
Configure Serialization
After you have imported the project, create the Serialization.kt file and register application/json content type to the ContentNegotiation feature:
fun Application.configureSerialization() {
install(ContentNegotiation) {
json()
}
}
In simple words, with this code snippet we will be able to serialize Kotlin objects into JSON (and deserialize the JSON into objects, as well).
Create a DTO
Now let us implement a MessageDto data class like this:
@Serializable
data class MessageDto(val message: String)
Basically, we will use this generic class to provide messages for our API consumers.
Expose Endpoints
As the next step, let us create a Routing.kt file and expose a new endpoint:
fun Application.configureRouting() {
routing {
helloWorldRoute()
}
}
fun Routing.helloWorldRoute() {
route("/hello") {
get {
call.respond(HttpStatusCode.OK, MessageDto("Hello World!"))
}
}
}
As you can see, our application will respond with a 200 OK status code to each GET request to the /hello path.
Configure the App
Now, let us combine everything inside the Application.kt file:
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
configureRouting()
configureSerialization()
}.start(wait = true)
}
As you can see, our Kotlin microservice will be a Netty embedded server running on localhost:8080.
I highly encourage you to run the application and verify that everything is working properly:
GET localhost:8080/hello
Status: 200 OK
Response Body:
{
"message": "Hello World!"
}
Implement the Dockerfile
Finally, let us add the Dockerfile to the root directory of our project:
FROM openjdk:8-jdk
EXPOSE 8080:8080
RUN mkdir /app
COPY ./build/install/com.codersee.ktor-app-runner/ /app/
WORKDIR /app/bin
CMD ["./com.codersee.ktor-app-runner"]
Important: Match Project Name
Make sure that the directory specified for the COPY and CMD commands matches the value of rootProject.name inside the settings.gradle.kts file. If the project name is xyz, then these commands should reflect that: COPY ./build/install/xyz/ /app/ and CMD ["./xyz"].
Step 2: Build the Docker Image
At this point, we have everything we need to build our Docker Image, which we will use later for the AWS App Runner deployment.
Run the Gradle Command
Run the installDist command with Gradle Wrapper: ./gradlew installDist. This command is responsible for assembling the distribution content and installing it on the current machine. It will simply create necessary files inside the ./build/install/{project-name}/ directory.
Build the Docker Image
Run docker build -t ktor-aws-runner . to build the image. We named our desired image ktor-aws-runner with the -t option (a shortcut for --tag).
Verify Docker Configuration
Run docker run -p 8080:8080 ktor-aws-runner to verify. The -p flag publishes the container port 8080 to the host port 8080. After a few seconds you should see Application started in 0.078 seconds in the logs.
Step 3: Create and Configure an AWS User
With all of that being done, we can finally start working with AWS. But before we are able to push our Docker Image, we need to make sure that we have AWS CLI installed on our local machine.
aws --version
# Result:
# aws-cli/2.5.3 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
If you need to install or update the CLI, AWS ships with a really good article on that in their official documentation.
Create an IAM User
Additionally, we have to have access to AWS Cloud from our computer. In order to set up the access, let us sign in to the AWS Management Console and navigate to the Users feature of the IAM Console.
Add User with Programmatic Access
Click Add users, specify the preferred User name along with the Access key - Programmatic access credential type. With these settings, we will be able to access AWS using a combination of access key and secret.
Create Group with AdministratorAccess
Create a new group (e.g., admin-group) and select the AdministratorAccess policy. For simplicity, we are going to use AdministratorAccess. But in real-life scenarios, we should always stick to The Principle of Least Privilege.
Download Credentials
After creating the user, click the Download .csv button to fetch your access and secret keys. Keep in mind that access and secret keys are highly confidential data and you should never share them with anyone!
Configure AWS CLI with Credentials
Navigate to the download directory and run: aws configure import --csv file://some_user_credentials.csv. Verify that a new file called credentials has been created inside the .aws directory.
Step 4: Push the Docker Image to ECR
At this point, our CLI is properly prepared, so we can learn how to push our local Docker Image to the Elastic Container Registry.
Create ECR Repository
Go to the Management Console, search for container registry, click on Elastic Container Registry, and click Create repository. Select a Private repository and specify a name. Leave the rest of settings with default values.
Tag the Docker Image
Copy the repository URI and tag your local image: docker tag ktor-aws-runner:latest [your_registry_uri]:latest. When working with Docker, we need to tag images with registry host and port in order to push them to any private repository.
Authenticate to Amazon ECR
Run: aws ecr get-login-password --profile some-admin --region us-east-1 | docker login --username AWS --password-stdin [your registry URI]. You should see Login Succeeded.
Push the Image
Run docker push [your_tagged_image]. Depending on your connection it can take some time, but finally, you should see the updated list in your repository.
Step 5: Deploy the Application to AWS App Runner
Now we have everything we need to share our Kotlin microservice with the world.
Create App Runner Service
Search for app runner in the Management Console and click Create service. For Source configuration, choose Container registry along with Amazon ECR.
Select Your Image
Click Browse and select your previously created image. For Deployment settings, choose Manual and Create new service role.
Configure Service Resources
Provide a Service name along with CPU, Memory, and Port information. Choose the minimum available combination. We do not need environment variables and we have already added a start command to our Docker Image.
Configure Auto Scaling
On the Auto scaling page, select Custom configuration and create a new configuration. This example configuration will not scale our Kotlin Microservice. However, if we increase the Maximum size, then a new instance will be created each time the number of simultaneous requests increases by 10.
Deploy and Test
Click Create and Deploy. After the process finishes (a few minutes), the status will change to Running. Test the GET /hello endpoint using the Default domain URL provided by App Runner.
# Replace with your App Runner default domain
GET https://aaaaaaaaaa.us-east-1.awsapprunner.com/hello
Status: 200 OK
Response Body:
{
"message": "Hello World!"
}
Important: Clean Up Resources
Please remember to delete all the resources we created today, so that you will not be charged for them. It is really easy to forget about all the things we create when learning AWS Cloud and at some point, you may exceed your free quota. Thus, it is a good practice to remove all of that.
Need Help Deploying Applications to AWS?
Braincuber's cloud experts can help you architect, containerize, and deploy Kotlin microservices on AWS App Runner, ECS, or EKS. 500+ successful cloud projects delivered.
Frequently Asked Questions
What is AWS App Runner?
AWS App Runner is a fully managed service that allows you to build and deploy containerized web applications and APIs with ease. It handles load balancing, scaling, and infrastructure management automatically.
How do I push a Docker image to Amazon ECR?
Authenticate with aws ecr get-login-password, tag your image with the ECR repository URI using docker tag, then push with docker push. You need AWS CLI configured with appropriate IAM permissions.
What is Ktor in Kotlin?
Ktor is a Kotlin framework for building asynchronous servers and clients. It is lightweight, coroutine-based, and ideal for creating microservices and REST APIs with minimal boilerplate code.
How much does AWS App Runner cost?
App Runner charges based on vCPU and memory allocation, plus data transfer. The minimum configuration (1 vCPU, 2 GB memory) costs approximately $0.064 per hour. You only pay for what you use.
Should I delete my AWS resources after this tutorial?
Yes. Delete the App Runner service, ECR repository, and IAM user to avoid ongoing charges. It is a good practice to clean up all resources after completing learning tutorials to stay within free tier limits.
