How to Override CMD in Docker Containers: Complete Guide for Developers


4 views

When working with Docker images, it's crucial to understand how ENTRYPOINT and CMD interact. The ENTRYPOINT specifies the executable that will run when the container starts, while CMD provides default arguments to that executable.

# Example Dockerfile snippet
ENTRYPOINT ["/usr/sbin/apache2ctl"]
CMD ["-D", "FOREGROUND"]

When debugging or inspecting containers, you often want to:

  • Drop into an interactive shell
  • Run diagnostic commands
  • Test alternative configurations

The common method to inspect a container is:

docker run -it --entrypoint=/bin/bash imagename --login

This works but requires the --login argument because the original CMD ("-D", "FOREGROUND") would otherwise be passed to bash.

Here are three methods to completely override the CMD:

1. Explicit Empty CMD Override

docker run -it --entrypoint=/bin/bash imagename

This works because specifying a new entrypoint automatically clears the CMD unless you provide arguments.

2. Using Double Dash Syntax

docker run -it --entrypoint= imagename /bin/bash

The empty --entrypoint= clears the entrypoint, and everything after the image name becomes the new CMD.

3. JSON Array Format for Precision

docker run -it --entrypoint='[]' imagename /bin/bash

This explicitly sets an empty entrypoint using JSON array syntax.

For our Apache example, here's how to get a clean shell:

# Method 1: Clear both entrypoint and cmd
docker run -it --entrypoint= imagename /bin/bash

# Method 2: Keep entrypoint but clear cmd
docker run -it --entrypoint=/bin/bash imagename

To see what command will actually run:

docker inspect --format='{{.Config.Cmd}}' imagename
docker inspect --format='{{.Config.Entrypoint}}' imagename

When working with Docker containers, you might encounter images where both ENTRYPOINT and CMD are predefined. For example:

ENTRYPOINT ["/usr/sbin/apache2ctl"]
CMD ["-D", "FOREGROUND"]

This configuration starts Apache in foreground mode by default. But what if you need to debug or run alternative commands?

The simplest way to bypass the default CMD is by specifying a new command after the image name:

docker run -it --entrypoint=/bin/bash my-image

However, this still executes the shell with arguments. To completely override CMD, you need to explicitly set it to empty:

Use the following syntax to replace the entire CMD instruction:

docker run -it --entrypoint=/bin/bash my-image

Or more precisely:

docker run -it --entrypoint=/bin/bash my-image ""

The empty quotes ensure no arguments are passed to the entrypoint.

For more complex scenarios, consider these approaches:

# Method 1: Using --cmd flag (Docker 20.10+)
docker run -it --entrypoint=/bin/bash --cmd="" my-image

# Method 2: JSON array syntax
docker run -it --entrypoint='["/bin/bash"]' my-image

# Method 3: Override both entrypoint and cmd
docker run -it --entrypoint= --cmd='[]' my-image /bin/bash

When inspecting an Apache container:

# Start interactive shell without Apache
docker run -it --entrypoint=/bin/bash httpd:latest

# Or for temporary debugging:
docker run -it --entrypoint=/bin/bash httpd:latest -c "apt update && apt install -y curl"
  • Some minimal base images might not have /bin/bash - use /bin/sh instead
  • The override only affects the current container instance
  • For permanent changes, rebuild the image with new instructions