A containerização de Java é mais complexa que a de Go ou Python devido a repositórios Maven autogerenciados e armadilhas de cache do Docker. Aprenda a criar imagens de contêiner Java, otimizar a velocidade de build com cache de dependências e automatizar builds com o ACR-EE.
Pré-requisitos
Crie uma base de código no GitLab.
Crie um repositório Maven.
Crie uma instância do ACR-EE. Criar uma instância Enterprise Edition.
Visão geral do projeto de exemplo
O exemplo usa dois projetos Java interdependentes:
-
Provider: serviço invocável por outras aplicações.
Módulo Core: fornece interfaces comuns.
Módulo Service: implementa os serviços.
-
Consumer: chama o serviço Provider.
-
Módulo Service: depende do módulo Core do Provider. Estrutura do projeto:
. ├── consumer │ ├── Dockerfile │ ├── consumer.iml │ ├── pom.xml │ └── service │ ├── pom.xml │ ├── src │ └── target └── provider ├── Dockerfile ├── core │ ├── pom.xml │ ├── src │ └── target ├── pom.xml ├── provider.iml └── service ├── pom.xml ├── src └── target
-
Artefatos de build:
Imagem da aplicação Provider.
Imagem da aplicação Consumer.
Etapa 1: Fazer upload das dependências comuns
Antes de iniciar o build, faça upload das dependências comuns para seu repositório Maven autogerenciado. Execute o comando abaixo no diretório do Provider:
mvn clean install org.apache.maven.plugins:maven-deploy-plugin:2.8:deploy -DskipTests
Etapa 2: Criar uma imagem base personalizada do Maven
Inclua a configuração do repositório Maven em uma imagem base personalizada, construída sobre a imagem oficial do Maven. Dessa forma, os projetos herdam o acesso ao repositório.
-
Salve o Dockerfile a seguir no mesmo diretório do arquivo settings.xml do repositório Maven.
FROM maven:3.8-openjdk-8 # Specify a Maven image that matches your project. This example uses Maven v3.8. ADD settings.xml /root/.m2/ # Add the custom Maven repository configuration to the appropriate directory. -
Crie a imagem e envie-a para um repositório remoto.
ls Dockerfile settings.xml docker build -t demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 -f Dockerfile . Sending build context to Docker daemon 7.68kB Step 1/2 : FROM maven:3.8-openjdk-8 ---> a3f42bfde036 Step 2/2 : ADD settings.xml /root/.m2/ ---> db0d5a5192e3 Successfully built db0d5a5192e3 Successfully tagged demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 docker push demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8
Etapa 3: Criar a imagem da aplicação Consumer
Use o Dockerfile abaixo. Envie todas as imagens base necessárias para o repositório de imagens do Alibaba Cloud.
FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder
# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./service service/
# package jar
RUN mvn clean package
# Second stage: minimal runtime environment
FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine
# copy jar from the first stage
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]
Etapa 4: Otimizar a velocidade do build
Na Etapa 3: Criar a imagem da aplicação Consumer (pular para o projeto Provider), você criou uma imagem funcional. Contudo, qualquer alteração no código-fonte aciona um novo download completo das dependências. O Docker invalida todas as camadas após uma mudança no hash do comando ADD, incluindo a camada de build do RUN. As melhores práticas de Dockerfile detalham esse comportamento de cache.
Para otimizar a velocidade do build, armazene em cache e reutilize as dependências do Maven entre builds:
Copie apenas o pom.xml para o contêiner e baixe as dependências. Se o pom.xml permanecer inalterado, os builds subsequentes reutilizam a camada de dependências em cache.
Copie o código-fonte e compile.
O Dockerfile a seguir separa a resolução de dependências da compilação. Os builds iniciais levam cerca de 43 segundos; já os rebuilds com alterações apenas no código-fonte são concluídos em aproximadamente 7 segundos.
FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/maven-base:3.8-openjdk-8 AS builder
# To resolve dependencies in a safe way (no re-download when the source code changes)
ADD ./pom.xml pom.xml
ADD ./service/pom.xml service/pom.xml
RUN mvn install
ADD ./service service/
# package jar
RUN mvn clean package
# Second stage: minimal runtime environment
FROM demo-registry-vpc.cn-beijing.cr.aliyuncs.com/demo/openjdk:8-jre-alpine
# copy jar from the first stage
COPY --from=builder service/target/service-1.0-SNAPSHOT.jar service-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "service-1.0-SNAPSHOT.jar"]
Etapa 5: Automatizar builds com o ACR-EE
O ACR-EE oferece serviços de build de nível empresarial para automatizar a criação de imagens. Usar uma instância Enterprise Edition para criar imagens.
Melhores práticas para o serviço de build do ACR-EE:
-
Utilize o modo de build seguro na VPC
Para repositórios GitLab autogerenciados hospedados na nuvem, use o modo de build seguro na VPC e evite expor serviços à internet pública. Criar uma imagem de contêiner em uma VPC.
-
Use tags de imagem imutáveis
Ative tags de imagem imutáveis para evitar substituições acidentais de tags de produção.

-
Crie uma regra de build baseada em IDs de commit
Configure a regra de build para gerar duas tags por build: uma com o ID do commit para rastreabilidade entre versão e código, e
latestpara o build mais recente.
Cada commit de código aciona um build automaticamente. A figura a seguir mostra dois builds provenientes de commits distintos. Cada build gera duas imagens. O segundo build é mais rápido porque reutiliza o cache.
