Docker e Java: conteinerização avançada de aplicações

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Docker e Java: nível avançado de conteinerização de aplicações

\n\n

A conteinerização de aplicações Java tornou-se o padrão de facto no desenvolvimento moderno. No entanto, o conhecimento básico de Docker (criação de imagem a partir de openjdk:11 e execução de contêiner) já não atende aos requisitos de ambientes de produção. Em nível avançado, é necessário considerar as particularidades da JVM dentro do contêiner, otimizar o tamanho das imagens, gerenciar a memória e configurar o monitoramento. Neste artigo, abordaremos as principais técnicas que o ajudarão a criar imagens Docker eficientes e seguras para aplicações Java.

\n\n

1. Construção multi-estágio: minimização do tamanho da imagem

\n\n

A abordagem clássica "um Dockerfile — uma imagem" frequentemente leva ao inchaço do artefato final. Ferramentas de construção (Maven, Gradle, compilador) que não são necessárias em tempo de execução acabam na imagem. A solução é a construção multi-estágio (multi-stage). Dividimos o processo em etapas: construção (build) e execução (runtime).

\n\n

Exemplo de Dockerfile para uma aplicação Spring Boot usando Maven:

\n\n
# Etapa de construção\nFROM maven:3.8.6-openjdk-17 AS builder\nWORKDIR /app\nCOPY pom.xml .\nRUN mvn dependency:go-offline -B\nCOPY src ./src\nRUN mvn clean package -DskipTests\n\n# Etapa de execução\nFROM eclipse-temurin:17-jre-alpine\nWORKDIR /app\nCOPY --from=builder /app/target/*.jar app.jar\nEXPOSE 8080\nENTRYPOINT ["java", "-jar", "app.jar"]
\n\n

Como resultado, a imagem final pesa ~150 MB em vez de 600+ MB. Importante: use imagens jre (não jdk) e distribuições mínimas (Alpine, Slim). Para aplicações em Java 17+, considere usar jlink — criação de uma JRE personalizada apenas com os módulos necessários.

\n\n

2. Configuração da JVM para funcionar dentro do contêiner

\n\n

Por muito tempo, a JVM não conseguia identificar corretamente os limites de memória e CPU definidos para o contêiner. A partir do Java 8u191 e Java 10, surgiu o suporte a cgroups v1 (e com Java 15, cgroups v2). No entanto, não se deve confiar apenas na automação.

\n\n

Parâmetros-chave para produção:

\n
    \n
  • -XX:+UseContainerSupport — ativa o suporte a contêineres (ativo por padrão no Java 10+).
  • \n
  • -XX:MaxRAMPercentage=75.0 — limita o uso do heap a 75% da memória disponível do contêiner. Isso reserva memória para o metaspaco, pilha de threads e processos do sistema.
  • \n
  • -XX:ActiveProcessorCount=2 — especificação explícita do número de processadores disponíveis, caso a deteção automática falhe.
  • \n
\n\n

Exemplo de comando ENTRYPOINT completo:

\n\n
ENTRYPOINT ["java", \\\n    "-XX:+UseContainerSupport", \\\n    "-XX:MaxRAMPercentage=75.0", \\\n    "-XX:+ExitOnOutOfMemoryError", \\\n    "-jar", "app.jar"]
\n\n

Importante: evite valores fixos de -Xmx e -Xms em ambientes Docker. Eles não se adaptam a alterações nos limites do contêiner durante replicação ou escalonamento.

\n\n

3. Otimização de camadas e cache de construção

\n\n

Cada instrução no Dockerfile cria uma nova camada. O Docker armazena em cache as camadas que não foram alteradas. Para acelerar reconstruções, organize as instruções das menos mutáveis para as mais mutáveis.

\n\n

Estrutura correta do Dockerfile:

\n
    \n
  1. Instalação de dependências do SO (apk add, apt-get).
  2. \n
  3. Cópia de arquivos de configuração do construtor (pom.xml, build.gradle).
  4. \n
  5. Download de dependências (mvn dependency:go-offline).
  6. \n
  7. Cópia do código-fonte.
  8. \n
  9. Construção e cópia do artefato.
  10. \n
\n\n

Adicionalmente, pode-se usar o docker layer caching em CI/CD. Por exemplo, no GitHub Actions ou GitLab CI, salve o cache do Maven entre as construções:

\n\n
# Exemplo para GitLab CI\ncache:\n  key: ${CI_COMMIT_REF_SLUG}\n  paths:\n    - .m2/repository/\n    - .gradle/caches/
\n\n

Considere também o uso de

Blogs

Book Recommendations