Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I use Docker CMD multiple times to run multiple services?

Tags:

docker

I have built a base image from Dockerfile named centos+ssh. In centos+ssh's Dockerfile, I use CMD to run ssh service.

Then I want to build a image run other service named rabbitmq,the Dockerfile:

FROM centos+ssh EXPOSE 22 EXPOSE 4149 CMD /opt/mq/sbin/rabbitmq-server start 

To start rabbitmq container,run:

docker run -d -p 222:22 -p 4149:4149 rabbitmq 

but ssh service doesn't work, it sense rabbitmq's Dockerfile CMD override centos's CMD.

  1. How does CMD work inside docker image?
  2. If I want to run multiple service, how to? Using supervisor?
like image 359
edwardsbean Avatar asked May 16 '14 04:05

edwardsbean


People also ask

Can we have multiple CMD in Dockerfile?

There can only be one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect. If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.

Can a Docker container have multiple services?

It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.


2 Answers

You are right, the second Dockerfile will overwrite the CMD command of the first one. Docker will always run a single command, not more. So at the end of your Dockerfile, you can specify one command to run. Not more.

But you can execute both commands in one line:

FROM centos+ssh EXPOSE 22 EXPOSE 4149 CMD service sshd start && /opt/mq/sbin/rabbitmq-server start 

What you could also do to make your Dockerfile a little bit cleaner, you could put your CMD commands to an extra file:

FROM centos+ssh EXPOSE 22 EXPOSE 4149 CMD sh /home/centos/all_your_commands.sh 

And a file like this:

service sshd start & /opt/mq/sbin/rabbitmq-server start 
like image 60
Thomas Uhrig Avatar answered Oct 11 '22 19:10

Thomas Uhrig


Even though CMD is written down in the Dockerfile, it really is runtime information. Just like EXPOSE, but contrary to e.g. RUN and ADD. By this, I mean that you can override it later, in an extending Dockerfile, or simple in your run command, which is what you are experiencing. At all times, there can be only one CMD.

If you want to run multiple services, I indeed would use supervisor. You can make a supervisor configuration file for each service, ADD these in a directory, and run the supervisor with supervisord -c /etc/supervisor to point to a supervisor configuration file which loads all your services and looks like

[supervisord] nodaemon=true  [include] files = /etc/supervisor/conf.d/*.conf 

If you would like more details, I wrote a blog on this subject here: http://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance/

like image 36
qkrijger Avatar answered Oct 11 '22 18:10

qkrijger