3

I have a large scale java application with 5 Main methods in different classes. I want to run this application as a docker container. From DockerHub OpenJDK Image, I started my Dockerfile as follows

FROM openjdk:latest
COPY . /usr/src/APP
WORKDIR /usr/src/APP`

and I want to add the lines to run the main methods. Without Docker, I run the app using the below lines

echo 'Starting App'
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class1  >> 
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class2  >> 
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class3  >> 
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class4  >> 
/path/to/nohup/nohup.out 2>&1 &
nohup $JAVA_HOME/bin/java .:./App.jar path.to.main.class5  >> 
/path/to/nohup/nohup.out 2>&1 &
echo 'App Started Successfully'`

Is it possible to run the above scenario in one docker container? If possible, how can it be done while there can only be one ENTRYPOINT and CMD instructions in a Dockerfile ?

JonK
  • 2,097
  • 2
  • 25
  • 36
Randa ElBehery
  • 167
  • 2
  • 17
  • 3
    add all to one `.sh` and add this .sh to CMD – LinPy Nov 25 '19 at 12:55
  • @LinPy Would it differ if I used CMD or ENTRYPOINT in this case ? – Randa ElBehery Nov 25 '19 at 13:02
  • 1
    @RandaElBehery. See this other answer for differences between CMD and ENTRYPOINT: https://stackoverflow.com/questions/21553353/what-is-the-difference-between-cmd-and-entrypoint-in-a-dockerfile/21564990#21564990 – Zeitounator Nov 25 '19 at 13:05
  • The Docker docs explain how to do this with a script or using supervisord: https://docs.docker.com/config/containers/multi-service_container/ . In general I would use `supervisord` rather than a script, as it can monitor and restart services that die. – Augusto Nov 25 '19 at 14:44

1 Answers1

5

The usual answer to "how do I run multiple processes from one image" is to run multiple containers. Given the Dockerfile you show this is fairly straightforward:

# Build the image (once)
docker build -t myapp .

# Then run the five containers as background processes
docker run -d --name app1 java .:./App.jar path.to.main.class1
docker run -d --name app2 java .:./App.jar path.to.main.class2
docker run -d --name app3 java .:./App.jar path.to.main.class3
docker run -d --name app4 java .:./App.jar path.to.main.class4
docker run -d --name app5 java .:./App.jar path.to.main.class5

Since all of the commands are pretty similar, you could write a script to run them

#!/bin/sh

# Use the first command-line argument as the main class
MAIN_CLASS="$1"
shift

# Can also set JAVA_OPTS, other environment variables, ...

# Run the application
exec java -jar App.jar "path.to.main.$MAIN_CLASS" "$@"

copy that into the image

COPY run_main.sh /usr/local/bin

and then when you launch the containers just run that wrapper

docker run -d --name app1 run_main.sh class1
David Maze
  • 130,717
  • 29
  • 175
  • 215