Creating Docker Container

预计阅读时间:5分钟

Docker是一个容器平台:它允许以某种格式打包软件,然后可以在任何受支持的操作系统中单独运行.

将Ktor应用程序发布到docker非常简单,只需几个步骤:

  • Install Docker
  • JAR打包工具

在此页面中,我们将指导您创建docker映像并向其发布应用程序.

目录:

Package an application using Gradle

在本教程中,我们将使用Gradle shadow插件 . 它将所有输出类,资源和所有必需的依赖项打包到一个JAR文件中,并附加一个清单文件以告诉Java这是包含main方法的入口点主类.

首先,您需要在build.gradle文件中添加影子插件依赖build.gradle

buildscript {
    ...
    repositories {
        ...
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        ...
        classpath "com.github.jengelman.gradle.plugins:shadow:2.0.1"
    }
}

之后,您必须将其与应用程序插件一起应用:

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

然后指定主类,这样它就知道在Docker中运行Java的JAR时要运行什么:

mainClassName = 'org.sample.ApplicationKt'

字符串是包含您的main功能的类的完全限定名称. 当main函数是文件中的顶级函数时,类名是带有Kt后缀的文件名. 在上面的示例中, main功能位于软件包org.sample中的Application.kt文件中.

最后,您必须配置影子插件:

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

现在,您可以运行./gradlew build来构建和打包您的应用程序. 您应该在build/libs文件夹中获取my-application.jar .

有关配置此插件的更多信息,请参见该插件的文档.

因此,完整的build.gradle文件将如下所示:

build.gradle
buildscript {
    ext.kotlin_version = '1.3.60'
    ext.ktor_version = '1.2.6'
    ext.logback_version = '1.2.3'
    ext.slf4j_version = '1.7.25'
    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:2.0.1"
    }
}

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

mainClassName = "io.ktor.server.netty.EngineMain"

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

repositories {
    jcenter()
}

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

kotlin.experimental.coroutines = 'enable'

shadowJar {
    baseName = 'my-application'
    classifier = null
    version = null
}
resources/application.conf
ktor {
    deployment {
        port = 8080
    }

    application {
        modules = [ io.ktor.samples.hello.HelloApplicationKt.main ]
    }
}
src/HelloApplication.kt
package io.ktor.samples.hello

import io.ktor.application.*
import io.ktor.features.*
import io.ktor.html.*
import io.ktor.routing.*
import kotlinx.html.*

fun Application.main() {
    install(DefaultHeaders)
    install(CallLogging)
    routing {
        get("/") {
            call.respondHtml {
                head {
                    title { +"Ktor: jetty" }
                }
                body {
                    p {
                        +"Hello from Ktor Jetty engine sample application"
                    }
                }
            }
        }
    }
}

您可以在ktor-samples存储库中查看完整的示例 .

Prepare Docker image

在项目的根文件夹中,创建一个名为Dockerfile的文件,其内容如下:

Dockerfile
FROM openjdk:8-jre-alpine

ENV APPLICATION_USER ktor
RUN adduser -D -g '' $APPLICATION_USER

RUN mkdir /app
RUN chown -R $APPLICATION_USER /app

USER $APPLICATION_USER

COPY ./build/libs/my-application.jar /app/my-application.jar
WORKDIR /app

CMD ["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"]

让我们看看是什么:

FROM openjdk:8-jre-alpine

该行告诉Docker使用Alpine Linux将映像基于预先构建的映像. 您可以使用OpenJDK注册表中的其他图像. Alpine Linux的好处是图像很小. 我们也选择仅JRE映像,因为我们不需要在映像上编译代码,只需运行预编译的类即可.

RUN mkdir /app
COPY ./build/libs/my-application.jar /app/my-application.jar
WORKDIR /app

这些行将打包的应用程序复制到Docker映像中,并将工作目录设置为我们将其复制到的位置.

CMD ["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使用G10s GC,4G内存和打包的应用程序运行java .

Building and running the Docker image

构建一个应用程序包:

./gradlew build

构建并标记图像:

docker build -t my-application .

开始图像:

docker run -m512M --cpus 2 -it -p 8080:8080 --rm my-application

使用此命令,我们以前台模式启动Docker. 它将等待服务器退出,并且还将响应Ctrl+C使其停止. -it指示Docker分配一个终端( tty ),以传递标准输出并响应中断键序列.

由于我们的服务器现在在隔离的容器中运行,因此我们应该告诉Docker公开一个端口,以便我们可以实际访问服务器端口. 参数-p 8080:8080告诉Docker从容器内部将端口8080发布为本地计算机上的端口8080. 因此,当您告诉浏览器访问localhost:8080 ,它将首先到达Docker,并将其桥接到应用程序的内部端口8080中.

您可以使用-m512M调整内存,并使用--cpus 2调整暴露的cpus数量.

默认情况下,即使容器退出后,容器的文件系统--rm ,因此我们提供--rm选项以防止垃圾堆积.

有关运行docker映像的更多信息,请查阅docker run文档.

Pushing docker image

Once your application is running locally successfully, it might be a time to deploy it:

docker tag my-application hub.example.com/docker/registry/tag
docker push hub.example.com/docker/registry/tag

这些命令将标记您的应用程序以注册并推送图像. 当然,您需要使用注册表的实际URL替换hub.example.com/docker/registry/tag .

由于您的配置可能需要身份验证,特定的配置选项甚至是特殊的工具,因此我们在这里不做详细介绍. 请咨询您的组织或云平台,或查看docker push文档.

Sample

您可以在ktor-samples存储库中查看完整的样本 .

by  ICOPY.SITE