Docker – How to run a shell script using dockerfiles CMD

dockerdockerfile

I am using dockerfiles to build a simple container. Here is the Dockerfile:

FROM XXXXXXX:5003/base-java

MAINTAINER XXXXX

ADD pubsub/ /opt/pubsub/

CMD ["/opt/pubsub/run.sh"]

Content of run.sh is as follows:

#!/bin/bash
nohup java -jar /opt/pubsub/publish.jar &
nohup java -jar /opt/pubsub/subscribe.jar &

This is simple java application for pub/sub.

Now I have got another container running rabbitmq and I am linking the 2 containers however each of my attempt has just failed and My pub/sub container does not start. Can someone advice how to go about debuggin this issue? Somehow docker logs does not have anything.

Here is how I am linking the containers: sudo docker run -d -P --name pub_sub --link rabbitmq:rabbitmq1 image_pub_sub

And here is how I am using the alias name in my pub/sub code

factory = new ConnectionFactory(); 
factory.setHost("rabbitmq1"); 
try { connection = factory.newConnection(); 
channel = connection.createChannel(); 
channel.queueDeclare("pub", true, false, false, null); 
} 
catch (IOException e) { // TODO Auto-generated catch block 
e.printStackTrace(); }

I was expecting that my publish code will create a queue in the rabbitmq container and start pushing messages. My subscriber code will basically connect to the same rabbitmq and start reading the messages.

When I run the command nothing happens it just prints a long id of the new container and exits..When I run sudo docker ps -a, I can see the following:

e8a50d5aefa5     image_pub_sub:latest     "/opt/pubsub/run.sh"     32 minutes ago     Exited (0) 32 minutes ago     pub_sub

So this means my container is not running.

Just now I tested by updating the /etc/hosts by launching a new container using the following command: sudo docker run -i -t image_pub_sub /bin/bash. Modified the /etc/hosts of this new container and added the following entry <IP_ADDRESS> rabbitmq1 and ran my script /opt/pubsub/run.sh and it appends the nohup file with the following messages:

Message Sent
 [x] Received 'Hello'
Message Sent
Message Sent
 [x] Received 'Hello'

Best Solution

A Docker container will stop when its main process completes. In your case, this means the two Java applications will be forked to the background (because of the nohup call) then the script will immediately complete and the container will exit.

There are a few solutions:

  • The quickest and easiest solution is to just remove nohup call from the second java call. That way the script won't exit until the second Java application exits.
  • Use a process manager such as runit or supervisord to manage the processes.
  • Put the jars in separate containers and call Java directly (this would seem to be the best solution to me).