October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk11 min

How to Use ENTRYPOINT in a Dockerfile: Exec Form, CMD, Signals, and Overrides

A practical guide to Dockerfile ENTRYPOINT: choose exec form for the main executable, pair it with CMD for replaceable defaults, preserve graceful shutdown with exec, and debug or override containers with the right Docker run options.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use an exec-form ENTRYPOINT for the executable that defines your container’s job, then use an exec-form CMD for default arguments that callers may replace. A practical pattern is ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] with CMD ["--help"], or an application directly such as ENTRYPOINT ["python", "-m", "myapp"].

The distinction matters at runtime: arguments typed after an image name replace CMD defaults, while docker run --entrypoint replaces ENTRYPOINT itself. Exec form also lets the application become PID 1, which improves signal handling and graceful shutdown.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What ENTRYPOINT does

Docker describes ENTRYPOINT as the instruction that configures a container to run as an executable. It establishes the image’s primary command—the process that gives the image its purpose. An image built to run a web server, worker, migration tool, or CLI can therefore behave like that executable when started.

There are two syntaxes:

Form Example How Docker starts it Important consequence
Exec form ENTRYPOINT ["executable", "param1", "param2"] Runs the executable directly. Arguments are separate JSON elements; no shell is inserted automatically.
Shell form ENTRYPOINT command param1 param2 Runs through the image shell, normally /bin/sh -c on Linux. Shell-form ENTRYPOINT ignores CMD and positional arguments supplied to docker run.

Docker recommends JSON-array syntax for ENTRYPOINT. JSON means double quotes are required, and the executable and every argument occupy their own array element.

The executable role belongs in ENTRYPOINT

Put a stable command in ENTRYPOINT when the image is intended to be run as a particular program. For example:

FROM python:3.13-slim
WORKDIR /app
COPY . .
ENTRYPOINT ["python", "-m", "myapp"]
CMD ["--config", "/etc/myapp/config.yml"]

Every normal start now invokes the Python module. The configuration option is a default, not part of the image’s identity, so a caller can select another file without replacing the executable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How ENTRYPOINT and CMD work together

The most useful design pairs an exec-form ENTRYPOINT with an exec-form CMD. The first defines the executable; the second supplies default parameters. Docker appends the CMD array to the ENTRYPOINT array unless the caller provides a replacement argument list.

ENTRYPOINT ["top", "-b"]
CMD ["-c"]

With no extra arguments, Docker starts the equivalent of top -b -c. If the image is started with docker run image -H, Docker starts top -b -H; the supplied list replaces CMD rather than being added after it.

Command Effective command What changed
docker run image top -b -c Uses the configured defaults.
docker run image -H top -b -H Replaces the CMD array while retaining ENTRYPOINT.
docker run --entrypoint /bin/sh -it image /bin/sh Replaces ENTRYPOINT itself.

Why an explicit CMD is often necessary

Docker requires a runnable image to have at least one CMD or ENTRYPOINT command. A base image may already define a CMD, but adding an ENTRYPOINT in your Dockerfile can reset that inherited default. Define the desired CMD in the current Dockerfile instead of relying on an inherited value whose meaning may no longer fit your executable.

Only the final ENTRYPOINT instruction has an effect. Earlier declarations are not combined, so a Dockerfile with several such lines silently uses the last one.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Understanding command resolution

Think of the image configuration as two separate arrays. ENTRYPOINT is the part that should remain stable; CMD is the initial value for the argument array. At launch, Docker combines them when both use exec form. Supplying words after the image name replaces the entire CMD array, not just one element and not by appending to the existing defaults.

That distinction explains why a command such as docker run image --config /tmp/test.yml still starts the configured application, while docker run --entrypoint /bin/sh image starts a different executable. The first operation changes parameters; the second changes the image’s executable role for one container.

If operators need to replace the whole command frequently, a fixed ENTRYPOINT may be unnecessarily restrictive. In that case, a plain exec-form CMD can provide a default command while allowing the command after the image name to replace it completely. Choose the arrangement that matches the image’s intended contract rather than adding ENTRYPOINT automatically.

Exec form versus shell form

Use exec form for predictable argument passing

Exec form is a JSON array, not a quoted command line. This is correct:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ENTRYPOINT ["python", "-m", "myapp"]

Docker passes three arguments to the process: python, -m, and myapp. There is no intermediate shell to reinterpret spaces, metacharacters, or variable references.

Exec form does not perform shell expansion. Expressions such as $PORT, pipes, redirection, command chaining, globbing, and shell conditionals are not interpreted automatically. If those features are genuinely part of the design, invoke a shell explicitly and make argument boundaries deliberate:

ENTRYPOINT ["/bin/sh", "-c", "exec myapp "$@"", "--"]

Here the final -- supplies the shell’s $0 value, while arguments passed by Docker become $@. The script uses exec so the shell is replaced by myapp after expansion.

When shell form is appropriate

Shell form can be useful for a command that intentionally depends on shell syntax, but it changes Docker’s override behavior. A shell-form ENTRYPOINT is run as a shell command, and Docker does not append CMD values or positional arguments from docker run in the way exec form does. If users must change flags at launch time, shell form is usually the wrong choice; use exec form or an explicit wrapper that forwards arguments.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PID 1, signals, and graceful shutdown

Docker sends the container’s stop signal to its main process. With an exec-form ENTRYPOINT, the intended application normally becomes PID 1 and can receive SIGTERM directly, perform cleanup, and exit within the runtime’s grace period.

A shell wrapper can sit between Docker and the application. In that arrangement the wrapper is PID 1, and the application may not receive the signal normally. Symptoms include a container that takes the full stop timeout, leaves child processes behind, or exits only after a forced kill.

The standard solution is to end a necessary wrapper with an exec hand-off:

#!/bin/sh
set -eu
# optional setup here
exec "$@"

exec replaces the wrapper process with the final command instead of creating a child that remains behind it. Copy the script into the image and make it executable:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
FROM alpine:3.20
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["--help"]

The Docker build check named JSONArgsRecommended recommends JSON-array CMD and ENTRYPOINT for this signal and process-management reason.

Designing a transparent wrapper

A wrapper is appropriate when startup needs preparation before the long-running program: for example, the script may perform the optional setup documented for the image, then hand control to the command supplied by CMD or by the caller. Keep that script small and explicit. Give it a valid interpreter line, copy it to the path used in ENTRYPOINT, and set execute permission during the build.

Use set -eu when setup errors should stop startup instead of allowing a partially prepared container to continue. Quote argument forwarding exactly as "$@"; this preserves each argument as a separate value, including spaces. A final line such as myapp "$@" starts the application as a child and leaves the script as PID 1. The final line exec myapp "$@", or exec "$@" when the command comes from CMD, replaces the script and restores direct signal delivery.

If a wrapper fails immediately, use an override shell to inspect its path, interpreter, permissions, line endings, and working directory. These checks distinguish a missing file from a valid script that cannot be executed by the chosen base image.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Overriding an image at runtime

Replace default arguments

Put ordinary arguments after the image name when you want to keep the configured executable but change its defaults:

docker run --rm myimage --config /tmp/test.yml

For an exec-form pair, Docker retains ENTRYPOINT and uses --config /tmp/test.yml as the new argument list. This is the normal mechanism for selecting a test configuration, a different subcommand, or a one-off flag.

Replace the executable

Use --entrypoint when debugging startup failures, inspecting an image, or running a maintenance command:

docker run --rm --entrypoint /bin/sh -it myimage

The option changes the executable for that invocation. It does not edit the Dockerfile or alter future containers. Add a command after the image name if the replacement executable needs one, for example docker run --rm --entrypoint /bin/sh -it myimage -c 'ls -la /app'.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A complete implementation workflow

1. Decide what must never change

Identify the program that defines the image’s job. If the image is a Python module, place the interpreter, module switch, and module name in ENTRYPOINT. If startup requires migrations, environment preparation, or file generation, use a wrapper script as the entrypoint.

2. Separate defaults from identity

Flags that operators may change belong in CMD. Keep each token separate in the JSON array. Do not put an entire command line into one element.

3. Add and test any wrapper

A wrapper must exist at the path named in ENTRYPOINT, have a valid interpreter line, and be executable in the image. Use set -eu when appropriate so setup failures do not silently continue, and finish with exec "$@" unless the wrapper intentionally remains the long-running supervisor.

4. Build and inspect the image

Build with your normal tag, then inspect the configured metadata if startup behavior is surprising:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
docker build -t myimage .
docker image inspect myimage

Inspect the image’s Config.Entrypoint and Config.Cmd values. This reveals whether a base-image default was replaced and whether the arrays contain the elements you intended.

5. Exercise all launch paths

  1. Start without arguments to verify the documented defaults.
  2. Start with a replacement argument list to verify CMD override behavior.
  3. Start with --entrypoint to verify that emergency access is possible.
  4. Stop the normal container and confirm the application receives termination and exits cleanly.

Testing the image as an interface

Test the image in the same combinations users will rely on. First run it with no arguments and record the effective command. Next provide a complete replacement argument list, not just one token, and verify that the executable remains unchanged. Then launch with --entrypoint /bin/sh (or the shell available in the base image) to confirm that a broken startup can still be inspected. Finally, stop the normal container and watch for clean termination rather than assuming that a successful start proves signal handling is correct.

When a result differs from expectation, compare the Dockerfile with docker image inspect output. Check whether the final ENTRYPOINT is the one you intended, whether Config.Cmd contains an inherited value, and whether every array element is split correctly. This metadata check is faster and more reliable than inferring configuration from a log line alone.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common mistakes and precise fixes

Putting a whole command in one JSON element

ENTRYPOINT ["python -m myapp"] asks Docker to find an executable literally named python -m myapp. Split it into ENTRYPOINT ["python", "-m", "myapp"].

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Using single quotes in exec form

Exec form follows JSON syntax, which requires double quotes. Replace single-quoted elements with valid JSON strings and check commas and brackets.

Expecting environment expansion in exec form

ENTRYPOINT ["myapp", "$PORT"] passes the characters $PORT as an argument; it does not expand the variable. Have the application read its environment, use a wrapper, or invoke an explicit shell when expansion is truly required.

Choosing shell form while expecting overrides

If docker run image new-value appears to have no effect, check whether ENTRYPOINT uses shell form. Convert it to exec form and put replaceable defaults in CMD, or write a wrapper that explicitly forwards arguments.

Forgetting exec in a wrapper

A setup script that ends with myapp "$@" leaves the script as PID 1. Change the final line to exec myapp "$@" or, when the command is supplied by CMD, exec "$@".

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Relying on an inherited CMD

If adding ENTRYPOINT causes an image to start without its former default arguments, define a new CMD in the child Dockerfile. Treat the base image’s command as an implementation detail, not a contract you have not checked.

Defining multiple entrypoints

Docker uses only the last ENTRYPOINT. Remove obsolete lines so the Dockerfile communicates one unambiguous startup design.

Choosing the right pattern

Requirement Recommended design Reason
One fixed application, replaceable flags Exec-form ENTRYPOINT plus exec-form CMD Preserves the executable while allowing argument replacement.
Startup preparation before the application Executable wrapper in ENTRYPOINT, ending with exec "$@" Performs setup without sacrificing PID 1 behavior.
Shell pipelines or conditionals are intrinsic Explicit /bin/sh -c with carefully quoted arguments Makes shell interpretation intentional and visible.
Image mainly used for interactive maintenance Normal entrypoint plus --entrypoint for one-off shells Keeps production startup predictable while retaining a debugging path.
Users must freely replace the whole command Consider relying on CMD rather than a fixed ENTRYPOINT A fixed entrypoint constrains the command that follows the image.

Diagnosing startup and shutdown problems

The container exits immediately

  • Check that the executable path exists in the image and has execute permission.
  • Inspect Config.Entrypoint and Config.Cmd for a missing or unexpectedly inherited value.
  • Run a shell with --entrypoint and verify the file, interpreter, line endings, and working directory.

Arguments are ignored

  • Confirm that ENTRYPOINT is exec form rather than shell form.
  • Check whether the wrapper actually forwards "$@".
  • Remember that positional arguments replace CMD; they do not append to it.

docker stop is slow or the app does not clean up

  • Check whether a shell or wrapper remains PID 1.
  • Use exec-form instructions or finish the wrapper with exec.
  • Verify that the application itself handles the termination signal and exits promptly.

Practical checklist

  • Is the image’s stable executable in an exec-form ENTRYPOINT?
  • Are replaceable defaults in an exec-form CMD?
  • Does every executable and argument occupy its own JSON element?
  • Are all JSON strings double-quoted?
  • If shell syntax is required, is the shell invoked explicitly and are arguments quoted?
  • If a wrapper is used, is it copied, executable, and finished with an exec hand-off?
  • Have you tested normal startup, positional argument overrides, --entrypoint debugging, and shutdown?
  • Have you checked the final image metadata rather than assuming the base image’s CMD survived?

Frequently Asked Questions

What does ENTRYPOINT do in a Dockerfile?

It configures the executable a container runs and defines the image’s primary job. Use exec form when that executable should receive arguments and termination signals directly.

What is the difference between ENTRYPOINT and CMD?

ENTRYPOINT identifies the stable executable. CMD supplies default arguments (or, when no ENTRYPOINT is used, a default command) that can be replaced at runtime.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use exec form or shell form?

Prefer exec form for predictable argument boundaries, runtime overrides, and direct signal delivery. Use shell form only when shell expansion, pipelines, redirection, or conditionals are intentionally required.

Why does docker stop not stop my application cleanly?

A shell or wrapper may be PID 1 and may receive the stop signal instead of the application. Use exec-form instructions or end the wrapper with exec "$@", then ensure the application handles termination.

How do I override an ENTRYPOINT?

Pass --entrypoint to docker run, such as docker run --rm --entrypoint /bin/sh -it myimage. This changes only that container invocation.

How do I override CMD without replacing ENTRYPOINT?

Put the replacement arguments after the image name: docker run --rm myimage --config /tmp/test.yml. Those arguments replace the configured CMD array.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does ENTRYPOINT [“python -m myapp”] fail?

Each JSON element is one argument, so Docker looks for an executable whose name contains spaces. Use ENTRYPOINT ["python", "-m", "myapp"] instead.

Why did adding ENTRYPOINT remove my base image’s default arguments?

Defining an ENTRYPOINT can reset an inherited CMD. Add the intended CMD explicitly in the current Dockerfile and verify Config.Cmd with docker image inspect.

The Bottom Line

Use exec-form ENTRYPOINT for the executable that gives the image its purpose and pair it with exec-form CMD for replaceable defaults. Choose shell form only for intentional shell behavior, make wrappers end with exec, and use positional arguments or --entrypoint according to whether you are changing defaults or the executable itself.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.