-
Notifications
You must be signed in to change notification settings - Fork 344
Add docs on deployment of Ktor apps to Azure App Service #671
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new Publishing TOC entry for Azure App Service and a new topic file Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Pre-merge checks (3 passed)✅ Passed checks (3 passed)
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal). Please share your feedback with us on this Discord post. ✨ Finishing touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (10)
topics/azure-app-service.md (10)
37-46
: Add language to fenced block (application.conf) to satisfy MD040Specify the language for proper highlighting and to appease markdownlint.
Apply:
-``` +```hocon ... -``` +```
47-48
: Add a blank line after the headingImproves readability and fixes the grammar/lint warning.
-### Step 2: Add plugins {id="plugins"} -Open the `build.gradle.kts` file and add the following lines to the `plugins` section: +### Step 2: Add plugins {id="plugins"} + +Open the `build.gradle.kts` file and add the following lines to the `plugins` section:
60-66
: Call out EngineMain mainClass alternativeReaders following the EngineMain sample need a different
mainClass
.}
+If you used the EngineMain variant:
+
+```kotlin
+application {
- mainClass.set("io.ktor.server.netty.EngineMain")
+}
+```--- `74-86`: **Fix code fence language and typo (“farJar” → “fatJar”)** Small polish + better highlighting. ```diff -``` +```kotlin // 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 `farJar` task instead +// to deploy the archive created by the `fatJar` task instead tasks.named("jar") { enabled = false } -``` +```
111-115
: Avoid intra-page anchor flagged by MD051The fragment link to
#plugins
appears to trip MD051. Rephrase to avoid the anchor.-First, to build the fat JAR, execute the `buildFatJar` task provided by the [Ktor plugin](#plugins) running the command below: +First, to build the fat JAR, execute the `buildFatJar` task provided by the Ktor Gradle plugin:
115-122
: Clarify multi-project vs single-project task invocationYour commands assume a subproject. Add a note for single-project users.
</tabs> +Note: For single-project builds, omit the `:embedded-server:` prefix (for example, `./gradlew buildFatJar`). +
128-131
: Tighten wording on authenticationMinor clarity and concision.
-The authentication method used by the Azure Web App Deploy plugin used in the configuration added earlier will use the Azure CLI. If you haven't done so, log in once with `az login` and follow the instructions. +The Azure Web App Gradle plugin is configured to authenticate via the Azure CLI. If you haven't already, run `az login` and follow the prompts.
143-157
: Add language to fenced block (deployment logs) to satisfy MD040Mark as
text
for readability and linter happiness.-``` +```text ... -``` +```
165-167
: Add language to fenced block (CLI) to satisfy MD040Mark as
bash
.-``` +```bash az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --src-path ./path/to/embedded-server.jar --restart true -``` +```
88-104
: AddclosureOf
import and deploy fat JAR viasetDeployment
- Import
org.gradle.kotlin.dsl.closureOf
at the top of yourbuild.gradle.kts
soclosureOf<…>
resolves.- Replace renaming/disabling tasks with an explicit
setDeployment
block pointing at your fat JAR:import org.gradle.kotlin.dsl.closureOf plugins { id("com.microsoft.azure.azurewebapp") version "1.10.0" } azurewebapp { subscription = "<YOUR_SUBSCRIPTION_ID>" resourceGroup = "<YOUR_RESOURCE_GROUP>" appName = "<YOUR_APP_NAME>" pricingTier = "P1v2" region = "centralus" setRuntime(closureOf<com.microsoft.azure.gradle.configuration.GradleRuntimeConfig> { os("Linux") webContainer("Java SE") javaVersion("Java 21") }) setDeployment(closureOf<com.microsoft.azure.gradle.configuration.GradleDeploymentConfig> { resources(closureOf<com.microsoft.azure.gradle.configuration.GradleDeploymentResources> { resource(closureOf<com.microsoft.azure.gradle.configuration.GradleDeploymentResource> { type("jar") directory("${project.buildDir}/libs") includes(closureOf<MutableList<String>> { add("embedded-server-all.jar") }) }) }) }) setAuth(closureOf<com.microsoft.azure.gradle.auth.GradleAuthConfig> { type = "azure_cli" }) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
ktor.tree
(1 hunks)topics/azure-app-service.md
(1 hunks)
🧰 Additional context used
🪛 LanguageTool
topics/azure-app-service.md
[grammar] ~47-~47: There might be a mistake here.
Context: ... ### Step 2: Add plugins {id="plugins"} Open the build.gradle.kts
file and add...
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
topics/azure-app-service.md
37-37: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
74-74: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
113-113: Link fragments should be valid
(MD051, link-fragments)
143-143: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
165-165: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
171-171: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
ktor.tree (1)
261-261
: TOC entry looks goodNice addition under Publishing; consistent with neighboring entries.
…updated version of Ktor plugin, renamed JAR file in log example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (7)
topics/azure-app-service.md (7)
22-26
: Tighten wording for clarity.-Here we'll specify the port number where to listen for requests. +Specify the port the app listens on.
38-46
: Add language to fenced code block (fixes MD040).- ``` + ```hocon ktor { deployment { port = ${PORT:8080} } } ```
74-104
: Code fence language + typo in comment ("farJar" → "fatJar").-``` +```kotlin // 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 `farJar` task instead +// to deploy the archive created by the `fatJar` task instead tasks.named("jar") { enabled = false } // Azure Webapp Plugin configuration azurewebapp {
113-113
: Fix linted fragment link (MD051).The custom ID may not be recognized by markdownlint. Simplest: drop the fragment link.
-First, to build the fat JAR, execute the `buildFatJar` task provided by the [Ktor plugin](#plugins) running the command below: +First, to build the fat JAR, execute the `buildFatJar` task provided by the Ktor plugin:
143-157
: Add language to log block (fixes MD040).-``` +```text > Task: :embedded-server:azureWebAppDeploy Auth type: AZURE_CLI Username: [email protected] 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--- `165-167`: **Add language to CLI block (fixes MD040).** ```diff -``` +```bash az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --src-path ./path/to/embedded-server.jar --restart true
--- `171-184`: **Add language to log block (fixes MD040).** ```diff -``` +```text 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
</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: CodeRabbit UI **Review profile**: CHILL **Plan**: Pro <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 26e469797f53b1f96e3652b5b945ec695409a984 and 35dbe8502e45687b13281c1c1d75ecfdbcb62f48. </details> <details> <summary>📒 Files selected for processing (1)</summary> * `topics/azure-app-service.md` (1 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> <details> <summary>topics/azure-app-service.md</summary> 38-38: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 74-74: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 113-113: Link fragments should be valid (MD051, link-fragments) --- 143-143: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 165-165: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 171-171: Fenced code blocks should have a language specified (MD040, fenced-code-language) </details> </details> </details> <details> <summary>🔇 Additional comments (4)</summary><blockquote> <details> <summary>topics/azure-app-service.md (4)</summary><blockquote> `28-35`: **Good: safe PORT handling with fallback.** Reading PORT via toIntOrNull with 8080 default is correct and avoids crashes. --- `16-16`: **Fix empty link text (renders nothing).** Provide anchor text for the link. ```diff -Create a sample application as described in [](server-create-a-new-project.topic). This example will show code and commands based on the following projects: [embedded-server](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/embedded-server) and [engine-main](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/engine-main). +Create a sample application as described in [Create a new Ktor project](server-create-a-new-project.topic). This example will show code and commands based on the following projects: [embedded-server](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/embedded-server) and [engine-main](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/engine-main).
⛔ Skipped due to learnings
Learnt from: osipxd PR: ktorio/ktor-documentation#602 File: topics/client-responses.md:91-91 Timestamp: 2025-03-24T15:17:05.086Z Learning: In Writerside (the documentation engine used for Ktor docs), empty link brackets `[]()` are a special syntax feature. Without any text in the brackets, Writerside will automatically use the title of the referenced element or the URL if it is an external link. This is intentional and not an error.
132-139
: No changes required;azureWebAppDeploy
is the correct, case-sensitive task name.
49-56
: No update needed for Azure WebApp Gradle plugin version. Version 1.10.0 (released Jan 10, 2024) is the latest stable release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
topics/azure-app-service.md (1)
72-104
: Kotlin DSL: add missing import for closureOf or the snippet won’t compileWithout this import, copy-paste fails in build.gradle.kts.
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: +Add this import at the very top of `build.gradle.kts`: + +```kotlin +import org.gradle.kotlin.dsl.closureOf +``` + ```kotlin // Rename the fat JAR to the name that the deploy task expects ktor {
🧹 Nitpick comments (6)
topics/azure-app-service.md (6)
12-12
: Update Azure CLI link to Learn domainUse the Learn URL to avoid redirects.
-* The [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) installed in your machine. +* The [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed on your machine.
38-44
: Add language to fenced code block (HOCON) to satisfy markdownlintThis fixes MD040 and improves highlighting.
- ``` + ```hocon ktor { deployment { port = ${PORT:8080} } } ```
24-35
: Add note to bind to 0.0.0.0 (not only localhost)Avoids “listens only on loopback” issues on App Service.
}.start(wait = true) }+> Note: Ensure the server binds to 0.0.0.0 (the default for Netty). Do not bind only to localhost, or the app won’t be reachable from App Service.
--- `60-66`: **Clarify mainClass for engine-main projects** Users of engine-main should set EngineMain. ```diff }
+If you created the project with the “engine-main” template, set:
+
+```kotlin
+application {
- mainClass.set("io.ktor.server.netty.EngineMain")
+}
+```--- `75-86`: **Make deployment depend on fat JAR build** Prevents deploying a stale or missing artifact. ```diff tasks.named("jar") { enabled = false } +// Ensure the deploy task builds the fat JAR first +tasks.named("azureWebAppDeploy") { + dependsOn("buildFatJar") +}
Please verify that the Gradle task name matches the plugin’s deploy task in your environment.
183-183
: Use HTTPS for final app URL (consistency and security)Earlier example uses HTTPS; align this one too.
-You can visit your app at: http://your-app-name.some-region.azurewebsites.net +You can visit your app at: https://your-app-name.some-region.azurewebsites.net
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
topics/azure-app-service.md
(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
topics/azure-app-service.md
38-38: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
113-113: Link fragments should be valid
(MD051, link-fragments)
🔇 Additional comments (2)
topics/azure-app-service.md (2)
113-115
: Anchor check: verify (#plugins) resolves on the siteStatic analysis flagged MD051. If your site generator doesn’t honor
{id="plugins"}
, consider linking to the generated heading anchor or keep the explicit id but confirm it renders.
53-55
: Confirm plugin versions before publishing
%ktor_version%
is good; please verify the Azure WebApp Gradle plugin version is the latest recommended at release time.If needed, I can help run a quick check and update the pin.
…ldFatJar, moved buildFatJar paragraph to existing webapp case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
topics/azure-app-service.md (1)
108-116
: Kotlin DSL: add missing closureOf import or avoid it.Without
import org.gradle.kotlin.dsl.closureOf
, copy-paste fails. Alternatively, use the plugin’s Kotlin lambda overloads if available.Add at the top of build.gradle.kts:
import org.gradle.kotlin.dsl.closureOfOr replace with actions (if supported by the plugin):
setRuntime(Action<com.microsoft.azure.gradle.configuration.GradleRuntimeConfig> { os("Linux"); webContainer("Java SE"); javaVersion("Java 21") }) setAuth(Action<com.microsoft.azure.gradle.auth.GradleAuthConfig> { type = "azure_cli" })
🧹 Nitpick comments (5)
topics/azure-app-service.md (5)
38-46
: Specify code-fence language for application.conf.Adds syntax highlighting and fixes MD040.
- ``` + ```hocon ktor { deployment { port = ${PORT:8080} } } ```
24-35
: Consider documenting bind host = 0.0.0.0.Some setups bind to loopback by default; being explicit avoids “site up but not reachable” issues.
fun runBasicServer() { val port = System.getenv("PORT")?.toIntOrNull() ?: 8080 - embeddedServer(Netty, port = port) { + embeddedServer(Netty, port = port, host = "0.0.0.0") { // ... }.start(wait = true) }Alternatively, in application.conf:
ktor { deployment { host = 0.0.0.0 port = ${PORT:8080} } }
163-171
: Tighten grammar and ensure internal anchor passes linters.Small grammar fix; also rephrase the link text while keeping the same
#plugins
anchor.-If you had an existing Java web app in Azure App Service build the fat JAR, executing the `buildFatJar` task provided by the [Ktor plugin](#plugins): +If you have an existing Java web app in Azure App Service, build the fat JAR by executing the `buildFatJar` task provided in [Step 2: Add plugins](#plugins):
176-178
: Be explicit about deployment type.
az webapp deploy
usually auto-detects, but--type jar
removes ambiguity.-az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --src-path ./path/to/embedded-server.jar --restart true +az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --type jar --src-path ./path/to/embedded-server.jar --restart true
5-7
: Avoid repeating the opening sentence.The paragraph duplicates the link-summary.
-This tutorial shows how to build, configure and deploy your Ktor application to Azure App Service. +This tutorial shows how to build, configure, and deploy your Ktor application to Azure App Service.(If you keep both, at least fix the serial comma.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
topics/azure-app-service.md
(1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
topics/azure-app-service.md
38-38: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
163-163: Link fragments should be valid
(MD051, link-fragments)
🔇 Additional comments (3)
topics/azure-app-service.md (3)
90-100
: Confirm deployment artifact selection with the Azure plugin.Disabling
jar
and renaming the fat JAR is fine; please verify the plugin indeed picksbuild/libs/embedded-server.jar
without extra config, and that no other JARs in that folder cause ambiguity.
16-16
: Fix empty link text (broken Markdown).The link has no visible text, which renders incorrectly.
-Create a sample application as described in [](server-create-a-new-project.topic). This example will show code and commands based on the following projects: [embedded-server](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/embedded-server) and [engine-main](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/engine-main). +Create a sample application as described in [Create a new Ktor project](server-create-a-new-project.topic). This example will show code and commands based on the following projects: [embedded-server](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/embedded-server) and [engine-main](https://github.com/ktorio/ktor-documentation/tree/%ktor_version%/codeSnippets/snippets/engine-main).⛔ Skipped due to learnings
Learnt from: osipxd PR: ktorio/ktor-documentation#602 File: topics/client-responses.md:91-91 Timestamp: 2025-03-24T15:17:05.086Z Learning: In Writerside (the documentation engine used for Ktor docs), empty link brackets `[]()` are a special syntax feature. Without any text in the brackets, Writerside will automatically use the title of the referenced element or the URL if it is an external link. This is intentional and not an error.
50-55
: Bump Ktor plugin version to 3.1.3
Azure WebApp plugin1.10.0
is already the latest stable release; update the Ktor placeholder to match the currentio.ktor.plugin
version:- id("io.ktor.plugin") version "%ktor_version%" + id("io.ktor.plugin") version "3.1.3"Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
topics/azure-app-service.md (1)
101-116
: Kotlin DSL: closureOf requires an import; or switch to Action-style blocks.As-is, users copying this into build.gradle.kts will hit “Unresolved reference: closureOf.” Add the import, or (if supported by the plugin) use Kotlin Action-lambda overloads.
Add at the top of build.gradle.kts:
import org.gradle.kotlin.dsl.closureOfOr replace with Action-style configuration (if available):
azurewebapp { // ... runtime { os = "Linux" webContainer = "Java SE" javaVersion = "Java 21" } auth { type = "azure_cli" } }Can you confirm whether the plugin exposes these Kotlin DSL accessors? If not, keep closureOf with the import.
🧹 Nitpick comments (6)
topics/azure-app-service.md (6)
5-8
: Avoid repeating the intro sentence.The sentence on Line 7 duplicates the link-summary. Consider removing or rephrasing Line 7.
-This tutorial shows how to build, configure and deploy your Ktor application to Azure App Service. +In this guide, you’ll build, configure, and deploy a Ktor app to Azure App Service.
38-44
: Add language to fenced code block (HOCON).This fixes MD040 and improves highlighting.
-``` +```hocon ktor { deployment { port = ${PORT:8080} } }--- `121-123`: **Tiny enhancement: show how to fetch subscription/regions.** Consider adding a tip under this list for quick retrieval. ```diff * The list of values for `region` can be obtained with the following Azure CLI command: `az account list-locations --query "[].name" --output tsv` or search "App Service" in [this page](https://go.microsoft.com/fwlink/?linkid=2300348&clcid=0x409). +* To get your current subscription ID: `az account show --query id -o tsv`
128-131
: Tighten wording around authentication.Minor grammar/readability tweak.
-The authentication method used by the Azure Web App Deploy plugin used in the configuration added earlier will use the Azure CLI. If you haven't done so, log in once with `az login` and follow the instructions. +The Azure WebApp Gradle plugin is configured to authenticate via the Azure CLI. If you haven’t already, run `az login` and follow the prompts.
176-178
: Be explicit about artifact type in az webapp deploy.App Service usually auto-detects, but adding --type jar makes the command unambiguous.
-az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --src-path ./path/to/embedded-server.jar --restart true +az webapp deploy -g RESOURCE-GROUP-NAME -n WEBAPP-NAME --type jar --src-path ./path/to/embedded-server.jar --restart true
49-56
: Update plugin version notes
- com.microsoft.azure.azurewebapp 1.10.0 is current; io.ktor.plugin latest stable is 3.1.3 (docs continue to use the %ktor_version% placeholder)
- Clarify where the Kotlin/JVM plugin version is defined (e.g., settings.gradle[kts], version catalog, or gradle.properties)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
topics/azure-app-service.md
(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-08T05:54:33.810Z
Learnt from: dfuenzalida
PR: ktorio/ktor-documentation#671
File: topics/azure-app-service.md:11-13
Timestamp: 2025-09-08T05:54:33.810Z
Learning: The Gradle wrapper (gradlew) generated by Ktor projects is sufficient for building and deploying to Azure App Service, eliminating the need for local Gradle installation as a prerequisite.
Applied to files:
topics/azure-app-service.md
📚 Learning: 2025-09-08T05:54:33.810Z
Learnt from: dfuenzalida
PR: ktorio/ktor-documentation#671
File: topics/azure-app-service.md:11-13
Timestamp: 2025-09-08T05:54:33.810Z
Learning: Azure App Service Java 21 runtime can run applications compiled with earlier Java versions, so specifying the exact JDK version as a requirement is unnecessary for Azure App Service deployments.
Applied to files:
topics/azure-app-service.md
🪛 markdownlint-cli2 (0.17.2)
topics/azure-app-service.md
38-38: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
163-163: Link fragments should be valid
(MD051, link-fragments)
🔇 Additional comments (6)
topics/azure-app-service.md (6)
11-13
: Prereqs look lean and accurate (no hard JDK pin or local Gradle requirement).Good call keeping this minimal; the Gradle wrapper suffices and Java 21 runtime on App Service can run apps compiled for earlier targets.
24-35
: PORT handling is correct and resilient.Reading PORT with a safe Int fallback (8080) and providing the application.conf alternative is spot on for App Service.
60-73
: Main class examples are clear for both templates.Good clarity for embedded-server vs engine-main.
83-99
: Build pipeline wiring is correct.Renaming the fat JAR, disabling jar, and making azureWebAppDeploy depend on buildFatJar is a pragmatic setup.
163-171
: MD051 appears to be a false positive.The fragment (#plugins) matches the explicit id on the heading. No action needed.
16-16
: Fix empty link text.The link to “server-create-a-new-project.topic” has no anchor text, which will render poorly.
-Create a sample application as described in [](server-create-a-new-project.topic). +Create a sample application as described in [Create a new Ktor project](server-create-a-new-project.topic).⛔ Skipped due to learnings
Learnt from: osipxd PR: ktorio/ktor-documentation#602 File: topics/client-responses.md:91-91 Timestamp: 2025-03-24T15:17:05.086Z Learning: In Writerside (the documentation engine used for Ktor docs), empty link brackets `[]()` are a special syntax feature. Without any text in the brackets, Writerside will automatically use the title of the referenced element or the URL if it is an external link. This is intentional and not an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @dfuenzalida, thank you for the PR. LGTM
@vnikolova, @nomisRev could you also check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution @dfuenzalida ! 🙏 It already looks pretty good. I’ve added some suggestions to improve clarity and bring it more in line with our documentation style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @dfuenzalida,
Thank you for opening this PR 🥳
Can Azure Container Registry be used instead of fatJar? This is often a preferred approach by many. Ktor has a Gradle plugin that allows publishing to external registries.
I think we can shorten the Set up the application
by mostly referring to the original pages, and perhaps introducing I'm afraid we otherwise introduce too much duplication on the website. Instead just focusing on the Azure related configuration. WDYT @vnikolova @e5l?
I think this amount of duplication is fine as it's short and it saves the user time from switching between different topics. I see we also include this set up in other deployment topics, such as for Heroku and Sevalla. |
I can look into publishing to Azure Container Registry from the Gradle plugin in an upcoming PR. My impression is that while there are some similarities with other cloud providers, the Azure Webapp Plugin might be an easier experience. |
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
Co-authored-by: Vik Nikolova <[email protected]>
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
topics/azure-app-service.md (1)
108-116
: closureOf requires an import in Kotlin DSL (or avoid closureOf entirely)As written, copy-paste into build.gradle.kts fails without the import. Either add the import or switch to the plugin’s Kotlin lambda overloads if available.
// Place at the top of build.gradle.kts import org.gradle.kotlin.dsl.closureOfOptionally replace setRuntime/setAuth + closureOf with Kotlin lambdas if supported by the plugin.
🧹 Nitpick comments (7)
topics/azure-app-service.md (7)
38-45
: Add a language to the application.conf code fence to satisfy MD040Specify HOCON for syntax highlighting and to fix the linter warning.
- ``` + ```hocon ktor { deployment { port = ${PORT:8080} } } ```
128-129
: Tighten wording of the authentication sentenceMinor clarity and style tweak.
-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. +The Azure Web App Deploy plugin authenticates via the Azure CLI. If you haven't already, run `az login` and follow the instructions.
101-116
: Consider explicitly setting the deployment artifact to avoid implicit detectionYou disable the jar task and depend on buildFatJar, which works in many setups, but future plugin changes might not pick the intended JAR automatically. Consider explicitly pointing the plugin to embedded-server.jar in the deployment config. Please verify exact DSL with the plugin docs.
119-123
: Add a note on globally unique appNameappName must be globally unique (affects the azurewebsites.net hostname). This saves users a failed first run.
Example addition right below this paragraph:
- Note: appName must be unique across all Azure App Service apps (it determines https://.azurewebsites.net).
11-13
: Add a JDK prerequisite (version‑agnostic)Building the sample requires a local JDK; the App Service runtime can still be Java 21 even if you compile for an earlier target.
Before starting this tutorial, you will need the following: * An Azure account ([Free trial here](https://azure.microsoft.com/en-us/free/)). * The [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed on your machine. +* A local JDK compatible with your project (for example, Java 17 or 21). The App Service Java 21 runtime can run applications compiled with earlier Java versions.
163-165
: Fix or verify the local anchor link to “Ktor plugin”The linter flags (#plugins). If this doc engine requires fully qualified topic anchors, switch to a topic‑scoped link; otherwise, confirm the build recognizes the custom {id="plugins"} anchor.
-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](#plugins): +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](azure-app-service.md#plugins):If the site generator auto-resolves (#plugins), keep it and ignore this change.
83-88
: Rephrase “expects” to avoid implying a hard requirementThe plugin doesn’t inherently “expect” this name; we’re standardizing it for consistency with the commands/logs.
- // Rename the fat JAR to the name that the deploy task expects + // Rename the fat JAR to a predictable name used by the deploy task and examples
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
topics/azure-app-service.md
(1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-08T05:54:33.821Z
Learnt from: dfuenzalida
PR: ktorio/ktor-documentation#671
File: topics/azure-app-service.md:11-13
Timestamp: 2025-09-08T05:54:33.821Z
Learning: The Gradle wrapper (gradlew) generated by Ktor projects is sufficient for building and deploying to Azure App Service, eliminating the need for local Gradle installation as a prerequisite.
Applied to files:
topics/azure-app-service.md
📚 Learning: 2025-09-08T05:54:33.821Z
Learnt from: dfuenzalida
PR: ktorio/ktor-documentation#671
File: topics/azure-app-service.md:11-13
Timestamp: 2025-09-08T05:54:33.821Z
Learning: Azure App Service Java 21 runtime can run applications compiled with earlier Java versions, so specifying the exact JDK version as a requirement is unnecessary for Azure App Service deployments.
Applied to files:
topics/azure-app-service.md
🪛 markdownlint-cli2 (0.17.2)
topics/azure-app-service.md
38-38: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
163-163: Link fragments should be valid
(MD051, link-fragments)
🔇 Additional comments (3)
topics/azure-app-service.md (3)
24-36
: PORT handling is correct and resilientReading PORT with toIntOrNull and defaulting to 8080 is the right approach for App Service.
60-73
: Good call-out on mainClass for fat JAR entrypointThis avoids common deployment pitfalls.
49-55
: Verify pinned plugin versions before publishing — confirmedAs of September 11, 2025: com.microsoft.azure.azurewebapp 1.10.0 is the latest stable (published January 10, 2024); io.ktor.plugin latest stable is 3.1.2 (published March 27, 2025). Keeping %ktor_version% is fine — no changes required. Confirm compatibility with your Gradle/Kotlin DSL before release.
Hi @vnikolova @nomisRev , I wanted to check if you have any other comments or changes you'd want on this PR. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update, looks good to me! 👍
This PR adds documentation on how to deploy Ktor web apps to Azure App Service either by creating a new web app or deploying to an existing one.
Feel free to suggest any edits, rewording and clarifications.
Disclaimer: I'm in the App Service Java team so I'm invested in attracting devs using Ktor to our service offering.