How to have two JARs start automatically on “docke

2019-04-29 08:48发布

I want two seperate JAR files to be executed automatically once a docker container is called via run command, so when I type docker run mycontainer they are both called. So far, I have a dockerfile that looks like this:

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

This, however, only starts second.jar.

Now, both jars are servers in a loop, so I guess once one is started it just blocks the terminal. If I run the container using run -it mycontainer bash and call them manually, too, the first one will do its outputs and I can't start the other one.

Is there a way to open different terminals and switch between them to have each JAR run in its own context? Preferably already in the dockerfile.

I know next to nothing about ubuntu but I found the xterm command that opens a new terminal, however this won't work after calling a JAR. What I'm looking for are instructions for inside the dockerfile that for example open a new terminal, execute first.jar, alt-tab into the old terminal and execute second.jar there, or at least achieve the same.

Thanks!

4条回答
霸刀☆藐视天下
2楼-- · 2019-04-29 08:56

If you want to start two different processes inside one docker container (not recommanded behaviour) you can use something like supervisord

查看更多
狗以群分
3楼-- · 2019-04-29 08:59

The second CMD instruction replaces the first, so you need to use a single instruction for both commands.

Easy (not so good) Approach

You could add a bash script that executes both commands and blocks on the second one:

# 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

Then change your Dockerfile to this:

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

When using docker stop it might not shut down properly, see: https://blog.phusion.nl/2015/01/20/docker-and-the-pid-1-zombie-reaping-problem/

Better Approach

To solve this, you could use Phusion: https://hub.docker.com/r/phusion/baseimage/
It has an init-system that is much easier to use than e.g. supervisord.

Here is a good starting point: https://github.com/phusion/baseimage-docker#getting_started

Instructions for using phusion

Sadly there is not official openjdk-8-jdk available for Ubuntu 14.04 LTS. You could try with an inofficial ppa, which is used in the following explanation.

In your case you would need to bash scripts (which act like "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

And your Dockerfile would look like this:

# 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/*

This should install two services which will be run on startup and shut down properly when using docker stop.

查看更多
ゆ 、 Hurt°
4楼-- · 2019-04-29 08:59

You have a few options. A lot of the answers have mentioned using supervisor for this, which is a fine solution. Here are some others:

Create a short script that just kicks off both jars. Add that to your CMD. For example, the script, which we'll call run_jars.sh could look like:

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

Then your CMD would be CMD sh run_jars.sh

Another alternative is just running two separate containers-- one for first.jar and the other for second.jar. You can run each one through docker run, for example:

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

查看更多
Evening l夕情丶
5楼-- · 2019-04-29 09:07

A Docker container has only a single process when it is started.

You can still create several processes afterward.:

查看更多
登录 后发表回答