Parameterized Dockerfiles
This article refers to Platform v3.1.0. The current Platform version is v3.2.0.
Overview
A reusable Dockerfile is parameterised — it accepts values from the outside so that the same recipe can produce images for development, staging, and production. Docker provides two mechanisms:
ARG— build-time parameters set duringdocker build(overridable with--build-arg).ENV— runtime environment variables baked into the image (overridable with-eondocker run).
This article shows when to use each, then walks through a small Node.js example.
Watch this step on YouTube: Parametrized Dockerfiles.
Build-time vs runtime parameters
Build-time — ARG
Set values that influence the image being built but are not part of the running container's environment.
Typical uses:
- Picking the base image version.
- Compile-time switches (
DEBUG=1,WITH_FEATURE=true). - Build-only secrets that should not be embedded in the final image.
ARG NODE_VERSION=14
FROM node:${NODE_VERSION}
Runtime — ENV
Set environment variables that are present inside the running container. The application reads them at runtime via process.env, os.getenv(), etc.
Typical uses:
- Switching the app between development and production modes.
- Pointing the app at a different upstream URL per deployment.
ENV APP_ENV=production
Overriding parameters from the CLI
Override ARG at build time
docker build -t parameterized-app:1.0 --build-arg NODE_VERSION=16 .
NODE_VERSION is set to 16 for this build, overriding the default 14 in the Dockerfile.
Override ENV at run time
docker run -p 8080:8080 -e APP_MODE=development parameterized-app:1.0
APP_MODE is set to development, overriding the default production baked into the image.
Practice — parameterised Node.js app
1. Create the project
mkdir 03_01_parameterized-dockerfile
cd 03_01_parameterized-dockerfile
2. Application files
app.js:
const http = require('http');
const appMode = process.env.APP_MODE || 'development';
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Application is running in ${appMode} mode!\n`);
});
server.listen(8080, () => {
console.log(`Server running on http://localhost:8080 in ${appMode} mode.`);
});
package.json:
{
"name": "parameterized-dockerfile",
"version": "1.0.0",
"main": "app.js",
"dependencies": {
"http": "^0.0.1-security"
}
}
3. Dockerfile
# Build-time argument for Node.js version
ARG NODE_VERSION=14
# Base image (parametrised)
FROM node:${NODE_VERSION}
# Working directory
WORKDIR /app
# Application files
COPY package*.json .
COPY app.js .
# Install dependencies
RUN npm install
# Runtime environment variable
ENV APP_MODE=production
# Port
EXPOSE 8080
# Default command
CMD ["node", "app.js"]
4. Build and run
Build the image with a custom Node version:
docker build -t parameterized-app:1.0 --build-arg NODE_VERSION=16 .
Run the container in development mode:
docker run -p 8080:8080 -e APP_MODE=development parameterized-app:1.0
5. Verify
curl http://localhost:8080
Expected output:
Application is running in development mode!
Summary
ARG for build-time parameters, ENV for runtime parameters — combined, they let one Dockerfile target many environments. Use --build-arg to pick a base image version or compile flag, and -e (or the environment: block in Compose) to point the running app at the right environment.