To run a Ktor server application, you need to create and configure a server first. Server configuration can include different settings: a server engine, various engine-specific options, host and port values, and so on. The following engines are supported:
- Netty
- Jetty
- Tomcat
- CIO (Coroutine-based I/O)
In addition to the engines mentioned above, Ktor provides a special engine type TestEngine
for testing application logic. You can learn more about it from .
Those are the official engines developed for Ktor, but it is also possible to create your own engines and provide custom configurations for them.
{type="note"}
Before using the desired engine, you need to add the corresponding dependency to your build script:
ktor-server-netty
ktor-server-jetty
ktor-server-tomcat
ktor-server-cio
Below are examples of adding a dependency for Netty:
For testing, you need to add the
ktor-server-test-host
dependency. There is also thektor-server-servlet
dependency that allows you to run an application in a servlet container like Jetty or Tomcat. Learn more at .
A Ktor server application can be created and run in two ways: using the embeddedServer to quickly pass server parameters in code, or using EngineMain to load the configuration from the external application.conf
file.
The embeddedServer function accepts an engine factory used to create an engine of a specific type. In the example below, we pass the Netty factory to run a server with the Netty engine and listen on the 8080
port:
{src="snippets/embedded-server/src/main/kotlin/com/example/Application.kt"}
EngineMain
represents an engine for running a server. You can use the following engines:
io.ktor.server.netty.EngineMain
io.ktor.server.jetty.EngineMain
io.ktor.server.tomcat.EngineMain
io.ktor.server.cio.EngineMain
The EngineMain.main
function is used to start a server with the selected engine and loads the application module specified in the external application.conf file. In the example below, we start a server from the application's main
function:
{src="snippets/engine-main/src/main/kotlin/com/example/Application.kt"}
{src="snippets/engine-main/src/main/resources/application.conf"}
If you need to start a server using a build system task, you need to configure the required EngineMain
as the main class:
application {
mainClassName = "io.ktor.server.netty.EngineMain"
}
mainClassName = "io.ktor.server.netty.EngineMain"
<properties>
<main.class>io.ktor.server.netty.EngineMain</main.class>
</properties>
In this section, we'll take a look how to specify various engine-specific options.
The embeddedServer
function allows you to pass engine-specific options using the configure
optional parameter. This parameter includes options common for all engines and exposed by the ApplicationEngine.Configuration class.
{src="snippets/_misc/EmbeddedServerConfigureEngine.kt"}
In addition to these options, you can configure additional engine-specific properties.
{.no_toc}
Netty-specific options are exposed by the NettyApplicationEngine.Configuration class.
embeddedServer(Netty, configure = {
requestQueueLimit = 16
shareWorkGroup = false
configureBootstrap = {
// ...
}
responseWriteTimeoutSeconds = 10
}) {
// ...
}.start(true)
{.no_toc}
If you use Jetty as the engine, you can configure the Jetty server inside the configureServer block, which provides access to a Server instance.
embeddedServer(Jetty, configure = {
configureServer = { // this: Server ->
// ...
}
}) {
// ...
}.start(true)
{.no_toc}
CIO-specific options are exposed by the CIOApplicationEngine.Configuration class.
embeddedServer(CIO, configure = {
connectionIdleTimeoutSeconds = 45
}) {
// ...
}.start(true)
{.no_toc}
If you use Tomcat as the engine, you can configure it using the configureTomcat property, which provides access to a Tomcat instance.
embeddedServer(Tomcat, configure = {
configureTomcat = { // this: Tomcat ->
// ...
}
}) {
// ...
}.start(true)
If you use EngineMain
, you can specify options common for all engines in the application.conf file within the ktor.deployment
group.
ktor {
deployment {
connectionGroupSize = 2
workerGroupSize = 5
callGroupSize = 10
}
}