ENV sets variables that exist during the build and in every container. ARG declares a build argument, set with docker build --build-arg NAME=value, which exists only during the build. BookNest combines them: ARG NODE_ENV=production accepts an override at build time, and ENV NODE_ENV=${NODE_ENV} bakes the result into the image (Express 24,430 caches views and hides stack traces when it is production). docker run -e overrides both:
docker build -q --build-arg NODE_ENV=development -t l3-booknest-api:dev . >/dev/null
docker run --rm l3-booknest-api:dev printenv NODE_ENV
docker run --rm -e NODE_ENV=test l3-booknest-api:1.0 printenv NODE_ENV PORT
docker rmi -f l3-booknest-api:dev >/dev/nulldevelopment test 3000
ARG is not safe for secrets: when a RUN step uses an argument, its value is recorded in the image history, where docker history --no-trunc shows RUN |1 NODE_ENV=production /bin/sh -c npm 2,036 ci ... here; use a secret mount for credentials (Secret Mounts). The PG* database settings are deliberately absent: each environment supplies its own at run time, so one image serves a laptop, Jenkins 8,793 and Kubernetes 5,150 .