Is Docker ARG allowed within CMD instruction
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Docker ARG values are not directly available inside CMD or ENTRYPOINT instructions at runtime. ARG is a build-time variable that exists only during docker build. CMD runs at container start time, when ARG values are gone. To pass build-time values into runtime commands, copy the ARG into an ENV variable, which persists in the final image.
The Problem
The CMD instruction does not expand $APP_PORT because:
- The exec form
["echo", "$APP_PORT"]does no shell processing - Even in shell form,
ARGvariables do not exist at runtime
Why ARG Does Not Work in CMD
ARG values are intentionally not baked into the image for security. You might pass secrets as build args that should not persist.
Fix: Copy ARG to ENV
The ENV instruction captures the build-time ARG value and stores it in the image. CMD can then access it at runtime.
Exec Form vs Shell Form
The exec form ["cmd", "arg"] does not invoke a shell, so environment variables are not expanded. Wrap in sh -c to get expansion.
Complete Example
ARG Scope: Before and After FROM
ARG declared before FROM is only available in the FROM instruction itself. Redeclare it after FROM to use it in subsequent instructions.
Multi-Stage Builds
Each FROM starts a new build stage. ARG values from a previous stage do not carry over. Redeclare them in each stage where needed.
Using ENTRYPOINT with ARG
The same rules apply to ENTRYPOINT:
Runtime Override with docker run -e
Even without ARG, you can pass values at runtime:
${NAME:-World} provides a default if NAME is not set.
Common Pitfalls
- Using ARG directly in CMD:
ARGvalues do not exist at runtime. Always copy toENVfirst:ENV VAR=${ARG_VAR}. - Exec form does not expand variables:
CMD ["echo", "$VAR"]prints the literal string$VAR. Use shell form or["sh", "-c", "echo $VAR"]. - ARG scope resets after FROM: Each build stage starts fresh. Redeclare
ARGafter everyFROMwhere you need it. - Sensitive build args persisting in ENV: Copying a secret
ARGtoENVbakes it into the image. Use Docker secrets or mount secrets at build time instead (--mount=type=secret). - Overriding CMD with docker run:
docker run myapp /bin/shreplacesCMDentirely. UseENTRYPOINTfor the main command andCMDfor default arguments if you need partial overrides.
Summary
ARGis build-time only. It does not exist whenCMDorENTRYPOINTrun- Copy
ARGtoENVto make build-time values available at runtime:ENV VAR=${ARG_VAR} - Shell form
CMD echo $VARexpands variables; exec formCMD ["echo", "$VAR"]does not - Use
["sh", "-c", "command $VAR"]for variable expansion in exec form ARGscope resets after eachFROMin multi-stage builds- Use
docker run -e VAR=valueto overrideENVvalues at runtime
Related reading
- is it a good practice to put a war file image into docker containers?
- Is it necessary to RUN apk update apk upgrade in a docker build stage?
- Is it ok to run docker from inside docker?
- Is it possible for 2 containers inside a Pod to share the same Environment Variables?
- Is it possible to create an AWS AMI from a Docker image?
- Is it possible to create an AWS AMI from a Docker image?
- Is it possible to run containers on android devices?
- Is it possible to run docker image/DockerFile on AWS Lambda?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.