web-dev-qa-db-fra.com

Manière correcte de déployer des fichiers WAR dans l'image Docker

Quelle est la méthode de docker pour déployer des projets Java dans un conteneur Docker?

Dois-je copier la guerre dans des webapps:

FROM jetty:9.2.10
MAINTAINER Me "[email protected]"
ADD ./target/*.war /var/lib/jetty/webapps/ROOT.war

ou dois-je prendre le fichier de guerre éclaté:

FROM jetty:9.2.10
MAINTAINER Me "[email protected]"
ADD ./target/app-0.1.0.BUILD-SNAPSHOT /var/lib/jetty/webapps/ROOT

Normalement, on déploierait le fichier de guerre scellé s'il s'agissait d'un conteneur normal, mais avec docker, cela signifie pousser un fichier de 10 à 20 Mo à chaque fois que vous apportez une petite modification tandis que l'ajout de la guerre éclatée ne ferait que pousser la différence - le fichier .class qui a changé.

Y a-t-il des inconvénients à déployer la guerre éclatée au lieu du fichier de guerre?

24

Je me demande comment vous utilisez vos images. L'ajout d'un fichier de 20 Mo lors de la création d'une image devrait être presque instantané. Vous pouvez en quelque sorte créer des images pendant le déploiement, comme AWS le fait lorsque vous lui donnez un Dockerfile.

En tout cas, je pense que cela dépend de la façon dont vous vous déployez. Si vous déplacez les images autour de vous, je ne vois pas beaucoup de différence entre AJOUTER un fichier .war et un répertoire WAR éclaté. Je dirais faire ce qui vous convient. Cependant, si vous exécutez parfois l'application à partir de Docker et parfois à partir d'un .war (qui peut manquer une partie de l'intérêt de Docker), vous pouvez tout aussi bien utiliser le .war tout le temps.

Si vous déployez vers quelque chose comme AWS Elastic Beanstalk (quelque chose qui extrait l'image d'un référentiel), qui veut soit un fichier Dockerfile soit un fichier Dockerrun.aws.json, séparer l'image de ce que vous déployez réellement a du sens (ou cela a eu du sens pour moi jusqu'à présent). Cela permet au conteneur de rester le même, tandis que la mise à jour de votre application peut simplement être la copie d'un fichier .jar/.war au bon emplacement (qui pourrait également manquer une partie du point de Docker;).

Ce que j'ai fait, c'est créer une image de base sur Docker Hub, puis utiliser le fichier Dockerrun.aws.json pour mapper dans mon application. De cette façon, AWS n'a pas besoin de créer mon image, il suffit de la tirer. C'est beaucoup plus rapide et moins coûteux ($). Mais cela sépare mon application de l'image, ce qui peut compliquer le déploiement dans certaines circonstances. Cependant, parce que mon image est si stable, je regroupe généralement un fichier .jar, un fichier Dockerrun.aws.json et un script Shell dans un .Zip et le télécharge sur AWS. Je pense que c'est assez facile.

Mon Dockerfile est assez simple et vraiment tout ce dont j'ai besoin pour mon application Spring Boot:

FROM Java:8
VOLUME /tmp
VOLUME /app
EXPOSE 8080
ENTRYPOINT ["sh","/app/app.sh"]

Vous pouvez faire quelque chose de similaire et utiliser l'option -v, etc., pour mapper les volumes à votre application, ses paramètres d'environnement, etc. BTW, cette image est disponible sur Docker Hub.

6
objectuser

Vous devriez en fait TOUJOURS déployer le .war éclaté.

Il y a deux éléments de vitesse à considérer ici:

  1. À quelle vitesse est-il possible de pousser votre image vers un référentiel de conteneurs?

    et

  2. À quelle vitesse une nouvelle instance de mon conteneur peut-elle commencer à traiter des demandes? (important dans un environnement à échelle élastique)

La réponse aux deux est la même: il est préférable d'exploser le fichier .war lors de la création de votre conteneur et de NE PAS copier le fichier .war dans celui-ci.

Cela a les deux effets très positifs suivants:

  1. Cela rend les différences entre les versions de conteneurs beaucoup plus petites, ce qui réduit le temps de téléchargement.
  2. Cela signifie que, lors de la mise à l'échelle dynamique pour répondre à la demande des applications, vos nouvelles instances de conteneur n'ont pas à décompresser votre fichier .war avant de pouvoir commencer à répondre aux demandes.

Pour ceux d'entre nous surchargés par les connexions à téléchargement lent, c'est également une excellente idée d'utiliser un serveur CI ou même un hébergé dans le cloud VM pour créer et pousser vos images de docker vers dockerhub ou un autre registre de conteneurs De cette façon, vous pouvez profiter de vitesses de téléchargement à l'échelle du gigabit.

8
Ryan Kimber

Voici comment je le fais:

FROM Tomcat:8.0
MAINTAINER David Ford <[email protected]>
ENV DB_Host mySqlServer
ENV DB_USER joeBlow
ENV DB_PASSWORD bla bla bla
EXPOSE 8080
RUN rm -fr /usr/local/Tomcat/webapps/ROOT
COPY target/webapp /usr/local/Tomcat/webapps/ROOT

Sur ma liste de tâches: séparez le répertoire WEB_INF/lib dans son propre conteneur.

6
Dave Ford

Vous pouvez essayer ceci: Copiez le fichier war dans le conteneur à l'aide de COPY Copiez le pot de jetty runner dans le conteneur à l'aide de COPY puis utilisez le CMD pour l'exécuter comme ceci ["Java -jar /path/to/jetty-runner.jar/chemin/vers/app.war "]

http://www.Eclipse.org/jetty/documentation/current/runner.html

REMARQUE: vous devrez avoir Java installé dans le conteneur.

1
Yogesh_D