Docker Tip #8: Overriding Your Dockerfile's CMD
If you've built any type of real world web app, chances are you've wanted to run different services from the same Docker image. Here's how.
Last week we covered the difference between
RUN in a
Dockerfile, and today I’d like to cover leveraging the same Docker image for multiple services. This is made possible by overriding the default
CMD in your
Before we get into that, here’s a very common use case:
Let’s say that you have a standard Ruby on Rails or Flask / Django application. It is composed of a database, your web app server and a background worker.
With Rails, that could be
Puma (app server) and
Sidekiq (background worker).
With Flask or Django, that might be
gunicorn (app server) and
Celery (background worker).
Chances are you have your Rails or Flask / Django application running in its own Docker container, and you have a single
Dockerfile also likely has a
CMD which starts your app server (
But, you also want to run your background worker in its own container. This way you can independently scale it from your web app server. This is considered a best practice.
Docker makes this very easy. All you have to do is supply a new command to run when you start your Docker image, and it will override the
CMD in your
For example (using Rails):
CMD might be
bundle exec puma -C config/puma.rb.
Here’s how to override that with Docker Compose:
website: build: . sidekiq: build: . command: sidekiq -C config/sidekiq.yml
That’s all there is to it. Now you have a completely separate service for your background worker and it will use the same exact
Dockerfile as your main web application. The
command: property’s value will take precedence over your
The same can be done on the command line with
docker run. You would just supply the custom command at the end of your
docker run command.