Docker
코드 예제: deployment-ktor-plugin
이 섹션에서는 Docker를 사용하여 애플리케이션을 패키징, 실행 및 배포하기 위해 Ktor Gradle 플러그인을 사용하는 방법을 살펴보겠습니다.
Ktor 플러그인 설치
Ktor 플러그인을 설치하려면, build.gradle.(kts) 파일의 plugins 블록에 추가하세요:
plugins {
id("io.ktor.plugin") version "3.3.3"
}plugins {
id "io.ktor.plugin" version "3.3.3"
}Ktor Gradle 플러그인을 Kotlin Multiplatform Gradle 플러그인과 함께 적용하면 Docker 통합이 자동으로 비활성화됩니다. 이들을 함께 사용하려면 다음과 같이 하세요:
- 위에서 보여준 대로 Ktor Gradle 플러그인이 적용된 JVM 전용 프로젝트를 생성합니다.
- 해당 JVM 전용 프로젝트에 Kotlin Multiplatform 프로젝트를 의존성으로 추가합니다.
이 해결 방법으로 문제가 해결되지 않는 경우, KTOR-8464에 의견을 남겨 알려주세요.
플러그인 태스크
플러그인을 설치한 후, 애플리케이션 패키징, 실행 및 배포를 위해 다음 태스크들을 사용할 수 있습니다:
buildImage: 프로젝트의 Docker 이미지를 타르볼(tarball)로 빌드합니다. 이 태스크는build디렉터리에jib-image.tar파일을 생성합니다. docker load 명령어를 사용하여 이 이미지를 Docker 데몬에 로드할 수 있습니다:Bashdocker load < build/jib-image.tarpublishImageToLocalRegistry: 프로젝트의 Docker 이미지를 빌드하고 로컬 레지스트리에 게시합니다.runDocker: 프로젝트의 이미지를 Docker 데몬으로 빌드하고 실행합니다. 이 태스크를 실행하면 Ktor 서버가 시작되며, 기본적으로http://0.0.0.0:8080에서 응답합니다. 서버가 다른 포트를 사용하도록 구성된 경우 포트 매핑을 조정할 수 있습니다.publishImage: 프로젝트의 Docker 이미지를 빌드하고 Docker Hub 또는 Google Container Registry와 같은 외부 레지스트리에 게시합니다. 이 태스크를 위해서는 ktor.docker.externalRegistry 속성을 사용하여 외부 레지스트리를 구성해야 합니다.
기본적으로 이러한 태스크들은 ktor-docker-image라는 이름과 latest 태그로 이미지를 빌드합니다. 플러그인 구성에서 이 값들을 사용자 정의할 수 있습니다.
Ktor 플러그인 구성
Docker 태스크와 관련된 Ktor 플러그인 설정을 구성하려면 build.gradle.(kts) 파일에서 ktor.docker 확장(extension)을 사용하세요:
ktor {
docker {
// ...
}
}JRE 버전
jreVersion 속성은 이미지에서 사용할 JRE 버전을 지정합니다:
ktor {
docker {
jreVersion.set(JavaVersion.VERSION_17)
}
}이미지 이름 및 태그
이미지 이름과 태그를 사용자 정의해야 하는 경우 각각 localImageName과 imageTag 속성을 사용합니다:
ktor {
docker {
localImageName.set("sample-docker-image")
imageTag.set("0.0.1-preview")
}
}포트 매핑
기본적으로 runDocker 태스크는 8080 컨테이너 포트를 8080 Docker 호스트 포트로 게시합니다. 필요한 경우 portMappings 속성을 사용하여 이 포트들을 변경할 수 있습니다. 이는 서버가 다른 포트를 사용하도록 구성된 경우 유용할 수 있습니다.
아래 예제는 8080 컨테이너 포트를 80 Docker 호스트 포트로 매핑하는 방법을 보여줍니다.
ktor {
docker {
portMappings.set(listOf(
io.ktor.plugin.features.DockerPortMapping(
80,
8080,
io.ktor.plugin.features.DockerPortMappingProtocol.TCP
)
))
}
}이 경우 http://0.0.0.0:80에서 서버에 접속할 수 있습니다.
외부 레지스트리
publishImage 태스크를 사용하여 프로젝트의 Docker 이미지를 외부 레지스트리에 게시하기 전에 ktor.docker.externalRegistry 속성을 사용하여 외부 레지스트리를 구성해야 합니다. 이 속성은 필요한 레지스트리 유형에 대한 구성을 제공하는 DockerImageRegistry 인스턴스를 받습니다:
DockerImageRegistry.dockerHub: Docker Hub를 위한DockerImageRegistry를 생성합니다.DockerImageRegistry.googleContainerRegistry: Google Container Registry를 위한DockerImageRegistry를 생성합니다.
아래 예제는 Docker Hub 레지스트리를 구성하는 방법을 보여줍니다:
ktor {
docker {
externalRegistry.set(
io.ktor.plugin.features.DockerImageRegistry.dockerHub(
appName = provider { "ktor-app" },
username = providers.environmentVariable("DOCKER_HUB_USERNAME"),
password = providers.environmentVariable("DOCKER_HUB_PASSWORD")
)
)
}
}Docker Hub 이름과 비밀번호는 환경 변수에서 가져오므로, publishImage 태스크를 실행하기 전에 이 값들을 설정해야 합니다:
export DOCKER_HUB_USERNAME=yourHubUsername
export DOCKER_HUB_PASSWORD=yourHubPasswordsetx DOCKER_HUB_USERNAME yourHubUsername
setx DOCKER_HUB_PASSWORD yourHubPassword수동 이미지 구성
필요한 경우, Ktor 애플리케이션으로 이미지를 어셈블하기 위해 직접 Dockerfile을 제공할 수 있습니다.
애플리케이션 패키징
첫 번째 단계로, 애플리케이션을 의존성과 함께 패키징해야 합니다. 예를 들어, 이는 Fat JAR 또는 실행 가능한 JVM 애플리케이션일 수 있습니다.
Docker 이미지 준비
애플리케이션을 도커화하기 위해 멀티 스테이지 빌드를 사용합니다:
- 먼저, Gradle/Maven 의존성에 대한 캐싱을 설정합니다. 이 단계는 선택 사항이지만 전체 빌드 속도를 향상시키므로 권장됩니다.
- 그런 다음,
gradle/maven이미지를 사용하여 애플리케이션이 포함된 Fat JAR를 생성합니다. - 마지막으로, 생성된 배포판은 JDK 이미지를 기반으로 생성된 환경에서 실행됩니다.
프로젝트의 루트 폴더에 다음 내용으로 Dockerfile이라는 파일을 생성합니다:
# Stage 1: Maven 의존성 캐싱
FROM maven:3.8-amazoncorretto-21 AS cache
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
# Stage 2: 애플리케이션 빌드
FROM maven:3.8-amazoncorretto-21 AS build
WORKDIR /app
COPY --from=cache /root/.m2 /root/.m2
COPY . .
RUN mvn clean package
# Stage 3: 런타임 이미지 생성
FROM amazoncorretto:21-slim AS runtime
EXPOSE 8080
WORKDIR /app
COPY --from=build /app/target/*-with-dependencies.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]첫 번째 스테이지는 빌드 관련 파일에 변경 사항이 있을 때만 의존성을 다시 다운로드하도록 보장합니다. 첫 번째 스테이지를 사용하지 않거나 다른 스테이지에서 의존성이 캐시되지 않으면 매 빌드마다 의존성이 설치됩니다.
두 번째 스테이지에서는 Fat JAR가 빌드됩니다. Gradle은 기본적으로 shadow 및 boot JAR도 지원한다는 점에 유의하세요.
빌드의 세 번째 스테이지는 다음과 같이 작동합니다:
- 사용할 이미지를 지정합니다.
- 노출할 포트를 지정합니다 (이것은 자동으로 포트를 노출하지 않으며, 컨테이너 실행 시 수행됩니다).
- 빌드 출력물의 내용을 폴더로 복사합니다.
- 애플리케이션을 실행합니다 (
ENTRYPOINT).
TIP
이 예제에서는 Amazon Corretto Docker 이미지를 사용하지만, 다음과 같은 다른 적절한 대안으로 교체할 수 있습니다:
Docker 이미지 빌드 및 실행
다음 단계는 Docker 이미지를 빌드하고 태그를 지정하는 것입니다:
docker build -t my-application .마지막으로 이미지를 시작합니다:
docker run -p 8080:8080 my-application이렇게 하면 Ktor 서버가 실행되어 https://0.0.0.0:8080에서 응답합니다.
