J'avais l'habitude de créer un environnement Java avec Docker pendant un certain temps, mais au fait, cela crée une image Docker avec Maven sans écrire un Dockerfile Jib Je pensais que c'était le cas et je l'ai essayé.
Pour être honnête, je n'y ai pas prêté beaucoup d'attention parce que je me suis dit "N'est-il pas normal d'écrire un Dockerfile normalement?", Mais c'est étonnamment pratique à utiliser.
Cette fois, j'ai créé un environnement Java 11 avec mon environnement de développement principal, Mac + NetBeans, donc je vais décrire comment le faire. Il y avait aussi un petit piège, alors je vais le lister aussi.
Le produit fini est ci-dessous. https://github.com/koduki/example-jib
Evidemment, écrivez d'abord le code à exécuter. Tout va bien, mais une fois cela ressemble à ce qui suit. Il semble que «public static void main» soit nécessaire comme point de terminaison.
public class Main {
public static void main(String[] args) {
System.err.printf("%s %s, %s %s" + System.lineSeparator(),
System.getProperty("os.name"),
System.getProperty("os.version"),
System.getProperty("java.vm.name"),
System.getProperty("java.vm.version")
);
System.out.println("Hello World.");
}
}
Alors ajoutons quand même Jib. C'est aussi simple que d'ajouter un plug-in à pom.xml.
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.0.0-rc2</version>
<configuration>
<from>
<image>openjdk:11-jdk-slim</image>
</from>
<to>
<image>example-jib</image>
</to>
<container>
<jvmFlags>
<jvmFlag>-Xmx512m</jvmFlag>
<jvmFlag>-Xdebug</jvmFlag>
</jvmFlags>
</container>
</configuration>
</plugin>
Pour plus de détails, reportez-vous au Document officiel, mais il y a quelques points.
Tout d'abord, la balise to / image
, qui spécifie le nom de l'image après la construction. Et la balise from / image
, qui spécifie l'image d'origine.
from / image
est facultatif, auquel cas gcr.io / distroless / java
sera utilisé par défaut.
Cependant, puisque cet environnement est Java8, si vous souhaitez utiliser un JDK tel que Java11, vous devez le spécifier explicitement, alors soyez prudent.
Avec container
, vous pouvez spécifier diverses choses telles que les options JVM. Bien que cela ne soit pas spécifié cette fois, utilisez extraDirectory Vous pouvez également faire l'équivalent de ʻADD` dans le Dockerfile.
Cependant, les fichiers dans src / resouces sont automatiquement ajoutés au conteneur, il peut donc ne pas entrer autant en jeu.
Si vous voulez jouer avec le conteneur d'une manière compliquée, je pense qu'il serait plus facile de créer une image de base avec Jib et d'en faire un FROM.
Vient ensuite la construction de l'image.
$ mvn compile jib:dockerBuild
Cela seul ignorera la création du Dockerfile et créera une image. Vous devriez être en mesure de voir que l'image est créée correctement comme indiqué ci-dessous.
% docker images|grep example-jib
example-jib latest 8ec59091042c 49 years ago 491MB
Dans le cas de dockerBuild
, l'image est enregistrée dans le démon Docker local, mais si vous voulez pousser directement vers une télécommande telle que DockerHub, utilisez jib: build
.
De plus, si vous utilisez Docker pour Mac à ce moment, vous pouvez obtenir l'erreur suivante.
Failed to execute goal com.google.cloud.tools:jib-maven-plugin:1.0.0-rc2:dockerBuild (default-cli) on project example-jib: Build to Docker daemon failed, perhaps you should make sure Docker is installed and you have correct privileges to run it -> [Help 1]
C'est simplement parce que Jib n'a pas trouvé le démon docker, mais si vous appuyez directement sur la commande docker, cela fonctionne normalement? ?? ?? C'était comme ça.
Cependant, il est facile de révéler les graines, et lors de l'appel de docker pour Mac directement depuis la ligne de commande, il n'est pas nécessaire de spécifier DOCKER_HOST
, donc il n'a pas été inclus dans la variable d'environnement.
Pourquoi, il est nécessaire d'ajouter DOCKER_HOST
à la variable d'environnement avec la commande suivante etc.
export DOCKER_HOST=unix:///var/run/docker.sock
J'aimerais que vous mentionniez ce domaine dans READ ME, mais je me demande s'il était trop évident pour ceux qui le connaissent et que personne ne s'en soucie. .. ..
Vient ensuite l'exécution du conteneur de Maven. Vous pouvez faire docker run
normalement, mais ce n'est pas pratique car vous devez démarrer le terminal séparément. .. .. J'ai donc essayé de rendre cela également possible à partir de Maven.
Jib lui-même semble être spécifique à la construction et il ne semble pas y avoir de mécanisme pour l'exécuter, j'ai donc mis un autre plug-in appelé fabric8io / docker-maven-plugin J'ai fait. C'est pourquoi j'ai ajouté ce qui suit à pom.xml.
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.28.0</version>
<configuration>
<showLogs>true</showLogs>
<images>
<image>
<name>example-jib</name>
<run>
<log>
<enabled>true</enabled>
</log>
<wait>
<exit>0</exit>
</wait>
</run>
</image>
</images>
<keepContainer>false</keepContainer>
</configuration>
</plugin>
Voir la documentation officielle pour plus de détails, mais spécifiez l'image à exécuter avec ʻimage / nom`. Si vous avez besoin d'un volume ou d'un port, c'est comme ajouter pour exécuter.
Les points sont showLogs
, ʻimage / run / log / enabled, ʻimage / run / wait / exit
. Si cette zone n'est pas spécifiée, le résultat de l'exécution ne sera pas émis vers la sortie standard.
showLogs
et ʻimage / run / log / enabledsont des options pour afficher le résultat de l'exécution sous forme de journal. Cependant, cela ne suffit pas, et si vous n'enregistrez pas quelque chose dans la balise
wait, l'exécution se terminera instantanément et rien n'apparaîtra à l'écran. Par conséquent, ʻexit 0
pour confirmer l'achèvement normal est vérifié.
Lorsque vous faites cela, vous obtenez:
% mvn docker:start
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< cn.orz.pascal:example-jib >----------------------
[INFO] Building example-jib 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- docker-maven-plugin:0.28.0:start (default-cli) @ example-jib ---
[INFO] DOCKER> [example-jib:latest]: Start container ec75063ae514
ec7506> Linux 4.9.125-linuxkit, OpenJDK 64-Bit Server VM 11.0.1+13-Debian-2bpo91
ec7506> Hello World.
[INFO] DOCKER> [example-jib:latest]: Waited on exit code 0 964 ms
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.142 s
[INFO] Finished at: 2019-01-13T20:09:12-08:00
[INFO] ------------------------------------------------------------------------
Étant donné que la partie OS du résultat de l'exécution est Linux au lieu de Mac, vous pouvez voir qu'elle est correctement démarrée dans le conteneur.
Si vous voulez tout faire fonctionner à partir de la ligne de commande, vous pouvez appuyer sur jib: dockerBuildou
docker: start` à chaque fois, mais généralement vous développez avec IDE, n'est-ce pas? C'est Java.
Avec NetBeans, vous pouvez enregistrer des objectifs personnalisés maven, mais je n'ai pas envie d'utiliser l'EDI, donc je vais le configurer un peu plus intégré.
Dans le cas de NetBeans, il est courant de créer une image de construction avec "Build" dans le menu. Pour Java, jar est pour Java EE, et pour Java EE, la guerre est appropriée.
Pourquoi écraser la phase package
de Maven pour que l'image Docker soit toujours générée.
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
...
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>dockerBuild</goal>
</goals>
</execution>
</executions>
</plugin>
J'ai ajouté la balise d'exécution à la partie de configuration du plug-in plus tôt. Vous pouvez maintenant lancer jib: dockerBuild
avec mvn package
comme ci-dessous.
% mvn package
[INFO] Scanning for projects...
...
[INFO] --- jib-maven-plugin:1.0.0-rc2:dockerBuild (default) @ example-jib ---
[INFO]
[INFO] Containerizing application to Docker daemon as example-jib...
[INFO] The base image requires auth. Trying again for openjdk:11-jdk-slim...
[INFO]
[INFO] Container entrypoint set to [java, -Xmx512m, -Xdebug, -cp, /app/resources:/app/classes:/app/libs/*, cn.orz.pascal.example_jib.Main]
...
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19.345 s
[INFO] Finished at: 2019-01-13T20:07:28-08:00
[INFO] ------------------------------------------------------------------------
Puisque la Build
de NetBeans appelle la phase package
de Maven, il est normal que le côté NetBeans fasse simplement Build
depuis le menu normalement sans définir d'objectif personnalisé.
Vient ensuite l'exécution du conteneur. En fait, il n'y a pas de phase équivalente «d'exécution» dans le cycle de vie standard de Maven. ʻOrg.codehaus.mojo: exec-maven-plugin: 1.5.0: exec` est en fait exécuté, mais comme il n'est exécuté qu'en spécifiant directement l'objectif, comment l'accrochage du côté Maven Je ne savais pas si cela devait être fait.
Ainsi, Maven a décidé d'abandonner et de ne modifier que les paramètres NetBeans. Pour personnaliser des actions standard telles que «Exécuter», éditez nbactions.xml directement sous le projet.
<?xml version="1.0" encoding="UTF-8"?>
<actions>
<action>
<actionName>run</actionName>
<goals>
<goal>docker:start</goal>
</goals>
</action>
</actions>
Maintenant, si vous exécutez Exécuter à partir de NetBeans, docker: start
sera exécuté à la place de ʻexec: exec`.
Voici un résumé de la manière d'intégrer parfaitement Docker, Maven et NetBeans avec Jib. Si vous développez en Java, il est assez pratique de pouvoir faire diverses choses intégrées à l'EDI plutôt qu'à la CLI. Je suis content d'avoir pu le faire car il n'y a aucun sentiment d'intégration avec des objectifs personnalisés.
Cette fois, j'ai écrit Java basé sur CLI, mais il semble que Java EE puisse être imagé avec Jib sans aucun problème, donc j'aimerais étudier ce domaine la prochaine fois.
Je me demande si c'est un pas en avant pour utiliser Docker au travail.
Alors bon piratage!