Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

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 CMD and 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 Dockerfile.

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 PostgreSQL, Puma (app server) and Sidekiq (background worker).
With Flask or Django, that might be PostgreSQL, 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.

Your Dockerfile also likely has a CMD which starts your app server (Puma or gunicorn).

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 Dockerfile.

For example (using Rails):

Your CMD might be bundle exec puma -C config/puma.rb.

Here’s how to override that with Docker Compose:

    build: .

    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 Dockerfile’s CMD.

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.

Free Intro to Docker Email Course

Over 5 days you'll get 1 email per day that includes video and text from the premium Dive Into Docker course. By the end of the 5 days you'll have hands on experience using Docker to serve a website.