Ktor 3.5.0 Help

Configuration in a file

Ktor allows you to configure various server parameters, such as a host address and port, modules to load, and so on. The configuration depends on the way you used to create a server - embeddedServer or EngineMain.

For EngineMain, Ktor loads its configuration from a configuration file that uses the HOCON or YAML format. This way provides more flexibility to configure a server and allows you to change a configuration without recompiling your application. Moreover, you can run your application from a command line and override the required server parameters by passing corresponding command-line arguments.

Overview

If you use EngineMain to start a server, Ktor loads configuration settings automatically from a file named application.* located in the resources directory. Two configuration formats are supported:

  • HOCON (application.conf)

  • YAML (application.yaml)

A configuration file should contain at least modules to load specified using the ktor.application.modules property, for example:

ktor { application { modules = [ com.example.ApplicationKt.module ] } }
ktor: application: modules: - com.example.ApplicationKt.module

In this case, Ktor calls the Application.module function in the Application.kt file below:

package com.example import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) fun Application.module() { routing { get("/") { call.respondText("Hello, world!") } } }

Besides modules to load, you can configure various server settings, including predefined (such as a port or host, SSL settings, etc.) and custom ones. Let's take a look at several examples.

Basic configuration

In the example below, a server listening port is set to 8080 using the ktor.deployment.port property.

ktor { deployment { port = 8080 } application { modules = [ com.example.ApplicationKt.module ] } }
ktor: deployment: port: 8080 application: modules: - com.example.ApplicationKt.module

Engine configuration

If you use EngineMain, you can specify options common for all engines within the ktor.deployment group.

ktor { deployment { connectionGroupSize = 2 workerGroupSize = 5 callGroupSize = 10 shutdownGracePeriod = 2000 shutdownTimeout = 3000 } }
ktor: deployment: connectionGroupSize: 2 workerGroupSize: 5 callGroupSize: 10 shutdownGracePeriod: 2000 shutdownTimeout: 3000

Netty

You can also configure Netty-specific options in a configuration file within the ktor.deployment group:

ktor { deployment { maxInitialLineLength = 2048 maxHeaderSize = 1024 maxChunkSize = 42 } }
ktor: deployment: maxInitialLineLength: 2048 maxHeaderSize: 1024 maxChunkSize: 42

SSL configuration

The example below enables Ktor to listen on the 8443 SSL port and specifies the required SSL settings in a separate security block.

ktor { deployment { port = 8080 sslPort = 8443 } application { modules = [ com.example.ApplicationKt.module ] } security { ssl { keyStore = keystore.jks keyAlias = sampleAlias keyStorePassword = foobar privateKeyPassword = foobar trustStore = truststore.jks trustStorePassword = foobar enabledProtocols = ["TLSv1.2", "TLSv1.3"] } } }
ktor: deployment: port: 8080 sslPort: 8443 application: modules: - com.example.ApplicationKt.module security: ssl: keyStore: keystore.jks keyAlias: sampleAlias keyStorePassword: foobar privateKeyPassword: foobar trustStore: truststore.jks trustStorePassword: foobar enabledProtocols: ["TLSv1.2", "TLSv1.3"]

Custom configuration

Apart from specifying the predefined properties, Ktor allows you to keep custom settings in the configuration file. The configuration files below contain a custom jwt group used to keep JWT settings.

ktor { deployment { port = 8080 } application { modules = [ com.example.ApplicationKt.main ] } } jwt { secret = "secret" issuer = "http://0.0.0.0:8080/" audience = "http://0.0.0.0:8080/hello" realm = "Access to 'hello'" }
ktor: deployment: port: 8080 application: modules: - com.example.ApplicationKt.main jwt: secret: "secret" issuer: "http://0.0.0.0:8080/" audience: "http://0.0.0.0:8080/hello" realm: "Access to 'hello'"

You can read and handle such settings in code.

Predefined properties

Below is a list of predefined settings that you can use inside a configuration file.

ktor.deployment.host

A host address.

Example: 0.0.0.0

ktor.deployment.port

A listening port. You can set this property to 0 to run the server on a random port.

Example: 8080, 0

ktor.deployment.sslPort

A listening SSL port. You can set this property to 0 to run the server on a random port.

Example: 8443, 0

ktor.deployment.watch

Watch paths used for auto-reloading.

ktor.deployment.rootPath

A servlet context path.

Example: /

ktor.deployment.shutdown.url

A shutdown URL. Note that this option uses the Shutdown URL plugin.

ktor.deployment.shutdownGracePeriod

A maximum time in milliseconds for a server to stop accepting new requests.

ktor.deployment.shutdownTimeout

A maximum time in milliseconds to wait until the server stops completely.

ktor.deployment.callGroupSize

A minimum size of a thread pool used to process application calls.

ktor.deployment.connectionGroupSize

A count of threads used to accept new connections and start call processing.

ktor.deployment.workerGroupSize

A size of the event group for processing connections, parsing messages, and doing the engine's internal work.

If you've set ktor.deployment.sslPort, you need to specify the following SSL-specific properties:

ktor.security.ssl.keyStore

An SSL key store.

ktor.security.ssl.keyAlias

An alias for the SSL key store.

ktor.security.ssl.keyStorePassword

A password for the SSL key store.

ktor.security.ssl.privateKeyPassword

A password for the SSL private key.

Environment variables

In a configuration file, you can substitute parameters with environment variables.

  • In HOCON (application.conf), only the ${ENV} syntax is supported.

  • In YAML (application.yaml), both ${ENV} and $ENV syntaxes are supported.

For example, you can assign the PORT environment variable to the ktor.deployment.port property in the following way:

ktor { deployment { port = ${PORT} } }
ktor: deployment: port: ${PORT} # or $PORT

In this case, an environment variable value will be used to specify a listening port. If the PORT environment variable variable doesn't exist at runtime, you can provide a default port value as follows:

ktor { deployment { port = 8080 port = ${?PORT} } }
ktor: deployment: port: ${PORT:8080} # or "$PORT:8080"

Read configuration in code

Ktor allows you to access property values specified in a configuration file from your application code. In the following example, you've specified the ktor.deployment.port property:

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

You can access the application's configuration using the ApplicationEnvironment.config() function and retrieve property values. Use the .property() function to access required values or .propertyOrNull() for optional ones:

fun Application.module() { val port = environment.config.propertyOrNull("ktor.deployment.port")?.getString() ?: "8080" routing { get { call.respondText("Listening on port $port") } } }

Deserialize configuration into data classes

You can deserialize configuration into Kotlin data classes using the .getAs() function. This approach provides type-safe access to configuration values.

The example below defines app and security configuration sections and maps them to serializable Kotlin data classes.

app { port = 8080 host = "0.0.0.0" } security { clientId = ${?CLIENT_ID} clientSecret = ${?CLIENT_SECRET} }
app: port: 8080 host: "0.0.0.0" security: clientId: $CLIENT_ID clientSecret: $CLIENT_SECRET
@Serializable data class App(val port: Int, val host: String) @Serializable data class Security(val clientId: String, val clientSecret: String) @Serializable data class Config(val app: App, val security: Security) fun Application.module() { val config = environment.config.getAs<Config>() val clientId = config.security.clientId val clientSecret = config.security.clientSecret println("Authorization header: $clientId:$clientSecret") }

Command line

If you use EngineMain to create a server, you can run a packaged application from a command line and override the required server parameters by passing corresponding command-line arguments. For example, you can override a port specified in a configuration file in the following way:

java -jar sample-app.jar -port=8080

The available command-line options are listed below:

-jar

A path to JAR file.

-config

A path to a custom configuration file used instead of application.conf/application.yaml from resources.

Example: java -jar sample-app.jar -config=anotherfile.conf

Note: You can pass multiple values. java -jar sample-app.jar -config=config-base.conf -config=config-dev.conf. In this case all configs will be merged, where values from configs on the right will have priority.

-host

A host address.

-port

A listening port.

-watch

Watch paths used for auto-reloading.

SSL-specific options:

-sslPort

A listening SSL port.

-sslKeyStore

An SSL key store.

If you need to override a predefined property that doesn't have a corresponding command-line option, use the -P flag, for example:

java -jar sample-app.jar -P:ktor.deployment.callGroupSize=7

You can also use the -P flag to override a custom property.

Example: Specify an environment using a custom property

You can use custom configuration properties to change application behavior depending on the environment in which the server is running, such as local development or production.

To do this, define a custom property in application.conf or application.yaml and assign its value from an environment variable. In the example below, the KTOR_ENV environment variable is assigned to the custom ktor.environment property. The value of KTOR_ENV can then be set differently for local and production environments.

ktor { environment = ${?KTOR_ENV} }
ktor: environment: $?KTOR_ENV

You can access the ktor.environment value at runtime by reading configuration in code and perform the required actions:

import io.ktor.server.application.* import io.ktor.server.response.* import io.ktor.server.routing.* fun Application.module() { val env = environment.config.propertyOrNull("ktor.environment")?.getString() routing { get { call.respondText(when (env) { "dev" -> "Development" "prod" -> "Production" else -> "..." }) } } }

For the full code example, see engine-main-custom-environment.

15 May 2026