Ktor 3.3.1 Help

Azure App Service

This tutorial shows how to build, configure and deploy your Ktor application to Azure App Service.

Prerequisites

Before starting this tutorial, you will need the following:

Create a sample application

Create a sample application as described in Create, open and run a new Ktor project. This example shows code and commands based on the following projects: embedded-server and engine-main.

Set up the application

Step 1: Set up the port

In Azure App Service, the environment variable PORT contains the port number open for incoming requests. Depending on how you created the app in configure a Ktor server, you'll need to update your code to read this environment variable in one of two places:

  • If you used the example with port configuration in code, the PORT environment variable can be read with System.getenv() and parsed to an integer with .toIntOrNull(). Open the file Application.kt and change the port number as shown below:

    fun runBasicServer() { val port = System.getenv("PORT")?.toIntOrNull() ?: 8080 embeddedServer(Netty, port = port) { // ... }.start(wait = true) }
  • If the server configuration is defined in the config file application.conf, update it to read the PORT environment variable as in the following example:

    ktor { deployment { port = ${PORT:8080} } }

Step 2: Add plugins

Open the build.gradle.kts file and add the following lines to the plugins section:

plugins { application kotlin("jvm") id("io.ktor.plugin") version "3.3.1" // ADDED id("com.microsoft.azure.azurewebapp") version "1.10.0" // ADDED }

The io.ktor.plugin will provide the task used to create a fat JAR and the Azure WebApp Plugin for Gradle will be used to create all the required resources in Azure with ease.

Make sure a mainClass is defined in the application section, so that there's a well-defined entry point for your fat JAR:

application { mainClass.set("com.example.ApplicationKt") }

If you created the project with the engine-main template, the main class will look like the following:

application { mainClass.set("io.ktor.server.netty.EngineMain") }

Step 3: Configuration

If you already created a Java web app in App Service that you want to deploy to, you can skip this step.

Otherwise, add the following entries to build.gradle.kts at the end of the file so that the Azure Webapp Plugin creates one for you:

// Rename the fat JAR to the name that the deploy task expects ktor { fatJar { archiveFileName.set("embedded-server.jar") } } // Disable the `jar` task that Azure Plugin would normally run // to deploy the archive created by the `fatJar` task instead tasks.named("jar") { enabled = false } // Ensure the deploy task builds the fat JAR first tasks.named("azureWebAppDeploy") { dependsOn("buildFatJar") } // Azure Webapp Plugin configuration azurewebapp { subscription = "YOUR-SUBSCRIPTION-ID" resourceGroup = "RESOURCE-GROUP-NAME" appName = "WEBAPP-NAME" pricingTier = "YOUR-PLAN" // e.g. "F1", "B1", "P0v3", etc. region = "YOUR-REGION" // e.g. "westus2" setRuntime(closureOf<com.microsoft.azure.gradle.configuration.GradleRuntimeConfig> { os("Linux") // Or "Windows" webContainer("Java SE") javaVersion("Java 21") }) setAuth(closureOf<com.microsoft.azure.gradle.auth.GradleAuthConfig> { type = "azure_cli" }) }

For detailed descriptions of the available configuration properties, see the Webapp Configuration documentation.

  • The values for pricingTier (Service Plan) can be found for Linux and for Windows.

  • The list of values for region can be obtained with the following Azure CLI command: az account list-locations --query "[].name" --output tsv or by searching for "App Service" in the Product Availability table.

Deploy the application

To a new web app

The authentication method used by the Azure Web App Deploy plugin uses the Azure CLI. If you haven't already, log in once with az login and follow the instructions.

Finally, deploy the application by running the azureWebAppDeploy task, which is set to build the fat JAR first and then deploy:

./gradlew :embedded-server:azureWebAppDeploy
gradlew.bat :embedded-server:azureWebAppDeploy

This task will create the resource group, plan, and web app, and then deploy the fat JAR. When the deployment succeeds, you should see output like the following:

> Task: :embedded-server:azureWebAppDeploy Auth type: AZURE_CLI Username: some.username@example.com Subscription: Some Subscription(13936cf1-cc18-40be-a0d4-177fe532b3dd) Start creation Resource Group(resource-group) in region (Some Region) Resource Group (resource-group) is successfully created. Start creating App Service plan (asp-your-webapp-name)... App Service plan (asp-your-webapp-name) is successfully created Start creating Web App(your-webapp-name)... Web App(your-webapp-name) is successfully created Trying to deploy artifact to your-webapp-name... Deploying (C:\docs\ktor-documentation\codeSnippets\snippets\embedded-server\build\libs\embedded-server.jar)[jar] ... Application url: https://your-webapp-name.azurewebsites.net

When the deployment completes, you should be able to see your new web app running at the URL shown above.

To an existing web app

If you already have an existing Java web app in Azure App Service, first build the fat JAR by executing the buildFatJar task provided by the Ktor plugin:

./gradlew :embedded-server:buildFatJar
gradlew.bat :embedded-server:buildFatJar

Then, deploy the fat JAR created earlier using the following command of the Azure CLI:

az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --src-path ./path/to/embedded-server.jar --restart true

This command will upload the JAR file and restart your web app. After a while, you should see the result of the deployment:

Deployment type: jar. To override deployment type, please specify the --type parameter. Possible values: war, jar, ear, zip, startup, script, static Initiating deployment Deploying from local path: ./snippets/embedded-server/build/libs/embedded-server.jar Warming up Kudu before deployment. Warmed up Kudu instance successfully. Polling the status of sync deployment. Start Time: 2025-09-07 00:07:14.729383+00:00 UTC Status: Build successful. Time: 5(s) Status: Starting the site... Time: 23(s) Status: Starting the site... Time: 41(s) Status: Site started successfully. Time: 44(s) Deployment has completed successfully You can visit your app at: http://your-app-name.some-region.azurewebsites.net
23 October 2025