Cómo hacer que dos JAR se inicien automáticamente en el "contenedor de ejecución del acoplador"

Quiero que se ejecuten automáticamente dos files JAR separados una vez que se llama un contenedor docker a través de un command de ejecución, de modo que cuando docker run mycontainer ambos son llamados. Hasta ahora, tengo un file docker que se ve así:

 # base image is java:8 (ubuntu) FROM java:8 # add files to image ADD first.jar . ADD second.jar . # start on run CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "first.jar"] CMD ["/usr/lib/jvm/java-8-openjdk-amd64/bin/java", "-jar", "second.jar"] 

Esto, sin embargo, solo comienza en second.jar.

Ahora, ambos jar son serveres en un bucle, así que supongo que una vez que se inicia simplemente bloquea la terminal. Si ejecuto el contenedor usando run -it mycontainer bash y los llamo manualmente también, el primero hará sus salidas y no puedo iniciar el otro.

¿Hay alguna manera de abrir diferentes terminales y cambiar entre ellas para que cada JAR se ejecute en su propio context? Preferiblemente ya está en el file docker.

No sé casi nada sobre ubuntu pero encontré el command xterm que abre una nueva terminal, sin embargo, esto no funcionará después de llamar a un JAR. Lo que estoy buscando son instrucciones para el interior del file docker que, por ejemplo, abren una nueva terminal, ejecutan first.jar, alt-tab en la terminal anterior y ejecutan second.jar allí, o al less logran lo mismo.

¡Gracias!

La segunda instrucción CMD reemplaza a la primera, por lo que debe usar una sola instrucción para ambos commands.

Enfoque fácil (no tan bueno)

Puede agregar un script bash que ejecute commands y bloques en el segundo:

 # start.sh /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar first.jar & /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar 

A continuación, cambie su file Docker a este:

 # base image is java:8 (ubuntu) FROM java:8 # add files to image ADD first.jar . ADD second.jar . ADD start.sh . # start on run CMD ["bash", "start.sh"] 

Al utilizar docker stop es posible que no se cierre correctamente, consulte: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

Mejor enfoque

Para resolver esto, puede usar Phusion: https://hub.docker.com/r/phusion/baseimage/
Tiene un sistema init que es mucho más fácil de usar que, por ejemplo, supervisord.

Este es un buen punto de partida: https://github.com/phusion/baseimage-docker#getting_started

Instrucciones para usar phusion

Lamentablemente, no hay openjdk-8-jdk oficial disponible para Ubuntu 14.04 LTS. Puedes probar con un ppa no oficial, que se usa en la siguiente explicación.

En su caso, necesitaría bash scripts (que actúan como "services"):

 # start-first.sh (the file has to start with the following line!): #!/bin/bash usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /root/first.jar # start-second.sh #!/bin/bash usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar /root/second.jar 

Y tu file Dockerfile se vería así:

 # base image is phusion FROM phusion/baseimage:latest # Use init service of phusion CMD ["/sbin/my_init"] # Install unofficial openjdk-8 RUN add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get dist-upgrade -y && apt-get install -y openjdk-8-jdk ADD first.jar /root/first.jar ADD second.jar /root/second.jar # Add first service RUN mkdir /etc/service/first ADD start-first.sh /etc/service/first/run RUN chmod +x /etc/service/first/run # Add second service RUN mkdir /etc/service/second ADD start-second.sh /etc/service/second/run RUN chmod +x /etc/service/second/run # Clean up RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 

Esto debería instalar dos services que se ejecutarán al inicio y se apagarán correctamente cuando se utilice la docker stop .

Un contenedor Docker solo tiene un process único cuando se inicia.

Todavía puedes crear varios processs después .:

Tienes pocas opciones. Muchas de las respuestas han mencionado usar supervisor para esto, que es una buena solución. Aquí hay algunos otros:

Crea un guión corto que simplemente inicie ambos flasks. Añádelo a tu CMD. Por ejemplo, el script, que llamaremos run_jars.sh podría verse así:

 /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar first.jar; /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar; 

Entonces tu CMD sería CMD sh run_jars.sh

Otra alternativa es simplemente ejecutar dos contenedores separados: uno para first.jar y el otro para second.jar . Puede ejecutar cada uno a través de la docker run , por ejemplo:

docker run my_repo/my_image:some_tag /usr/lib/jvm/java-8-openjdk-amd64/bin/java -jar second.jar

Si desea iniciar dos processs diferentes dentro de un contenedor de acoplador (no es un comportamiento recomendado) puede usar algo como supervisord