web-dev-qa-db-fra.com

Comment dockerize le projet maven? et combien de façons de le réaliser?

Je suis nouveau dans Docker et je ne sais pas comment exécuter un projet Java avec maven même si j’ai lu de nombreux documents et essayé de nombreuses méthodes.

  1. Devrais-je construire l'image en utilisant Dockerfile?
  2. À quoi ressemblent les commandes lorsqu'il s'agit d'exécuter le projet maven dans l'hôte avec Dockerfile?
60
Yashon Lin

Exemple de travail.

Ce n'est pas un tutoriel de démarrage de printemps. C'est la réponse mise à jour à une question sur la façon d'exécuter une construction Maven dans un conteneur Docker.

Question publiée à l'origine il y a 4 ans.

1. Générer une application

Utilisez l'initialiseur de printemps pour générer une application de démonstration

https://start.spring.io/

enter image description here

Extraire l'archive Zip localement

2. Créer un fichier Docker

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

Remarque

  • Cet exemple utilise un build multi-stage . La première étape est utilisée pour construire le code. La deuxième étape ne contient que le fichier jar construit et un JRE pour l’exécuter (notez comment le fichier jar est copié entre les étapes).

3. Construire l'image

docker build -t demo .

4. Exécuter l'image

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

Misc

Lisez la documentation de Docker Hub sur la manière dont la construction Maven peut être optimisée pour utiliser un référentiel local pour mettre en cache les fichiers JAR.

Mise à jour (2019-02-07)

Cette question a maintenant 4 ans et à cette époque, il était juste de dire que l'application de construction utilisant Docker avait subi des changements importants.

Option 1: construction en plusieurs étapes

Ce nouveau style vous permet de créer des images plus légères qui n'encapsulent pas vos outils de construction et votre code source.

Ici encore, l’exemple utilise l’image de base maven officiel pour exécuter la première étape de la construction à l’aide de la version souhaitée de Maven. La deuxième partie du fichier définit la manière dont le fichier jar construit est assemblé dans l'image de sortie finale.

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

Remarque:

  • J'utilise l'image distroless de base de Google, qui s'efforce de fournir juste assez de temps d'exécution pour une Java app.

Option 2: potence

Je n'ai pas utilisé cette approche, mais cela semble digne d'investigation, car cela vous permet de construire des images sans avoir à créer des choses désagréables comme Dockerfiles :-)

https://github.com/GoogleContainerTools/jib

Le projet a un plugin Maven qui intègre le packaging de votre code directement dans votre workflow Maven.


Réponse originale (inclus pour être complet, mais écrit il y a bien longtemps)

Essayez d'utiliser les nouvelles images officielles, il y en a une pour Maven

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

L'image peut être utilisée pour exécuter Maven au moment de la création afin de créer une application compilée ou, comme dans les exemples suivants, pour exécuter une construction Maven dans un conteneur.

Exemple 1 - Maven s'exécutant dans un conteneur

La commande suivante exécute votre construction Maven dans un conteneur:

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

Remarques:

  • La chose intéressante à propos de cette approche est que tous les logiciels sont installés et fonctionnent dans le conteneur. N'a besoin que de docker sur la machine hôte.
  • Voir Dockerfile pour cette version

Exemple 2 - Utilisez Nexus pour mettre en cache des fichiers

Lancer le conteneur Nexus

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

Créez un fichier "settings.xml":

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

Maintenant, lancez Maven vers le conteneur Nexus, de sorte que les dépendances soient mises en cache

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

Remarques:

  • Un avantage de l'exécution de Nexus en arrière-plan réside dans le fait que d'autres référentiels tiers peuvent être gérés via l'URL d'administration de manière transparente vers les versions Maven s'exécutant dans des conteneurs locaux.
58
Mark O'Connor

Il peut y avoir plusieurs façons .. Mais j'ai implémenté en suivant deux façons

L’exemple donné est celui du projet Maven.

1. Utilisation de Dockerfile dans le projet maven

Utilisez la structure de fichier suivante:

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

Et mettez à jour le fichier Docker en tant que:

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

Accédez au dossier du projet et tapez la commande suivante, vous serez libre de créer une image et de l'exécuter:

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

Obtenir la vidéo à Spring Boot avec Docker

2. Utiliser les plugins Maven

Ajouter le plugin maven donné dans 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>

Naviguez jusqu'au dossier du projet et tapez la commande suivante, vous pourrez créer une image et l'exécuter:

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

Dans le premier exemple, nous créons Dockerfile, fournissons une image de base et ajoutons jar. Après cela, nous allons exécuter la commande docker pour créer une image avec un nom spécifique, puis exécuter cette image.

Alors que dans le deuxième exemple, nous utilisons le plugin maven dans lequel nous fournissons baseImage et imageName, nous n’avons donc pas besoin de créer Dockerfile ici. Après avoir empaqueté le projet maven, nous obtiendrons juste besoin d'exécuter cette image ..

43
Riddhi Gohil

En règle générale, vous devez créer un gros fichier JAR à l'aide de Maven (un fichier JAR contenant à la fois votre code et toutes les dépendances).

Ensuite, vous pouvez écrire un Dockerfile qui correspond à vos besoins (si vous pouviez créer un gros fichier JAR, il vous suffirait d'un système d'exploitation de base, tel que CentOS, et de la machine virtuelle ).

C’est ce que j’utilise pour une Scala (basée sur Java).

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

Cela crée une image CentOS avec Java7. Une fois démarré, il exécutera votre jar d'application.

Le meilleur moyen de le déployer est via le registre de Docker, c'est comme un Github pour les images Docker.

Vous pouvez construire une image comme ceci:

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

Vous pouvez ensuite pousser une image de cette façon:

docker Push username/projectname # this pushes all tags

Une fois que l'image est dans le registre de Docker, vous pouvez l'extraire de n'importe où dans le monde et l'exécuter.

Voir Guide de l'utilisateur Docker pour plus d'informations.

Quelque chose à garder à l'esprit :

Vous pouvez également extraire votre référentiel à l'intérieur d'une image et construire le fichier jar dans le cadre de l'exécution du conteneur, mais ce n'est pas une bonne approche, car le code peut changer et vous risquez d'utiliser une autre version de l'application sans préavis.

Construire un pot de graisse élimine ce problème.

11
Matteo Pacini