Ktor 3.0.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

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 } } }
ktor: deployment: port: 8080 sslPort: 8443 application: modules: - com.example.ApplicationKt.module security: ssl: keyStore: keystore.jks keyAlias: sampleAlias keyStorePassword: foobar privateKeyPassword: foobar

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 by using the ${ENV}/$ENV syntax. 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

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"

Read configuration in code

Ktor allows you to access property values specified inside a configuration file in code. For example, if you've specified the ktor.deployment.port property,...

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

... you can access the application's configuration using ApplicationEnvironment.config and get the required property value in the following way:

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

This is especially useful when you keep custom settings in a configuration file and need to access its values.

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: How to specify an environment using a custom property

You might want to do different things depending on whether a server is running locally or on a production machine. To achieve this, you can add a custom property in application.conf/application.yaml and initialize it with a dedicated environment variable whose value depends on whether a server is running locally or on production. In the example below, the KTOR_ENV environment variable is assigned to a custom ktor.environment property.

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 -> "..." }) } } }

You can find the full example here: engine-main-custom-environment.

Last modified: 03 April 2023