Você criou um aplicativo Spring Boot. Ele está funcionando muito bem em sua máquina local e agora você precisa implantar o aplicativo em outro lugar. Em algumas plataformas, você pode enviar diretamente o arquivo jar e ele será implantado. Em alguns lugares, você pode ativar uma máquina virtual, baixar o código-fonte, construí-la e executá-la. Mas, na maioria das vezes, você precisará implantar o aplicativo usando contêineres. Na maioria das vezes, o Docker é usado para construir e executar a imagem em um contêiner. Além disso, quando você carrega o arquivo jar para algumas plataformas, o aplicativo é executado dentro de um contêiner interno.
Portanto, neste blog, veremos 3 maneiras diferentes de construir uma imagem Docker para um determinado aplicativo Spring Boot. Vamos começar:
A maneira ingênua e insuficiente de construir a imagem Docker para qualquer aplicativo é usar um Dockerfile simples que copia o arquivo jar dentro da imagem e executá-lo usando o comando java -jar.
Aqui está o Dockerfile que você pode colocar na raiz do projeto:
FROM eclipse-temurin:21-jre-ubi9-minimal ARG JAR_FILE COPY ${JAR_FILE} application.jar ENTRYPOINT ["java", "-jar", "/application.jar"]
Especificamos um argumento JAR_FILE que é o local do arquivo jar a ser usado.
Depois de criar o Dockerfile acima, as etapas abaixo são usadas para criar a imagem Docker:
Crie o arquivo jar para o projeto Spring Boot:
./gradlew bootJar # For Gradle build system
OU
./mvnw spring-boot:build-jar # For Maven build system
Use o Dockerfile para construir a imagem do Docker usando o arquivo jar mais recente. No comando abaixo, substitua {IMAGE_NAME} pelo nome da imagem necessária e {JAR_FILE} pelo caminho para o arquivo jar gerado. O nome da imagem também contém uma tag, como - minhaempresa/serviço-produto:0.0.1-SNAPSHOT:
docker build --build-arg JAR_FILE={JAR_FILE} --tag {IMAGE_NAME} .
Verifique se a imagem Docker foi construída usando o seguinte comando. Você deverá conseguir ver a imagem com o nome especificado no comando acima:
docker images
Embora seja possível e fácil empacotar um uber jar do Spring Boot como uma imagem do Docker (conforme mencionado no método anterior), há muitas desvantagens em copiar e executar o fat jar como está na imagem do Docker. Por exemplo,
Como compilamos nosso código com mais frequência do que atualizamos a versão Spring Boot, é melhor separar um pouco mais as coisas. Se colocarmos esses arquivos jar (que raramente são alterados) na camada anterior à camada de aplicativo, o Docker geralmente precisará alterar apenas a camada inferior e poderá selecionar o restante de seu cache.
Para criar uma imagem Docker em camadas, precisamos primeiro criar um jar em camadas. Hoje em dia, está habilitado por padrão no Gradle e Maven. Você pode ativar ou desativar o comportamento do jar em camadas usando a seguinte configuração:
// build.gradle tasks.named("bootJar") { layered { enabled = false } }
// build.gradle.kts tasks.named("bootJar") { layered { enabled.set(false) } }
org.springframework.boot spring-boot-maven-plugin true
Você pode até ajustar como as camadas são criadas. Consulte a documentação para configuração gradle ou maven.
Abaixo está o Dockerfile, que pode ser usado para aproveitar as vantagens do jar em camadas e para criar uma imagem Docker em camadas do aplicativo Spring Boot.
# Perform the extraction in a separate builder container FROM eclipse-temurin:21-jre-ubi9-minimal AS builder WORKDIR /builder # This points to the built jar file in the target folder # Adjust this to 'build/libs/*.jar' if you're using Gradle ARG JAR_FILE=target/*.jar # Copy the jar file to the working directory and rename it to application.jar COPY ${JAR_FILE} application.jar # Extract the jar file using an efficient layout RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted # This is the runtime container FROM eclipse-temurin:21-jre-ubi9-minimal WORKDIR /application # Copy the extracted jar contents from the builder container into the working directory in the runtime container # Every copy step creates a new docker layer # This allows docker to only pull the changes it really needs COPY --from=builder /builder/extracted/dependencies/ ./ COPY --from=builder /builder/extracted/spring-boot-loader/ ./ COPY --from=builder /builder/extracted/snapshot-dependencies/ ./ COPY --from=builder /builder/extracted/application/ ./ # Start the application jar - this is not the uber jar used by the builder # This jar only contains application code and references to the extracted jar files # This layout is efficient to start up and CDS friendly ENTRYPOINT ["java", "-jar", "application.jar"]
As etapas para construir a imagem Docker em camadas são as mesmas que para construir uma imagem Docker básica. Consulte lá.
E se eu disser que você pode criar uma imagem Docker sem criar um Dockerfile? Podemos construir imagens docker diretamente do plugin Gralde ou Maven usando Cloud Native Buildpacks. Algumas plataformas (como Heroku ou Cloud Foundry) usam Buildpacks para converter arquivos jar fornecidos em imagens executáveis.
Spring Boot inclui suporte a buildpack diretamente para Maven e Gradle. Não precisamos incluir nenhum plug-in adicional. Basta executar o comando abaixo:
./gradlew bootBuildImage # For gradle build system
OU
./mvnw spring-boot:build-image # For maven build system
O comando acima gera uma imagem com o nome padrão {PROJECT_NAME}:${PROJECT_VERSION}. Se quiser configurar o nome da imagem gerada, você pode seguir os passos abaixo:
Podemos configurar a tarefa bootBuildImage para definir o nome da imagem, assim:
// For build.gradle.kts val imagePrefix = "javarush" val dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName.set("${imagePrefix}/${dockerImageName}:${version}") }
// For build.gradle def imagePrefix = "javarush" def dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName = "${imagePrefix}/${dockerImageName}:${version}" }
Podemos configurar o spring-boot-maven-plugin para usar outro nome de imagem, como este:
... javarush org.springframework.boot spring-boot-maven-plugin ${imagePrefix}/${project.artifactId}:${project.version}
Podemos até definir o nome da imagem enquanto executamos o comando para construir a imagem.
./gradlew bootBuildImage --imageName=javarush/docker-example:1.0.0 # For grade build system ./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=javarush/docker-example:1.0.0 # For maven build system
Você pode ver a documentação para configurar ainda mais o plugin Gradle ou Maven.
Este é meu método preferido para criar uma imagem Docker para qualquer aplicativo Spring Boot.
Depois de criar uma imagem docker, você precisa ter certeza de que ela funciona conforme o esperado. Depois de certificar-se de que a imagem foi criada, você pode executá-la diretamente usando o comando docker run. Por exemplo,
docker run -p "8080:8080" {IMAGE_NAME}
Mas não é assim que as imagens são usadas em aplicações de produção. Docker Compose é usado para executar e gerenciar várias imagens do Docker.
Neste blog, vimos como construir imagens Docker para aplicativos Spring Boot usando diferentes métodos. Ser capaz de construir imagens docker para seus aplicativos é uma habilidade obrigatória porque a imagem é o que é entregue. Obrigado por ler o artigo até o fim. Eu agradeço. Encontro você no próximo. Como sempre, todos os comentários e sugestões são bem-vindos.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3