LoginSignup
7
8

More than 3 years have passed since last update.

【Kotlin for Server-Side】KtorのプロジェクトをDockerで起動する

Last updated at Posted at 2019-11-28

Kotlin for Server-Side

ServerSideの現状を以下に軽くまとめてみました。

Frameworks for Server-side Development with Kotlin

  • Spring
    • Javaでの有名なWebアプリケーションFramework
  • Vert.x
    • JVM上でReactiveアプリケーションを作成する為のToolkit
  • Ktor
    • JetBrains社が作成しているWebアプリケーションFramework
  • kotlinx.html
    • Kotlin DSL for HTML

今回は上記の中でも Ktor を試して見たいと思います。

:computer:環境構築


Ktor Project Generator で空のプロジェクトを作成し、ダウンロードします。

何も変更しない状態で「Build」を選択しプロジェクトをダウンロードします。
ダウンロードしたプロジェクトのディレクトリ構成は以下の様になってました。

.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── resources
│   ├── application.conf
│   └── logback.xml
├── settings.gradle
└── src
    └── Application.kt

※ ダウンロードしたプロジェクトのGradleのVerが 4.10 となっており、後述する Gradle Shadow を使用する際に
Versionが古いと怒られるので gradle-wrapper.properties のgradleのversionを 5.6.4 に変更してます。

また、build.gradleApplication.kt は以下の様になってました。

build.gradle
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'kotlin'
apply plugin: 'application'

group 'com.example'
version '0.0.1-SNAPSHOT'
mainClassName = "io.ktor.server.netty.EngineMain"

sourceSets {
    main.kotlin.srcDirs = main.java.srcDirs = ['src']
    test.kotlin.srcDirs = test.java.srcDirs = ['test']
    main.resources.srcDirs = ['resources']
    test.resources.srcDirs = ['testresources']
}

repositories {
    mavenLocal()
    jcenter()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile "io.ktor:ktor-server-netty:$ktor_version"
    compile "ch.qos.logback:logback-classic:$logback_version"
    testCompile "io.ktor:ktor-server-tests:$ktor_version"
}
package com.example

import io.ktor.application.*
import io.ktor.response.*
import io.ktor.request.*

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
}

:pencil: Dockerで起動できる様にする


こちらを参考に環境構築を行います。

Gradle Shadow

Jarを生成してくれる、GradleのPlugin。これを使ってjarを生成しDocker内で起動します。

build.gradle を以下に修正

buildscript {
    repositories {
        jcenter()
        maven {
        url 'https://plugins.gradle.org/m2/'
        }
    }

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.github.jengelman.gradle.plugins:shadow:5.2.0"
    }
}

apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'

group 'com.example'
version '0.0.1-SNAPSHOT'
mainClassName = "io.ktor.server.netty.EngineMain"

sourceSets {
    main.kotlin.srcDirs = main.java.srcDirs = ['src']
    test.kotlin.srcDirs = test.java.srcDirs = ['test']
    main.resources.srcDirs = ['resources']
    test.resources.srcDirs = ['testresources']
}

repositories {
    mavenLocal()
    jcenter()
    maven { url "https://dl.bintray.com/kotlin/ktor" }
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile "io.ktor:ktor-server-netty:$ktor_version"
    compile "ch.qos.logback:logback-classic:$logback_version"
    testCompile "io.ktor:ktor-server-tests:$ktor_version"
}

shadowJar {
    baseName = 'my-application'
    classifier = null
    version = null
}

以下のDockerfileをプロジェクト直下に追加

FROM openjdk:8-jdk

RUN mkdir /app
WORKDIR /app

ADD . $WORKDIR
RUN ./gradlew wrapper # gradle wrapper関連を諸々アップデート

起動時にkickするshellを作成 bin/start_server.sh

#!/bin/bash
set -e
source ~/.bashrc

./gradlew build
cp ./build/libs/my-application.jar .
java -server -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=2 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=2 -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+UseStringDeduplication -jar my-application.jar

docker-compose.yml を以下の内容で作成する。

version: '3'

services:
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - '8080:8080'
    volumes:
      - .:/app
    command:
      bin/start_server.sh

あとは docker-compose up で起動し、http://0.0.0.0:8080 にアクセスできればOKです。
作成したプロジェクトはこちらにアップしてます。

:bomb: バッドノウハウ


* What went wrong:
A problem occurred evaluating root project 'ktor-demo'.
> Failed to apply plugin [class 'com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin']
   > This version of Shadow supports Gradle 5.0+ only. Please upgrade.

gradleのバージョンが古い。こちらを参考に、
gradle/wrapper/gradle-wrapper.properties のversionを変更し、./gradlew wrapper を実行する
gradleのversionはこちらで確認できる。


* What went wrong:
Execution failed for task ':compileKotlin'.
> Kotlin could not find the required JDK tools in the Java installation '/usr/lib/jvm/java-1.8-openjdk/jre' used by Gradle. Make sure Gradle is running on a JDK, not JRE.

エラーメッセージの通りで、JREではなくJDKを指定する。
参考のリポジトリのDockerfileが ROM openjdk:8-jre-alpine になっている為、openjdk:8-jdk に修正する。

:link: 参考になったURL


7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8