Docker provides two powerful mechanisms for managing configuration values: ARG and ENV. While both serve distinct purposes, understanding their differences and best practices can significantly improve the flexibility and security of your containerized applications.
Understanding ARG vs. ENV
ARG: Build-Time Variables
- Available only inside the Dockerfile.
 - Not accessible in CMD or application code.
 - Set during image build using 
--build-arg. 
ENV: Runtime Variables
- Available inside the Dockerfile and application code.
 - Set via 
ENVin the Dockerfile or--envindocker run. - Can be overridden at runtime.
 
Using ENV for Dynamic Configuration
Consider a scenario where an application listens on a hardcoded port:
app.listen(80);
While this works, it’s not ideal for development. If the port needs to change, the image must be rebuilt. A better approach is to use an environment variable:
app.listen(process.env.PORT);
  
  
  Three Ways to Define PORT
1️⃣ Dockerfile
Define the default port inside the Dockerfile:
FROM node:18  
WORKDIR /app  
COPY package.json ./  
RUN npm install  
COPY . .  
ENV PORT=8000  
EXPOSE $PORT  
VOLUME [ "/app/feedback" ]  
CMD ["node", "server.js"]  
2️⃣ Docker Run Command
Override the default port at runtime:
docker run -p 3000:80 --env PORT=8000 feedback-node-app:volumes
3️⃣ Using a .env File
Create a .env file and define the port:
nano .env  
PORT=8000  
Run the container using the .env file:
docker run -p 3000:80 --env-file ./.env feedback-node-app:volumes
Important Note:
If a runtime environment variable is defined, it overwrites the default value set in the Dockerfile. Otherwise, the Dockerfile value is used.
Security Considerations for Environment Variables
Environment variables can store sensitive data such as credentials or API keys. However, if defined in the Dockerfile, they become baked into the image and can be retrieved using:
docker history <image>
Best Practice:
Instead of defining sensitive values in the Dockerfile, use a separate environment file and ensure it is excluded from version control.
Improving Configuration with ARG
Even with the above changes, the default port 80 is still hardcoded. To improve flexibility, use ARG:
FROM node:18  
WORKDIR /app  
COPY package.json ./  
RUN npm install  
COPY . .  
ARG DEFAULT_PORT=80  
ENV PORT=$DEFAULT_PORT  
EXPOSE $PORT  
VOLUME [ "/app/feedback" ]  
CMD ["node", "server.js"]  
  
  
  Defining DEFAULT_PORT at Build Time
docker build -t feedback-app --build-arg DEFAULT_PORT=8000 .
Optimizing Build Order
Place ARG DEFAULT_PORT=80 after dependency installation (RUN npm install). Changing an argument triggers a rebuild of subsequent instructions, so placing it earlier would force unnecessary reinstallation of dependencies.  
Final Thoughts
Using ARG and ENV effectively ensures a flexible, configurable, and secure Docker setup. While ARG is ideal for build-time configuration, ENV allows runtime flexibility. By following best practices, developers can optimize their workflows while maintaining security and efficiency.
              
    
Top comments (0)