Passing NODE_ENV to docker to run package.json scripts
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When a Node.js application changes behavior based on NODE_ENV, the important question in Docker is where that variable should be set. The answer depends on whether you need the value during image build, during container runtime, or both, because Docker treats build-time and runtime configuration as separate scopes.
Set NODE_ENV at Runtime for Script Behavior
If the goal is to control how npm run ... behaves inside a running container, the cleanest place is usually the runtime environment.
This passes NODE_ENV=development into the container process. The script can then read it through process.env.NODE_ENV.
A small diagnostic script makes this easy to verify.
Then run:
That should print staging.
Use ENV in the Dockerfile for a Default
If you want the image to have a default runtime value, set it in the Dockerfile.
This gives the container a baseline value, but docker run -e NODE_ENV=... can still override it at runtime.
That is usually what you want: a production-safe default that can be replaced explicitly in development or staging.
Understand Build-Time Versus Runtime Scope
A frequent source of confusion is expecting a build argument to keep affecting the running container automatically. ARG and ENV are not the same thing.
Build with:
ARG exists only during image build unless you copy it into ENV. If the variable only matters to the running application, a plain runtime environment variable is usually simpler.
Docker Compose Is Better for Team Workflows
For repeatable local development and staging setups, Docker Compose or another orchestrator is usually better than remembering long docker run commands.
This keeps environment configuration declarative and visible to the team.
If the project uses several services, Compose also prevents subtle drift where one container gets the right environment and another silently uses the Dockerfile default.
The same explicitness helps in CI. When a pipeline fails, it is much easier to reproduce locally if the source of NODE_ENV is visible in Compose or the runner command instead of being implied indirectly.
Be Explicit About Dependency Installation
NODE_ENV is often treated as if it automatically solves dependency installation behavior, but it is better to make build intent explicit.
This is clearer than hoping the right NODE_ENV side effect will produce the dependency tree you want. Explicit install commands are easier to audit and less surprising across environments.
Common Pitfalls
The most common mistake is setting NODE_ENV only at build time and expecting a later runtime container to inherit dynamic behavior automatically. Another is assuming a host shell variable is passed into the container without an explicit -e flag or Compose configuration.
Teams also often mix build defaults, Dockerfile ENV, Compose overrides, and ad hoc command-line overrides without documenting which one is authoritative.
Finally, NODE_ENV is not a secret. It describes environment mode, not sensitive configuration. Database passwords and tokens belong in dedicated secret or environment mechanisms, not overloaded into this variable.
Summary
- Use runtime environment variables when
NODE_ENVcontrols how package scripts run inside the container. - Use Dockerfile
ENVonly for sensible defaults. - Use
ARGonly for build-time needs unless you intentionally copy it intoENV. - Prefer Compose or orchestrator config for repeatable team setups.
- Keep dependency-install rules explicit instead of relying on
NODE_ENVside effects alone.
Related reading
- Permission denied on accessing host directory in Docker
- Pod in Kubernetes always in pending state
- Pod status as CreateContainerConfigError in Minikube cluster
- Pods stuck in PodInitializing state indefinitely
- Pods stuck in Terminating status
- Pre pulling docker images in AMI to reduce node and pod fresh start time slows down it's execution when using nvidia-docker with GPU enabled pods
- Pre pulling docker images in AMI to reduce node and pod fresh start time slows down it's execution when using nvidia-docker with GPU enabled pods
- Prevent Kubernetes users from being able to create privileged containers

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.