DEV Community

Cover image for Docker Multi-Stage para Aplicações JAVA 21
Adilson Oliveira
Adilson Oliveira

Posted on

Docker Multi-Stage para Aplicações JAVA 21

Para criar um Dockerfile com dois estágios para uma aplicação Java 21, você pode seguir um processo de multi-stage build. Isso ajuda a reduzir o tamanho da imagem final e garante que apenas os artefatos necessários sejam incluídos na imagem final de execução. Vamos seguir um exemplo com 2 estágios:

  1. Primeiro estágio (build): Compilar a aplicação usando uma imagem que tenha o JDK 21.

  2. Segundo estágio (runtime): Criar uma imagem mais leve apenas com o JRE para rodar a aplicação.

Estrutura do projeto

Deixei um projeto bem simples, feito em Spring Boot 3.3.0 que você pode baixar no meu github, que iremos seguir como exemplo:

/meu-projeto
|-- src
|   `-- main
|       `-- java
|           `-- com
|               `-- exemplo
|                   `-- DemoApplication.java
|                   `-- HelloWorldController.java
|-- pom.xml
Enter fullscreen mode Exit fullscreen mode

Exemplo de Dockerfile

Se você baixar o projeto de exemplo, o Dockerfile já existe e você pode apenas acompanhar o artigo, caso esteja com no seu projeto crie um arquivo chamado Dockerfile na raiz do seu projeto:

# Etapa 1: Compilar a aplicação
FROM maven:3.9.7-eclipse-temurin-21-alpine AS build

# Define o diretório de trabalho dentro do contêiner
WORKDIR /app

# Copia o arquivo pom.xml e os arquivos de dependências para o diretório de trabalho
COPY pom.xml ./
COPY src ./src

# Compila a aplicação
RUN mvn package

# Etapa 2: Criar a imagem final para execução
FROM eclipse-temurin:21-jre-alpine

# Define o diretório de trabalho dentro do contêiner
WORKDIR /app

# Cria um argumento para o nome da aplicação
ARG JAR_FILE=target/*.jar

# Copia o jar compilado da etapa anterior
COPY --from=build /app/${JAR_FILE} app.jar

# Expõe a porta da aplicação
EXPOSE 8080

# Define o comando padrão para rodar a aplicação
CMD ["java", "-jar", "app.jar"]
Enter fullscreen mode Exit fullscreen mode

Explicação do Dockerfile

  1. Primeiro estágio (build):
  • FROM maven:3.9.7-eclipse-temurin-21-alpine AS build: Usa uma imagem oficial do Maven base no Eclipse Temurin JDK 21 para compilar a aplicação.
  • WORKDIR /app: Define /app como o diretório de trabalho.
  • COPY pom.xml ./ e COPY src ./src: Copia os arquivos do projeto para dentro do contêiner.
  • RUN mvn package: Compila e cria o artefato da aplicação usando Maven.
  1. Segundo estágio (runtime):
  • FROM eclipse-temurin:21-jre-alpine: Usa uma imagem oficial do Eclipse Temurin JRE 21 para executar a aplicação, resultando em uma imagem mais leve.
  • WORKDIR /app: Define /app como o diretório de trabalho.
  • COPY --from=build /app/target/minha-aplicacao.jar ./minha-aplicacao.jar: Copia o arquivo JAR compilado da etapa anterior para o diretório de trabalho.
  • CMD ["java", "-jar", "minha-aplicacao.jar"]: Define o comando padrão para executar a aplicação.

Passos para construir e rodar a imagem

  1. Construir a imagem:
docker build -t minha-aplicacao:latest .
Enter fullscreen mode Exit fullscreen mode
  1. Executar o contêiner:
docker run -p 8080:8080 minha-aplicacao:latest
Enter fullscreen mode Exit fullscreen mode
  1. Teste a aplicação:
GET http://localhost:8080/hello
Enter fullscreen mode Exit fullscreen mode

Vantagens da construção em dois estágios

Imagens mais leves:

Quando usamos multi-stage builds, a imagem final só contém os artefatos necessários para rodar a aplicação. Isso significa que todas as ferramentas de compilação e dependências de desenvolvimento não são incluídas, resultando em uma imagem mais leve e eficiente.

Segurança melhorada:

Reduzir o número de componentes na imagem final diminui a superfície de ataque, melhorando a segurança. Menos dependências e ferramentas significam menos possíveis vulnerabilidades.

Desempenho otimizado:

Imagens menores são mais rápidas para baixar e iniciar, o que é especialmente importante em ambientes de produção onde a eficiência e a velocidade são cruciais.

Separação de responsabilidades:

Dividir o processo em estágios distintos ajuda a manter uma separação clara entre as etapas de construção e execução. Isso facilita a manutenção e a compreensão do Dockerfile.

Conclusão

Construir imagens Docker em dois estágios é uma prática poderosa que traz eficiência e simplicidade. Com essa técnica, você cria imagens mais leves, seguras e fáceis de manter.
Espero que este guia tenha ajudado você a entender melhor essa prática e como implementá-la em seus projetos. Boa sorte e feliz codificação!

Codigo fonte: github

Top comments (0)