मावेन परियोजना को कैसे करना है? और इसे पूरा करने के कितने तरीके हैं?


87

मैं डॉकर के लिए नया हूं, और यह नहीं जानता कि मावेन के साथ जावा प्रोजेक्ट कैसे चलाया जाए, हालांकि मैंने कई दस्तावेज पढ़े हैं और कई तरीके आजमाए हैं।

  1. क्या मुझे छवि का उपयोग करना चाहिए Dockerfile?
  2. जब यह होस्ट में मावेन प्रोजेक्ट को चलाने के लिए है, तो क्या है Dockerfile?

जवाबों:


122

काम करने का उदाहरण।

यह एक स्प्रिंग बूट ट्यूटोरियल नहीं है। यह एक प्रश्न का अद्यतन उत्तर है कि डॉक कंटेनर में मावेन निर्माण कैसे चलाया जाए।

प्रश्न मूल रूप से 4 साल पहले पोस्ट किया गया था।

1. एक आवेदन उत्पन्न करें

डेमो ऐप जनरेट करने के लिए स्प्रिंग इनिशियलाइज़र का उपयोग करें

https://start.spring.io/

यहां छवि विवरण दर्ज करें

स्थानीय रूप से ज़िप संग्रह निकालें

2. डॉकरफाइल बनाएं

#
# 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"]

ध्यान दें

  • यह उदाहरण एक मल्टी-स्टेज बिल्ड का उपयोग करता है । पहले चरण का उपयोग कोड बनाने के लिए किया जाता है। दूसरे चरण में केवल निर्मित जार और इसे चलाने के लिए एक JRE होता है (ध्यान दें कि जार को चरणों के बीच कैसे कॉपी किया जाता है)।

3. छवि का निर्माण

docker build -t demo .

4. छवि को चलाएं

$ 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)

विविध

मॉक बिल्ड को कैश जार में स्थानीय रिपॉजिटरी का उपयोग करने के लिए कैसे अनुकूलित किया जा सकता है, इस पर डॉकर हब प्रलेखन पढ़ें।

अपडेट (2019-02-07)

यह प्रश्न अब 4 वर्ष का है और उस समय में यह कहना उचित है कि डॉकटर के उपयोग से निर्माण में महत्वपूर्ण परिवर्तन आया है।

विकल्प 1: मल्टी-स्टेज बिल्ड

यह नई शैली आपको अधिक हल्के वजन वाली छवियां बनाने में सक्षम बनाती है जो आपके बिल्ड टूल और सोर्स कोड को एन्क्रिप्ट नहीं करती हैं।

यहाँ उदाहरण फिर से मावेन के वांछित संस्करण का उपयोग करके निर्माण के पहले चरण को चलाने के लिए आधिकारिक मावेन आधार छवि का उपयोग करता है। फ़ाइल का दूसरा भाग परिभाषित करता है कि निर्मित जार को अंतिम आउटपुट छवि में कैसे इकट्ठा किया जाता है।

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"]  

ध्यान दें:

  • मैं Google की डिस्ट्रोलेस आधार छवि का उपयोग कर रहा हूं , जो एक जावा ऐप के लिए बस पर्याप्त रन-टाइम प्रदान करने का प्रयास करता है।

विकल्प 2: जिब

मैंने इस दृष्टिकोण का उपयोग नहीं किया है, लेकिन जांच के योग्य लगता है क्योंकि यह आपको डॉकफ़र्ट्स :-) जैसी गंदी चीज़ों को बनाने के बिना चित्र बनाने में सक्षम बनाता है

https://github.com/GoogleContainerTools/jib

परियोजना में एक मावेन प्लगइन है जो आपके कोड की पैकेजिंग को सीधे आपके मावेन वर्कफ़्लो में एकीकृत करता है।


मूल उत्तर (पूर्णता के लिए शामिल है, लेकिन लिखित उम्र पहले)

नई आधिकारिक छवियों का उपयोग करने का प्रयास करें, मावेन के लिए एक है

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

छवि का उपयोग मावेन को बनाने के लिए एक संकलित अनुप्रयोग बनाने के लिए या निम्नलिखित उदाहरणों में, कंटेनर के भीतर मावेन निर्माण को चलाने के लिए किया जा सकता है।

उदाहरण 1 - एक कंटेनर के भीतर मावेन चल रहा है

निम्न आदेश आपके मावेन निर्माण को एक कंटेनर के अंदर चलाता है:

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

टिप्पणियाँ:

  • इस दृष्टिकोण के बारे में साफ बात यह है कि सभी सॉफ़्टवेयर कंटेनर के भीतर स्थापित और चल रहे हैं। मेजबान मशीन पर केवल डॉकटर की आवश्यकता है।
  • इस संस्करण के लिए Dockerfile देखें

उदाहरण 2 - फ़ाइलों को कैश करने के लिए नेक्सस का उपयोग करें

Nexus कंटेनर चलाएँ

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

एक "settings.xml" फ़ाइल बनाएँ:

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

अब मावेन को नेक्सस कंटेनर से जोड़कर चलाएं, ताकि निर्भरताएं खत्म हो जाएं

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

टिप्पणियाँ:

  • नेक्सस को पृष्ठभूमि में चलाने का एक फायदा यह है कि अन्य 3 पार्टी रिपॉजिटरी को व्यवस्थापक URL के माध्यम से पारदर्शी रूप से स्थानीय कंटेनरों में चल रहे मावेन बिल्ड के लिए प्रबंधित किया जा सकता है।

यह एक ढाल निर्माण के लिए मावेन सेंट्रल को बदलने के लिए इस्तेमाल किया जा सकता है? जैसा कि support.sonatype.com/entries/… में कहा गया है, मैंने mavenCentral()अपनी श्रेणीबद्ध निर्भरता को बदल दिया है maven {url "http://nexus:8081..."और अब केवल रिज़ॉल्यूशन समस्याएं हो रही हैं।
मुहम्मनाग

@mohamnag सही, उपरोक्त मावेन "सेटिंग" फ़ाइल बिल्कुल वैसी ही है, जो सभी मवेन सेंट्रल रिक्वेस्ट को स्थानीय नेक्सस रिपॉजिटरी में रीडायरेक्ट करती है। आपको इस बात की रूपरेखा तैयार करने की जरूरत है कि आपको किस तरह की संकल्प समस्याएं हैं। कुछ भी हो सकता है ... उदाहरण के लिए, क्या आपने डॉकर लिंक को सेटअप किया है, ताकि "नेक्सस" होस्ट ठीक से हल हो जाए?
मार्क ओ'कॉनर

मुझे पता चला कि हर बात ठीक थी, लेकिन सांठगांठ को या तो सूचकांक बनाने के लिए समय चाहिए था या कुछ और परेशानी का कारण बना। मैंने एक इंडेक्स अपडेट को ट्रिगर करने का भी प्रयास किया इसलिए मुझे यकीन नहीं है कि किस मामले ने समस्या को ठीक किया। फिर भी धन्यवाद।
मुहम्मनाग

Nexus 3 अब डॉकटर कंटेनर के रूप में भी उपलब्ध है। "सोनटाइप / नेक्सस 3" का उपयोग करें
एंडरसन

1
@avandeursen आप सही हैं कि --link पैरामीटर घटाया हुआ है (3 वर्ष से अधिक पुराना उत्तर)। हालांकि अधिक सही समाधान (मेरी राय में) एक डॉक नेटवर्क बनाने और उस पर दोनों कंटेनरों को चलाने के लिए है। इस तरह से आप Docker में देशी DNS सुविधा का लाभ उठा सकते हैं और नेक्सस कंटेनर को नाम से संदर्भित करना जारी रख सकते हैं। बाद में उदाहरण को अपडेट करेंगे
मार्क ओ'कॉनर

47

कई तरीके हो सकते हैं .. लेकिन मैंने दो तरीकों का पालन करके लागू किया है

दिया गया उदाहरण मावेन परियोजना का है।

1. मावेन परियोजना में डॉकरीफाइल का उपयोग करना

निम्न फ़ाइल संरचना का उपयोग करें:

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

और Dockerfile को इस प्रकार अपडेट करें:

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

प्रोजेक्ट फ़ोल्डर पर जाएँ और निम्नलिखित कमांड टाइप करें, जो आपको इमेज बनाने और उस इमेज को चलाने के लिए ab le होगा:

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

डॉक के साथ स्प्रिंग बूट पर वीडियो प्राप्त करें

2. मावेन प्लगइन्स का उपयोग करना

में दिए गए मावेन प्लगइन जोड़ें 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>

प्रोजेक्ट फ़ोल्डर पर जाएं और निम्न कमांड टाइप करें जिससे आप इमेज बना पाएंगे और उस इमेज को चला पाएंगे:

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

पहले उदाहरण में हम Dockerfile बना रहे हैं और आधार छवि प्रदान कर रहे हैं और जार जोड़ रहे हैं, ऐसा करने के बाद हम विशिष्ट नाम के साथ एक छवि बनाने के लिए docker कमांड चलाएंगे और फिर उस छवि को चलाएंगे ।।

जबकि दूसरे उदाहरण में हम मावेन प्लगइन का उपयोग कर रहे हैं जिसमें हम प्रदान करते हैं baseImageऔर imageNameइसलिए हमें यहां डॉकरफाइल बनाने की आवश्यकता नहीं है .. पैकेजिंग मावेन परियोजना के बाद हमें डॉकटर छवि मिलेगी और हमें केवल उस छवि को चलाने की आवश्यकता है ..


विरूपण साक्ष्य निर्दिष्ट करने के लिए प्रविष्टि बिंदु को संशोधित करने के बजाय आप यहां इस तरह दृष्टिकोण का उपयोग कर सकते हैं: alooma.com/blog/building-dockers - एक सामान्य नाम का उपयोग करने के लिए मावेन -निर्भरता-प्लगइन का उपयोग करें। डॉकटर कंटेनर में एक संस्करण वाले जार को डालने की आवश्यकता नहीं है क्योंकि कंटेनर खुद ही संस्करण है।
kboom

14

अंगूठे के एक नियम के रूप में, आपको मावेन (एक जार जिसमें आपके कोड और सभी निर्भरताएं शामिल हैं) का उपयोग करके एक मोटी JAR का निर्माण करना चाहिए ।

फिर आप एक डॉकरीफाइल लिख सकते हैं जो आपकी आवश्यकताओं से मेल खाता हो (यदि आप एक मोटा JAR का निर्माण कर सकते हैं तो आपको केवल Cent os, और JVM की तरह एक आधार ओएस की आवश्यकता होगी)।

यह मैं एक स्काला ऐप (जो जावा-आधारित है) के लिए उपयोग करता हूं।

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

यह Java7 के साथ एक CentOS- आधारित छवि बनाता है। शुरू होने पर, यह आपके ऐप जार को निष्पादित करेगा।

इसे तैनात करने का सबसे अच्छा तरीका डोकर रजिस्ट्री के माध्यम से है, यह डॉकटर छवियों के लिए जीथब जैसा है।

आप इस तरह की एक छवि बना सकते हैं:

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

फिर आप इस तरह से एक छवि को आगे बढ़ा सकते हैं:

docker push username/projectname # this pushes all tags

एक बार छवि डॉकर रजिस्ट्री पर है, तो आप इसे दुनिया में कहीं से भी खींच सकते हैं और इसे चला सकते हैं।

देखें डोकर उपयोगकर्ता गाइड अधिक जानकारियां के लिए।

कुछ ध्यान में रखना :

आप अपनी रिपॉजिटरी को एक छवि के अंदर भी खींच सकते हैं और कंटेनर के निष्पादन के हिस्से के रूप में जार का निर्माण कर सकते हैं, लेकिन यह एक अच्छा तरीका नहीं है, क्योंकि कोड बदल सकता है और आप बिना सूचना के ऐप के किसी भिन्न संस्करण का उपयोग करके समाप्त हो सकते हैं।

एक मोटी जार का निर्माण इस मुद्दे को हटा देता है।


नमस्ते, मैंने छवि में वसा जार की प्रतिलिपि बनाने के लिए अपने डॉकटर फ़ाइल में आपके उदाहरण का उपयोग किया है, लेकिन स्थानीय मार्ग को दिए गए वसा जार को खोजने में सक्षम नहीं होने के कारण बिल्ड विफल रहता है। यह लक्ष्य / app.jar की तरह कुछ है?
user_mda

नमस्ते, वहाँ एक तरह से मैं नेक्सस से कलाकृतियों को रनटाइम पर डाउनलोड कर सकता हूं? संपत्तियों का उपयोग करके डाउनलोड की जाने वाली कलाकृति को निर्दिष्ट करने के लिए और जार के लिए एक वास्तविक लिंक नहीं है? Dockerfile में: RUN wget -O {project.build.finalname}.jar लेकिन मैं नेक्सस से उपरोक्त जार डाउनलोड करना चाहता हूं।
प्रमोद सेटलुर

1
FAT JAR से कोड रेपो तक शामिल करना मेरे लिए धीमा है। क्या छवि बनाने के लिए मावेन का उपयोग करने का कोई तरीका है?
WoLfPwNeR

1
मोटे जार में कुछ समस्याएं भी होती हैं, विशेषकर हस्ताक्षरित जार के साथ।
थोर्बोजर्न रेवन एंडरसन

1
अंगूठे के एक नियम के रूप में कभी भी एक वसा जार का उपयोग न करें, पैकेज जो अपने जार के भीतर प्रकट या अन्य डेटा फ़ाइलों पर भरोसा करते हैं, वे विफल होने की संभावना है क्योंकि इस डेटा को मर्ज करने का कोई सुरक्षित तरीका नहीं है। एक जार संघर्ष के अंदर मेल खाते रास्तों के साथ मैनिफेस्ट फाइलें और या तो पहली या आखिरी जीत (जो याद नहीं कर सकते हैं)। केवल एक बार जब आपको वसा जार का उपयोग करने पर विचार करना चाहिए, यदि आपके पास बहुत सीमित निर्भरता है और आप अच्छी तरह जानते हैं कि उनके जार में परस्पर विरोधी प्रकट डेटा नहीं है। अन्यथा सुरक्षित उपयोग के जार रहें क्योंकि उनका उपयोग करने के लिए डिज़ाइन किया गया है (यानी अलग से)।
PiersyP

3

यहाँ मेरा योगदान है।
मैं सभी उपकरणों / पुस्तकालयों / प्लगइन्स को सूचीबद्ध करने की कोशिश नहीं करूँगा जो मावेन के साथ डॉकर का लाभ उठाने के लिए मौजूद हैं। कुछ उत्तर पहले ही कर चुके हैं।
इसके बजाय, मैं एप्लिकेशन टाइपोलॉजी और डॉकरीफाइल तरीके पर ध्यान केंद्रित करूंगा।
Dockerfileवास्तव में डॉकर की एक सरल और महत्वपूर्ण अवधारणा है (सभी ज्ञात / सार्वजनिक चित्र उस पर भरोसा करते हैं) और मुझे लगता है कि समझ से बचने की कोशिश करना और Dockerfileएस का उपयोग करना जरूरी नहीं है कि डोकर दुनिया में प्रवेश करने का बेहतर तरीका है।

किसी एप्लिकेशन को डॉकैराइज़ करना आवेदन के स्वयं और पहुंचने के लक्ष्य पर निर्भर करता है

1) उन अनुप्रयोगों के लिए जो हम उन्हें स्थापित / स्टैंडअलोन जावा सर्वर (टॉमकैट, जेबॉस, आदि) पर चलाने के लिए चाहते हैं)

सड़क कठिन है और यह आदर्श लक्ष्य नहीं है क्योंकि यह जटिलता (हमें सर्वर को प्रबंधित / बनाए रखना है) को जोड़ता है और यह बिल्ड / तैनात / undeploy के संदर्भ में एम्बेडेड सर्वर की तुलना में कम स्केलेबल और कम तेज़ है।
लेकिन विरासत अनुप्रयोगों के लिए, यह एक पहला कदम माना जा सकता है।
आम तौर पर, यहां विचार सर्वर के लिए डॉकर छवि को परिभाषित करने और प्रति एप्लिकेशन एक छवि को परिभाषित करने के लिए है।
अनुप्रयोगों के लिए docker की छवियाँ अपेक्षित WAR / EAR का उत्पादन करती हैं लेकिन इन्हें कंटेनर के रूप में निष्पादित नहीं किया जाता है और सर्वर अनुप्रयोग के लिए छवि इन छवियों द्वारा उत्पादित घटकों को तैनात किए गए अनुप्रयोगों के रूप में दर्शाती है।
बहुत सारे विरासत सामान के साथ विशाल अनुप्रयोगों (कोड की लाइन के लाखों) के लिए, और इसलिए एक पूर्ण वसंत बूट एम्बेडेड समाधान में स्थानांतरित करने के लिए कठिन है, जो वास्तव में एक अच्छा सुधार है।
मैं इस बारे में अधिक विस्तार नहीं करूंगा कि यह डॉकर के मामूली उपयोग के मामलों के लिए है, लेकिन मैं उस दृष्टिकोण के समग्र विचार को उजागर करना चाहता था क्योंकि मुझे लगता है कि डेवलपर्स के लिए इन जटिल मामलों का सामना करना पड़ रहा है, यह जानना बहुत अच्छा है कि कुछ दरवाजे खुल जाते हैं डॉकर को एकीकृत करें।

2) उन अनुप्रयोगों के लिए जो सर्वर को स्वयं एम्बेड / बूटस्ट्रैप करते हैं (सर्वर के साथ स्प्रिंग बूट एम्बेडेड: टॉमकैट, नेट्टी, जेटी ...)

यह डॉकर के साथ आदर्श लक्ष्य है । मैंने स्प्रिंग बूट को निर्दिष्ट किया क्योंकि ऐसा करने के लिए वास्तव में एक अच्छा ढांचा है और इसमें स्थिरता का एक उच्च स्तर भी है लेकिन सिद्धांत रूप में हम इसे प्राप्त करने के लिए किसी अन्य जावा तरीके का उपयोग कर सकते हैं।
आम तौर पर, यहां पर विचार यह है कि प्रति आवेदन करने के लिए एक डोकर छवि को परिभाषित करें।
अनुप्रयोगों के लिए डॉकरों की छवियां एक JAR या JAR / कक्षाएं / कॉन्फ़िगरेशन फ़ाइलों का एक सेट उत्पन्न करती हैं और जब हम इन चित्रों से एक कंटेनर बनाते हैं और शुरू करते हैं, तो एप्लिकेशन (जावा कमांड) के साथ एक JVM शुरू करते हैं।
नए अनुप्रयोगों या अनुप्रयोगों के लिए माइग्रेट करने के लिए बहुत जटिल नहीं है, इस तरह से स्टैंडअलोन सर्वरों के पक्ष में होना चाहिए क्योंकि यह मानक तरीका है और कंटेनरों का उपयोग करने का सबसे कुशल तरीका है।
मैं उस दृष्टिकोण का विस्तार करूंगा।

एक मावेन एप्लिकेशन को डॉकटराइज़ करना

1) स्प्रिंग बूट के बिना

विचार मावेन के साथ एक मोटा जार बनाने के लिए है (मावेन असेंबली प्लगइन और उसके लिए मावेन शेड प्लगइन मदद) जिसमें आवेदन के दोनों संकलित वर्ग और मावेन निर्भरता की आवश्यकता होती है।
तब हम दो मामलों की पहचान कर सकते हैं:

  • यदि एप्लिकेशन एक डेस्कटॉप या स्वायत्त एप्लिकेशन है (जिसे सर्वर पर तैनात करने की आवश्यकता नहीं है): हम आवेदन के जावा निष्पादन के रूप CMD/ENTRYPOINTमें निर्दिष्ट कर सकते हैं Dockerfile:java -cp .:/fooPath/* -jar myJar

  • यदि आवेदन एक सर्वर अनुप्रयोग है, उदाहरण के लिए टॉमकैट, विचार एक ही है: आवेदन का एक मोटा जार पाने के लिए और दूसरे मामले (सर्वर एप्लिकेशन) के लिए जेवीएम चलाने के लिए, वह काम करता है लेकिन वह सीधा नहीं है, त्रुटि प्रवण हो सकता है और यह एक बहुत बड़ा मॉडल नहीं है क्योंकि आप अपने आवेदन को स्प्रिंग फ्रेम जैसे परिपक्व ढांचे के फ्रेम में नहीं रखते हैं जो आपके लिए इनमें से कई काम करता है और उच्च स्तर का विस्तार भी प्रदान करता है।CMD/ENTRYPOINT । लेकिन यहां एक महत्वपूर्ण अंतर के साथ: हमें कुछ तर्क और विशिष्ट पुस्तकालयों ( org.apache.tomcat.embedपुस्तकालयों और कुछ अन्य) को शामिल करने की आवश्यकता है जो मुख्य अनुप्रयोग शुरू होने पर एम्बेडेड सर्वर को शुरू करता है।
    हम हरोकू वेबसाइट पर एक व्यापक गाइड है ।
    पहले मामले के लिए (स्वायत्त आवेदन), जो डॉकर का उपयोग करने के लिए एक सीधा और कुशल तरीका है।

    लेकिन इसका एक फायदा है: आपके पास उच्च स्तर की स्वतंत्रता है क्योंकि आप सीधे एम्बेडेड टॉमकैट एपीआई का उपयोग करते हैं।

2) स्प्रिंग बूट के साथ

आखिर में, यहाँ हम चलते हैं।
यह सरल, कुशल और बहुत अच्छी तरह से प्रलेखित दोनों है।
डॉकर पर चलने के लिए मावेन / स्प्रिंग बूट एप्लिकेशन बनाने के लिए वास्तव में कई दृष्टिकोण हैं।
इन सभी का एक्सपोजर लंबा और शायद उबाऊ होगा।
सबसे अच्छा विकल्प आपकी आवश्यकता पर निर्भर करता है।
लेकिन जो भी हो, डॉक लेयर्स के लिहाज से बिल्ड की रणनीति एक जैसी ही दिखती है।
हम मल्टी स्टेज बिल्ड का उपयोग करना चाहते हैं: एक निर्भरता रिज़ॉल्यूशन के लिए मावेन पर निर्भर है और बिल्ड के लिए और दूसरा आवेदन शुरू करने के लिए जेडीके या जेआरई पर निर्भर है।

मंच बनाएं (मावेन छवि):

  • पोम कॉपी छवि के लिए
  • निर्भरता और प्लगइन्स डाउनलोड।
    इसके बारे में, mvn dependency:resolve-pluginsजंजीर mvn dependency:resolveकाम कर सकती है लेकिन हमेशा नहीं।
    क्यों ? चूँकि ये प्लगइन्स और packageवसा जार को पैकेज करने के लिए निष्पादन अलग-अलग कलाकृतियों / प्लगइन्स और यहां तक ​​कि एक ही आर्टिफिशियल / प्लग इन पर निर्भर हो सकता है, फिर भी ये एक अलग संस्करण को खींच सकते हैं। तो एक सुरक्षित दृष्टिकोण, जबकि संभावित रूप से धीमी गति से निर्भरता को निष्पादित कर रहा हैmvn अनुप्रयोगों को पैकेज करने के लिए उपयोग की जाने वाली कमांड रही हैं (जो कि पूरी तरह से निर्भरताएं हैं जिनकी आपको आवश्यकता है) लेकिन स्रोत संकलन को बंद करके और प्रसंस्करण को तेज करने के लिए लक्ष्य फ़ोल्डर को हटाकर और उस चरण के लिए किसी भी अवांछनीय परत परिवर्तन का पता लगाने से रोकें।
  • स्रोत कोड छवि पर कॉपी करें
  • एप्लिकेशन को पैकेज करें

रन स्टेज (JDK या JRE इमेज):

  • पिछले चरण से जार की प्रतिलिपि बनाएँ

यहाँ दो उदाहरण हैं।

क) डाउनलोड मावेन निर्भरता के लिए कैश के बिना एक सरल तरीका

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

उस समाधान का दोष? Pom.xml में किसी भी परिवर्तन का अर्थ है, मावेन निर्भरता को डाउनलोड करने और संग्रहीत करने वाली संपूर्ण परत को फिर से बनाता है। यह आम तौर पर कई निर्भरता वाले अनुप्रयोगों के लिए स्वीकार्य नहीं है (और स्प्रिंग बूट कई निर्भरता को खींचता है), कुल मिलाकर यदि आप छवि निर्माण के दौरान एक मैवॉन रिपॉजिटरी प्रबंधक का उपयोग नहीं करते हैं।

ख) मावेन निर्भरता के लिए कैश के साथ एक अधिक कुशल तरीका डाउनलोड किया गया

दृष्टिकोण यहाँ एक ही है, लेकिन मावेन निर्भरता डाउनलोड है जो डॉक बिल्डर कैश में कैश हैं।
कैश ऑपरेशन बिल्डकिट (docker की प्रायोगिक एपी) पर निर्भर करता है।
बिल्डकिट को सक्षम करने के लिए, env वैरिएबल DOCKER_BUILDKIT = 1 को सेट करना होगा (आप ऐसा कर सकते हैं जहां आप चाहते हैं: .bashrc, कमांड लाइन, docker daemon json फ़ाइल ...)।

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.