Configuration in a file
Edit pageLast modified: 13 December 2024Ktor 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)
note
To use a YAML configuration file, you need to add the
ktor-server-config-yaml
dependency.
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
}
}
}
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.
warning
Note that sensitive data (like secret keys, database connection settings, and so on) should not be stored in the configuration file as plain text. Consider using environment variables to specify such parameters.
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
note
Note that SSL requires additional options listed below.
- 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.