userMod2
userMod2

Reputation: 9000

defining multiple services on Dockerfile with single CMD

Say I have the commands:

rails server

and

bundle exec something:default

I understand my Dockerfile can only have 1 CMD line so is it ok to do:

CMD ["sh", "-c", "rail server && bundle exec something:default"]

As it's just those 2 commands, I don't want to COPY a script.sh then use that (hoping for a simple 1 line way).

Is there a best practice I should be aware of when running 2 services in one container?

Upvotes: 9

Views: 10639

Answers (4)

Jason Pascoe
Jason Pascoe

Reputation: 345

It is best practice to run a single service in each container, but it is not always practical. I run CMD ["sh", "-c", "/usr/sbin/crond && php-fpm"] so I can use the laravel scheduler. So in answer to the question, yes the above does work.

Upvotes: 4

b0gusb
b0gusb

Reputation: 4731

The rule of thumb is to have "one process per container". The purpose of the rule is to decouple applications into multiple containers. Take a look here Best practices for writing Dockerfiles - Each container should have only one concern

So if you are running two Rails applications it's probably better to create two containers.

The way you run the two services has a couple of issues. First, the processes are not supervised so the container cannot manage them correctly. Use a process manager like supervisord, if this is a concern. See Run multiple services in a container. Second, the services are started by a shell so the signals will not reach your application.

Upvotes: 0

nickgryg
nickgryg

Reputation: 28753

Docker container is running while main process inside it is running. So if you want to run two services inside docker container, one of them has to be run in a background mode.

So, CMD layer should be the following:

CMD ( rail server & ) && bundle exec something:default

Upvotes: 0

Jorge
Jorge

Reputation: 137

You can create a bash script

#!/bin/bash
rail server
bundle exec something:default

then add a COPY to your Dockerfile

COPY mycmd.sh /app

/app is your destination

and finally execute your script in a CMD step

CMD ["mycmd.sh"]

Upvotes: 2

Related Questions