Por que a containerização Kotlin é um must-have para o desenvolvedor moderno?
\n\nImagine a situação: você escreveu uma aplicação Kotlin incrível no seu MacBook. Tudo funciona perfeitamente. Você envia o código para um colega no Windows — o banco de dados não conecta. Para outro no Linux — a versão do JDK não é a mesma. Familiar? O Docker resolve esse problema de uma vez por todas.
\n\nA containerização de aplicações Kotlin não é apenas uma tendência da moda. É uma forma de garantir que sua aplicação funcione da mesma forma em qualquer máquina: do laptop de um júnior ao servidor de produção na AWS. Neste artigo, vamos abordar como empacotar corretamente uma aplicação Kotlin em uma imagem Docker, otimizar seu tamanho e configurá-la para produção.
\n\nO que você aprenderá:
\n- \n
- Como escrever um Dockerfile para uma aplicação Kotlin com Gradle \n
- Como reduzir o tamanho da imagem em 3-5 vezes \n
- Como usar o Docker Compose para integrar Kotlin + banco de dados \n
- Best practices para containerização em produção \n
Dockerfile básico para aplicação Kotlin
\n\nVamos começar com o simples. Suponha que você tenha uma aplicação Kotlin padrão que é compilada com Gradle. A primeira coisa que vem à mente é pegar uma imagem JDK, copiar os fontes e executar a compilação. Vamos fazer isso, mas já considerando as best practices.
\n\nCompilação monolítica (não faça isso em produção)
\n\n# Dockerfile\nFROM gradle:7.6-jdk17 AS build\nWORKDIR /app\nCOPY build.gradle.kts settings.gradle.kts ./\nCOPY src ./src\nRUN gradle build --no-daemon -x test\n\nFROM openjdk:17-jdk-slim\nWORKDIR /app\nCOPY --from=build /app/build/libs/app.jar app.jar\nEXPOSE 8080\nCMD ["java", "-jar", "app.jar"]\n\nEssa abordagem funciona, mas tem três desvantagens sérias:
\n- \n
- Tamanho: a imagem pesa cerca de 400-500 MB devido ao JDK completo \n
- Cache: qualquer alteração nos fontes fará o Gradle baixar as dependências novamente \n
- Segurança: ferramentas de compilação desnecessárias em tempo de execução permanecem na imagem \n
Compilação otimizada: multi-estágios e cache
\n\nA verdadeira magia do Docker são as multi-stage builds. Vamos dividir o processo em três etapas:
\n- \n
- Download das dependências (em cache) \n
- Compilação da aplicação \n
- Imagem final mínima \n
Dockerfile correto para Kotlin + Gradle
\n\n# Stage 1: Download das dependências\nFROM gradle:7.6-jdk17 AS dependencies\nWORKDIR /app\nCOPY build.gradle.kts settings.gradle.kts ./\nRUN gradle dependencies --no-daemon\n\n# Stage 2: Compilação\nFROM dependencies AS build\nCOPY src ./src\nRUN gradle build --no-daemon -x test\n\n# Stage 3: Imagem final\nFROM eclipse-temurin:17-jre-alpine\nWORKDIR /app\nCOPY --from=build /app/build/libs/app.jar app.jar\nRUN addgroup -S appgroup && adduser -S appuser -G appgroup\nUSER appuser\nEXPOSE 8080\nCMD ["java", "-jar", "app.jar"]\n\nO que mudou?
\n- \n
- Alpine JRE em vez do JDK completo — a imagem é reduzida para ~120 MB \n
- Cache de dependências — se o build.gradle.kts não mudar, o Docker usa o cache \n
- Segurança — a aplicação é executada por um usuário não privilegiado \n
Compilação com Gradle Wrapper (método recomendado)
\n\nSe você usa o Gradle Wrapper (e deveria!), o Dockerfile fica ainda mais elegante. O Wrapper garante que a versão do Gradle seja a mesma para todos os desenvolvedores e no CI/CD.
\n\nFROM eclipse-temurin:17-jdk-alpine AS builder\nWORKDIR /app\nCOPY gradlew gradlew.bat ./\nCOPY gradle ./gradle\nRUN ./gradlew --version\n\nCOPY build.gradle.kts settings.gradle.kts ./\nRUN ./gradlew dependencies --no-daemon\n\nCOPY src ./src\nRUN ./gradlew build --no-daemon -x test\n\nFROM eclipse-temurin:17-jre-alpine\nWORKDIR /app\nCOPY --from=builder