Maven projesi nasıl dockerize edilir? ve bunu başarmanın kaç yolu var?


90

Docker'da yeniyim ve birçok belgeyi okuyup birçok yöntemi denemiş olmama rağmen bir java projesini maven ile nasıl çalıştıracağımı bilmiyorum.

  1. Görüntüyü kullanarak oluşturmalı mıyım Dockerfile?
  2. Ana bilgisayardaki maven projesini çalıştırmak için ne gibi komutlar var Dockerfile?

Yanıtlar:


125

Çalışma örneği.

Bu bir yaylı önyükleme öğreticisi değildir. Bir Docker kapsayıcısı içinde bir Maven derlemesinin nasıl çalıştırılacağına ilişkin bir sorunun güncellenmiş yanıtıdır.

Soru ilk olarak 4 yıl önce gönderildi.

1. Bir uygulama oluşturun

Bir demo uygulaması oluşturmak için yay başlatıcıyı kullanın

https://start.spring.io/

görüntü açıklamasını buraya girin

Zip arşivini yerel olarak çıkarın

2. Bir Dockerfile oluşturun

#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package

#
# Package stage
#
FROM openjdk:11-jre-slim
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]

Not

  • Bu örnek, çok aşamalı bir yapı kullanır . İlk aşama kodu oluşturmak için kullanılır. İkinci aşama yalnızca yerleşik kavanozu ve onu çalıştırmak için bir JRE'yi içerir (kavanozun aşamalar arasında nasıl kopyalandığına dikkat edin).

3. Görüntüyü oluşturun

docker build -t demo .

4. Resmi çalıştırın

$ docker run --rm -it demo:latest

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

2019-02-22 17:18:57.835  INFO 1 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT on f4e67677c9a9 with PID 1 (/usr/local/bin/demo.jar started by root in /)
2019-02-22 17:18:57.837  INFO 1 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-02-22 17:18:58.294  INFO 1 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.711 seconds (JVM running for 1.035)

Çeşitli

Maven derlemesinin, kavanozları önbelleğe almak için yerel bir depo kullanmak üzere nasıl optimize edilebileceğiyle ilgili Docker hub belgelerini okuyun.

Güncelleme (2019-02-07)

Bu soru artık 4 yaşında ve o zamanlar Docker kullanarak uygulama oluşturmanın önemli bir değişikliğe uğradığını söylemek doğru olur.

Seçenek 1: Çok aşamalı yapı

Bu yeni stil, oluşturma araçlarınızı ve kaynak kodunuzu kapsamayan daha hafif görüntüler oluşturmanıza olanak tanır.

Buradaki örnek yine Maven'in istenen bir sürümünü kullanarak yapının ilk aşamasını çalıştırmak için resmi maven temel görüntüsünü kullanır . Dosyanın ikinci bölümü, yerleşik kavanozun son çıktı görüntüsüne nasıl monte edildiğini tanımlar.

FROM maven:3.5-jdk-8 AS build  
COPY src /usr/src/app/src  
COPY pom.xml /usr/src/app  
RUN mvn -f /usr/src/app/pom.xml clean package

FROM gcr.io/distroless/java  
COPY --from=build /usr/src/app/target/helloworld-1.0.0-SNAPSHOT.jar /usr/app/helloworld-1.0.0-SNAPSHOT.jar  
EXPOSE 8080  
ENTRYPOINT ["java","-jar","/usr/app/helloworld-1.0.0-SNAPSHOT.jar"]  

Not:

  • Bir java uygulaması için yeterli çalışma süresi sağlamaya çalışan Google'ın sorunsuz temel görüntüsünü kullanıyorum .

Seçenek 2: Jib

Bu yaklaşımı kullanmadım, ancak Dockerfiles gibi kötü şeyler yaratmanıza gerek kalmadan imajlar oluşturmanıza olanak sağladığı için araştırmaya değer görünüyor :-)

https://github.com/GoogleContainerTools/jib

Proje, kodunuzun paketini doğrudan Maven iş akışınıza entegre eden bir Maven eklentisine sahiptir.


Orijinal cevap (Tamlık için dahil edilmiş, ancak yıllar önce yazılmıştır)

Yeni resmi resimleri kullanmayı deneyin, Maven için bir tane var

https://registry.hub.docker.com/_/maven/

Görüntü, derlenmiş bir uygulama oluşturmak için derleme zamanında Maven'i çalıştırmak veya aşağıdaki örneklerde olduğu gibi bir kap içinde bir Maven derlemesi çalıştırmak için kullanılabilir.

Örnek 1 - Bir konteyner içinde çalışan Maven

Aşağıdaki komut, Maven yapınızı bir kap içinde çalıştırır:

docker run -it --rm \
       -v "$(pwd)":/opt/maven \
       -w /opt/maven \
       maven:3.2-jdk-7 \
       mvn clean install

Notlar:

  • Bu yaklaşımla ilgili güzel olan şey, tüm yazılımların konteyner içinde kurulu ve çalışıyor olmasıdır. Yalnızca ana makinede docker gerekir.
  • Bu sürüm için Dockerfile'a bakın

Örnek 2 - Dosyaları önbelleğe almak için Nexus'u kullanın

Nexus kapsayıcısını çalıştırın

docker run -d -p 8081:8081 --name nexus sonatype/nexus

Bir "settings.xml" dosyası oluşturun:

<settings>
  <mirrors>
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://nexus:8081/content/groups/public/</url>
    </mirror>
  </mirrors>
</settings>

Bağımlılıkların önbelleğe alınması için şimdi bağlantı noktası kapsayıcısına Maven bağlantısını çalıştırın

docker run -it --rm \
       -v "$(pwd)":/opt/maven \
       -w /opt/maven \
       --link nexus:nexus \
       maven:3.2-jdk-7 \
       mvn -s settings.xml clean install

Notlar:

  • Nexus'u arka planda çalıştırmanın bir avantajı, diğer 3. taraf depolarının yerel kapsayıcılarda çalışan Maven yapılarına şeffaf bir şekilde yönetici URL'si aracılığıyla yönetilebilmesidir.

bu, kademeli bir yapı için maven merkezini değiştirmek için kullanılabilir mi? belirtilen support.sonatype.com/entries/... yerime başkasının mavenCentral()benim gradle bağımlılıkları maven {url "http://nexus:8081..."ve şimdi sadece çözünürlük sorunları alıyorsanız.
mohamnag

@mohamnag Doğru, yukarıdaki Maven "ayarlar" dosyası tam olarak bunu yapar ve tüm Maven Central isteklerini yerel nexus deposuna yönlendirir. Ne tür çözüm sorunları yaşadığınızı ana hatlarıyla belirtmeniz gerekir. Herhangi bir şey olabilir ... Örneğin, "nexus" ana bilgisayarının düzgün bir şekilde çözülmesi için Docker bağlantısını kurdunuz mu?
Mark O'Connor

Her şeyin yolunda gittiğini anladım, ancak nexus ya endeksi oluşturmak için zamana ihtiyaç duyuyordu ya da soruna başka bir şey neden oluyordu. Ayrıca bir dizin güncellemesini tetiklemeye çalıştım, bu nedenle hangi durumun sorunu çözdüğünden emin değilim. Ancak teşekkürler.
mohamnag

Nexus 3 artık bir docker container olarak da mevcuttur. "Sonatip / nexus3" kullanın
Thorbjørn Ravn Andersen

1
@avandeursen --link parametresinin kullanımdan kaldırıldığı konusunda haklısınız (3 yıldan eski yanıt). Ancak (bence) daha doğru çözüm, bir docker ağı oluşturmak ve her iki kapsayıcıyı da üzerinde çalıştırmaktır. Bu şekilde Docker'daki yerel DNS özelliğinden yararlanabilir ve nexus kapsayıcısına ada göre başvurmaya devam edebilirsiniz. Örneği daha sonra güncelleyecek
Mark O'Connor

47

Pek çok yol olabilir .. Ama iki yolu izleyerek uyguladım

Verilen örnek maven projesidir.

1. Dockerfile'ı maven projesinde kullanma

Aşağıdaki dosya yapısını kullanın:

Demo
└── src
|    ├── main
|    │   ├── java
|    │       └── org
|    │           └── demo
|    │               └── Application.java
|    │   
|    └── test
|
├──── Dockerfile
├──── pom.xml

Ve Dockerfile'ı şu şekilde güncelleyin:

FROM java:8
EXPOSE 8080
ADD /target/demo.jar demo.jar
ENTRYPOINT ["java","-jar","demo.jar"]

Proje klasörüne gidin ve aşağıdaki komutu yazın, görüntüyü oluşturabilir ve bu görüntüyü çalıştırabilirsiniz:

$ mvn clean
$ mvn install
$ docker build -f Dockerfile -t springdemo .
$ docker run -p 8080:8080 -t springdemo

Docker ile Spring Boot'ta video alın

2. Maven eklentilerini kullanma

Belirtilen maven eklentisini ekleyin pom.xml

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.4.5</version>
        <configuration>
            <imageName>springdocker</imageName>
            <baseImage>java</baseImage>
            <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
            <resources>
                <resource>
                    <targetPath>/</targetPath>
                    <directory>${project.build.directory}</directory>
                    <include>${project.build.finalName}.jar</include>
                </resource>
            </resources>
        </configuration>
    </plugin>

Proje klasörüne gidin ve aşağıdaki komutu yazın, görüntü oluşturabilir ve bu görüntüyü çalıştırabilirsiniz:

$ mvn clean package docker:build
$ docker images
$ docker run -p 8080:8080 -t <image name>

İlk örnekte Dockerfile oluşturuyoruz ve temel imajı sağlıyoruz ve buna jar ekliyoruz, bunu yaptıktan sonra docker komutunu çalıştırıp belirli bir isimle bir imaj oluşturup sonra o imajı çalıştıracağız ..

Oysa ikinci örnekte sağladığımız maven eklentisini kullanıyoruz baseImageve imageNamebu nedenle burada Dockerfile oluşturmamıza gerek yok .. maven projesini paketledikten sonra docker imajını alacağız ve sadece o imajı çalıştırmamız gerekiyor ..


Yapı adını belirtmek için giriş noktasını değiştirmek yerine, buradaki gibi bir yaklaşımı kullanabilirsiniz: alooma.com/blog/building-dockers - ortak bir ad kullanmak için maven-bağımlılık-eklentisini kullanın. Konteynerin versiyonu belirlendiği için docker konteynerine versiyonlu bir jar koymaya gerek yok.
kboom

14

Genel bir kural olarak, Maven'i (hem kodunuzu hem de tüm bağımlılıkları içeren bir JAR) kullanarak şişman bir JAR oluşturmanız gerekir .

Ardından gereksinimlerinize uyan bir Dockerfile yazabilirsiniz (şişman bir JAR oluşturabiliyorsanız, yalnızca CentOS ve JVM gibi bir temel işletim sistemine ihtiyacınız olacaktır).

Bu, bir Scala uygulaması için kullandığım şey (Java tabanlı).

FROM centos:centos7

# Prerequisites.

RUN yum -y update
RUN yum -y install wget tar

# Oracle Java 7

WORKDIR /opt

RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u71-b14/server-jre-7u71-linux-x64.tar.gz
RUN tar xzf server-jre-7u71-linux-x64.tar.gz
RUN rm -rf server-jre-7u71-linux-x64.tar.gz
RUN alternatives --install /usr/bin/java java /opt/jdk1.7.0_71/bin/java 1

# App

USER daemon

# This copies to local fat jar inside the image
ADD /local/path/to/packaged/app/appname.jar /app/appname.jar

# What to run when the container starts
ENTRYPOINT [ "java", "-jar", "/app/appname.jar" ]

# Ports used by the app
EXPOSE 5000

Bu, Java7 ile CentOS tabanlı bir görüntü oluşturur. Başladığında, uygulama jar'ınızı çalıştıracaktır.

Bunu konuşlandırmanın en iyi yolu Docker Registry'dir, Docker görüntüleri için Github gibidir.

Bunun gibi bir görüntü oluşturabilirsiniz:

# current dir must contain the Dockerfile
docker build -t username/projectname:tagname .

Daha sonra bir resmi şu şekilde itebilirsiniz:

docker push username/projectname # this pushes all tags

Görüntü Docker Kayıt Defterinde olduğunda, onu dünyanın her yerinden çekip çalıştırabilirsiniz.

Daha fazla bilgi için Docker Kullanım Kılavuzu'na bakın .

Akılda tutulması gereken bir şey :

Ayrıca, deponuzu bir görüntünün içine çekebilir ve kapsayıcı yürütmenin bir parçası olarak kavanozu oluşturabilirsiniz, ancak kod değişebileceğinden ve bildirimde bulunmaksızın uygulamanın farklı bir sürümünü kullanmaya başlayabileceğiniz için bu iyi bir yaklaşım değildir.

Şişman bir kavanoz inşa etmek bu sorunu ortadan kaldırır.


HI, docker dosyamdaki örneğinizi görüntüdeki yağ kavanozunu kopyalamak için kullandım, ancak yapı yerel yol verilen yağ kavanozunu bulamadığı için başarısız oldu. Target / app.jar gibi bir şey mi?
user_mda

Merhaba, yapıyı çalışma zamanında nexus'tan indirebilmemin bir yolu var mı? Jar'ın kendisine gerçek bir bağlantı değil, özellikler kullanılarak indirilecek yapıyı belirtmek için? Dockerfile'da: RUN wget -O {project.build.finalname}.jar Ama yukarıdaki jar dosyasını nexus'tan indirmek istiyorum.
Pramod Setlur

1
Kod deposuna bir FAT JAR eklemek benim için yavaş. Görüntüyü oluşturmak için maven kullanmanın bir yolu var mı?
WoLfPwNeR

1
Yağ kavanozlarının da özellikle imzalı kavanozlarda bazı sorunları vardır.
Thorbjørn Ravn Andersen

1
Genel bir kural olarak, hiçbir zaman şişman bir kavanoz kullanmayın, bu verileri birleştirmenin güvenli bir yolu olmadığından, manifestoya veya kavanozlarındaki diğer veri dosyalarına dayanan paketler büyük olasılıkla başarısız olur. Bir jar çakışması ve ilk veya son galibiyetleri (hangisi hatırlayamıyorum) içinde eşleşen yollara sahip dosyaları bildirin. Şişman kavanoz kullanmayı düşünmeniz gereken tek zaman, çok sınırlı bir bağımlılık kümesine sahipseniz ve kavanozlarının çelişkili bildirim verilerine sahip olmadığını çok iyi biliyorsunuzdur. Aksi takdirde, kullanılmak üzere tasarlandıkları için (yani ayrı ayrı) güvenli kullanım kavanozlarını saklayın.
PiersyP

3

İşte benim katkım.
Maven ile Docker'dan yararlanmak için var olan tüm araçları / kitaplıkları / eklentileri listelemeye çalışmayacağım. Bazı cevaplar bunu zaten yaptı.
Bunun yerine, uygulama tipolojisine ve Dockerfile yoluna odaklanacağım.
Dockerfilegerçekten basit ve önemli bir Docker kavramıdır (bilinen tüm / genel görüntüler buna dayanır) ve Dockerfiles'yi anlamaktan ve kullanmaktan kaçınmaya çalışmanın Docker dünyasına girmenin daha iyi bir yolu olmadığını düşünüyorum .

Bir uygulamayı dockerize etmek, uygulamanın kendisine ve ulaşma hedefine bağlıdır

1) Yüklü / bağımsız Java sunucusunda (Tomcat, JBoss, vb.) Çalıştırmak üzere devam etmek istediğimiz uygulamalar için

Yol daha zordur ve bu ideal hedef değildir çünkü bu karmaşıklık ekler (sunucuyu yönetmemiz / sürdürmemiz gerekir) ve oluşturma / dağıtma / dağıtma açısından gömülü sunuculardan daha az ölçeklenebilir ve daha az hızlıdır.
Ancak eski uygulamalar için bu bir ilk adım olarak kabul edilebilir.
Genel olarak buradaki fikir, sunucu için bir Docker görüntüsü tanımlamak ve dağıtılacak uygulama başına bir görüntü tanımlamaktır.
Uygulamalar için docker görüntüleri beklenen WAR / EAR'ı üretir ancak bunlar kapsayıcı olarak yürütülmez ve sunucu uygulamasının görüntüsü, bu görüntüler tarafından üretilen bileşenleri konuşlandırılmış uygulamalar olarak dağıtır.
Çok sayıda eski malzemeye sahip devasa uygulamalar (milyonlarca satır kod) için ve tam yay önyüklemeli gömülü bir çözüme geçmek çok zor, bu gerçekten güzel bir gelişme.
Bu yaklaşımı daha fazla detaylandırmayacağım, çünkü bu Docker'ın küçük kullanım durumları içindir, ancak bu yaklaşımın genel fikrini ortaya çıkarmak istedim çünkü bu karmaşık durumlarla karşılaşan geliştiriciler için bazı kapıların açıldığını bilmek harika. Docker'ı entegre edin.

2) Sunucunun kendisini gömen / önyükleyen uygulamalar için (Sunucuya gömülü Spring Boot: Tomcat, Netty, Jetty ...)

Docker ile ideal hedef budur . Spring Boot'u belirttim çünkü bunu yapmak için gerçekten güzel bir çerçeve ve aynı zamanda çok yüksek bir sürdürülebilirlik seviyesi var ama teorik olarak bunu başarmak için başka herhangi bir Java yolunu kullanabiliriz.
Genel olarak buradaki fikir, dağıtılacak uygulama başına bir Docker görüntüsü tanımlamaktır.
Uygulamalar için docker görüntüleri bir JAR veya bir dizi JAR / sınıf / yapılandırma dosyası üretir ve bunlar, bu görüntülerden bir konteyner oluşturup başlattığımızda uygulama (java komutu) ile bir JVM başlatır.
Taşınması çok karmaşık olmayan yeni uygulamalar veya uygulamalar için, bu yolun bağımsız sunuculara göre tercih edilmesi gerekir çünkü bu, kapsayıcıları kullanmanın standart yolu ve en verimli yoludur.
Bu yaklaşımı detaylandıracağım.

Bir maven uygulamasını dockerize etme

1) Yaylı Körüksüz

Buradaki fikir, uygulamanın hem derlenmiş sınıflarını hem de gerekli maven bağımlılıklarını içeren Maven (bunun için maven montaj eklentisi ve bunun için maven gölge eklentisi yardımı) ile bir şişman kavanoz oluşturmaktır.
Sonra iki durumu belirleyebiliriz:

  • Uygulama bir masaüstü ya da (bir sunucu üzerinde konuşlandırılacak gerekmez) özerk uygulama ise: biz belirtebilirsiniz CMD/ENTRYPOINTiçinde Dockerfilebaşvurunun java yürütülmesi:java -cp .:/fooPath/* -jar myJar

  • Uygulama bir sunucu uygulamasıysa, örneğin Tomcat, fikir aynıdır: uygulamanın dolgun bir kavanozunu almak ve bir JVM'yi CMD/ENTRYPOINT. Ancak burada önemli bir farkla: org.apache.tomcat.embedAna uygulama başlatıldığında katıştırılmış sunucuyu başlatan bazı mantık ve belirli kitaplıkları ( kitaplıklar ve diğerleri) eklememiz gerekir. Heroku web sitesinde
    kapsamlı bir rehberimiz var .
    İlk durum (otonom uygulama) için bu, Docker'ı kullanmanın düz ve verimli bir yoludur.
    Çalışan ancak düz olmayan ikinci durum (sunucu uygulaması) için, hataya açık olabilir ve çok genişletilebilir bir model değildir çünkü uygulamanızı Spring Boot gibi olgun bir çerçeve çerçevesine yerleştirmezsiniz. bunların sizin için ve ayrıca yüksek düzeyde bir uzantı sağlar.
    Ancak bunun bir avantajı var: Doğrudan gömülü Tomcat API'sini kullandığınız için yüksek düzeyde bir özgürlüğe sahipsiniz.

2) Yaylı Körüklü

Sonunda, işte başlıyoruz.
Bu hem basit, etkili hem de çok iyi belgelenmiştir.
Docker üzerinde çalıştırmak üzere bir Maven / Spring Boot uygulaması yapmak için gerçekten birkaç yaklaşım vardır.
Hepsini açığa çıkarmak uzun ve belki de sıkıcı olurdu.
En iyi seçim, ihtiyacınıza bağlıdır.
Ancak, yol ne olursa olsun, docker katmanları açısından derleme stratejisi aynı görünüyor.
Çok aşamalı bir yapı kullanmak istiyoruz: biri bağımlılık çözümü ve derleme için Maven'e, diğeri ise uygulamayı başlatmak için JDK veya JRE'ye güveniyor.

Oluşturma aşaması (Maven görüntüsü):

  • pom görüntüye kopyala
  • bağımlılıklar ve eklenti indirmeleri.
    O konuda, mvn dependency:resolve-pluginszincirlenmiş mvn dependency:resolvedaima işi ancak yapabilir.
    Neden ? Bu eklentiler ve packageşişman kavanozu paketlemek için yürütme, farklı yapılara / eklentilere ve hatta aynı yapıya / eklentiye dayanabileceğinden, bunlar yine de farklı bir sürümü çekebilir. Bu nedenle, potansiyel olarak daha yavaşken daha güvenli bir yaklaşım mvn, uygulamayı paketlemek için kullanılan komutu tam olarak çalıştırarak (tam olarak ihtiyacınız olan bağımlılıkları çekecektir), ancak kaynak derlemeyi atlayarak ve işlemi daha hızlı hale getirmek için hedef klasörü silerek bağımlılıkları çözmektir. bu adım için istenmeyen katman değişikliği algılamasını önlemek.
  • kaynak kodu resme kopyala
  • uygulamayı paketlemek

Çalıştırma aşaması (JDK veya JRE görüntüsü):

  • önceki aşamadaki kavanozu kopyala

İşte iki örnek.

a) İndirilen maven bağımlılıkları için önbelleksiz basit bir yol

Dockerfile:

########Maven build stage########
FROM maven:3.6-jdk-11 as maven_build
WORKDIR /app

#copy pom
COPY pom.xml .

#resolve maven dependencies
RUN mvn clean package -Dmaven.test.skip -Dmaven.main.skip -Dspring-boot.repackage.skip && rm -r target/

#copy source
COPY src ./src

# build the app (no dependency download here)
RUN mvn clean package  -Dmaven.test.skip

# split the built app into multiple layers to improve layer rebuild
RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar

########JRE run stage########
FROM openjdk:11.0-jre
WORKDIR /app

#copy built app layer by layer
ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF

#run the app
CMD java -cp .:classes:lib/* \
         -Djava.security.egd=file:/dev/./urandom \
         foo.bar.MySpringBootApplication

Bu çözümün dezavantajı? Pom.xml'deki herhangi bir değişiklik, maven bağımlılıklarını indiren ve depolayan tüm katmanı yeniden oluşturduğu anlamına gelir. Genel olarak, görüntü oluşturma sırasında bir maven depo yöneticisi kullanmazsanız, birçok bağımlılığı olan uygulamalar için (ve Spring Boot birçok bağımlılığı çeker) genellikle kabul edilemez.

b) İndirilen maven bağımlılıkları için önbellek ile daha verimli bir yol

Yaklaşım burada aynıdır, ancak docker builder önbelleğinde önbelleğe alınan maven bağımlılıkları indirmeleri.
Önbellek işlemi, buildkit'e (docker'ın deneysel API'si) dayanır.
Buildkit'i etkinleştirmek için, env değişkeni DOCKER_BUILDKIT = 1 ayarlanmalıdır (bunu istediğiniz yerde yapabilirsiniz: .bashrc, komut satırı, docker daemon json dosyası ...).

Dockerfile:

# syntax=docker/dockerfile:experimental

########Maven build stage########
FROM maven:3.6-jdk-11 as maven_build
WORKDIR /app

#copy pom
COPY pom.xml .

#copy source
COPY src ./src

# build the app (no dependency download here)
RUN --mount=type=cache,target=/root/.m2  mvn clean package -Dmaven.test.skip

# split the built app into multiple layers to improve layer rebuild
RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar

########JRE run stage########
FROM openjdk:11.0-jre
WORKDIR /app

#copy built app layer by layer
ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF

#run the app
CMD java -cp .:classes:lib/* \
         -Djava.security.egd=file:/dev/./urandom \
         foo.bar.MySpringBootApplication
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.