Writing Dockerfiles: File Instructions & Variables
The Moving Day Analogy 📦
Imagine you’re moving to a new apartment. Your Dockerfile is like a moving instruction list for your movers. You need to tell them:
- Where to put things (WORKDIR)
- What to copy (COPY)
- What special items need unpacking (ADD)
- Settings for the new home (ENV)
- Temporary notes just for moving day (ARG)
Let’s learn how to write these instructions!
1. COPY Instruction - The Basic Mover
What is COPY?
COPY is like telling your movers: “Take this box and put it exactly there.”
It copies files from your computer into the Docker container.
Simple Example:
COPY app.js /myapp/
This says: “Copy the file app.js into the /myapp/ folder inside the container.”
COPY Syntax
COPY <source> <destination>
- source = file on YOUR computer
- destination = where it goes INSIDE container
Multiple Files Example
# Copy one file
COPY index.html /website/
# Copy many files
COPY package.json package-lock.json /app/
# Copy entire folder
COPY ./src /app/src/
Real Life Example
Think of it like this:
- You have a toy on your desk
- You tell mom: “Put my toy in the blue box”
- Mom copies (not moves!) the toy to the box
- Now the toy exists in BOTH places!
2. ADD Instruction - The Smart Mover
What is ADD?
ADD is like COPY but with superpowers! 🦸
It can:
- Copy files (just like COPY)
- Download files from the internet
- Unpack compressed files automatically
Simple Example:
ADD myapp.tar.gz /app/
This downloads OR copies AND unpacks the tar file!
ADD with URL
ADD https://example.com/file.txt /app/
This downloads the file directly into the container!
ADD Auto-Extracts Archives
# This .tar.gz file gets unpacked automatically!
ADD project.tar.gz /app/
If you use ADD with a .tar, .tar.gz, .tgz, or similar archive, Docker unpacks it for you.
Real Life Example
Imagine you order a gift online:
- ADD can go pick it up from the store (URL download)
- AND unwrap it for you (extract archives)
- COPY would just move a wrapped gift without unwrapping
3. COPY vs ADD - When to Use Which?
The Golden Rule
Use COPY unless you NEED ADD’s special powers
Quick Comparison
graph TD A[Need to copy files?] --> B{Do you need to...} B --> C[Just copy files?] B --> D[Download from URL?] B --> E[Auto-extract archives?] C --> F[âś… Use COPY] D --> G[âś… Use ADD] E --> H[âś… Use ADD]
Side-by-Side Example
Using COPY (Recommended for simple copying):
COPY requirements.txt /app/
COPY ./src /app/src/
Using ADD (When you need superpowers):
# Download from internet
ADD https://example.com/data.json /app/
# Auto-extract archive
ADD project.tar.gz /app/
Why COPY is Usually Better
- Clearer - Everyone knows what COPY does
- Safer - No surprise extractions
- Best Practice - Docker recommends COPY
- Predictable - Does exactly one thing
4. WORKDIR Instruction - Setting Your Home Base
What is WORKDIR?
WORKDIR is like telling someone: “From now on, start everything from THIS room.”
It sets the working directory inside the container.
Simple Example:
WORKDIR /app
Now all future commands run from /app!
Why WORKDIR Matters
Without WORKDIR:
COPY app.js /myapp/app.js
RUN cd /myapp && node app.js
With WORKDIR (Much cleaner!):
WORKDIR /myapp
COPY app.js .
RUN node app.js
Multiple WORKDIR Commands
WORKDIR /app
# Now we're in /app
WORKDIR src
# Now we're in /app/src
WORKDIR /data
# Now we're in /data (absolute path)
Real Life Example
Think of it like a GPS:
- You set your home address once
- Now you can say “5 minutes from home”
- Instead of giving the full address every time!
5. ENV Instruction - Permanent Settings
What is ENV?
ENV creates environment variables that stay forever in your container.
Like putting a permanent sticky note on your fridge!
Simple Example:
ENV APP_NAME="MyAwesomeApp"
Now APP_NAME is available everywhere in the container.
ENV Syntax Options
# Method 1: With equals sign
ENV MY_VAR="hello"
# Method 2: Multiple variables
ENV NAME="Docker" VERSION="1.0"
# Method 3: Multi-line
ENV DB_HOST=localhost \
DB_PORT=5432 \
DB_NAME=mydb
Using ENV Variables
ENV APP_HOME=/app
WORKDIR $APP_HOME
COPY . $APP_HOME
The $APP_HOME gets replaced with /app!
Real Life Example
ENV is like your home thermostat setting:
- You set it once (ENV TEMP=72)
- It stays that way
- Everyone in the house feels it
- It doesn’t change until you change it
6. ARG Instruction - Build-Time Secrets
What is ARG?
ARG creates variables that only exist during building.
Like a temporary password that expires after moving day!
Simple Example:
ARG VERSION=1.0
Key Difference: ARG vs ENV
graph TD A[ARG] --> B[Only during build time] A --> C[Like a temporary note] D[ENV] --> E[Forever in container] D --> F[Like permanent settings]
Using ARG in Dockerfile
# Define the argument
ARG NODE_VERSION=18
# Use it in FROM
FROM node:${NODE_VERSION}
# ARG can have default values
ARG BUILD_TYPE=production
Passing ARG at Build Time
When building, you can override ARG values:
docker build --build-arg VERSION=2.0 .
Converting ARG to ENV
ARG disappears after build. To keep it:
ARG MY_VERSION=1.0
ENV VERSION=$MY_VERSION
Now VERSION stays in the running container!
Real Life Example
ARG is like a one-time delivery code:
- Delivery person uses code to drop off package
- Code stops working after delivery
- Package (container) doesn’t know the code existed
Complete Example: All Together!
Here’s a real Dockerfile using everything we learned:
# Build argument - can change at build time
ARG NODE_VERSION=18
# Use the argument
FROM node:${NODE_VERSION}-alpine
# Set permanent environment variables
ENV NODE_ENV=production \
APP_PORT=3000
# Create app directory
WORKDIR /app
# Copy package files first (for caching)
COPY package*.json ./
# Copy application code
COPY src/ ./src/
# If you need to download something
# ADD https://example.com/config.json ./
# Expose the port from ENV
EXPOSE $APP_PORT
# Start the app
CMD ["node", "src/index.js"]
Quick Summary
| Instruction | Purpose | Remembering Trick |
|---|---|---|
| COPY | Copy files into container | đź“‹ Simple copy machine |
| ADD | Copy + download + extract | 🦸 Copy with superpowers |
| WORKDIR | Set current directory | 🏠Set home base |
| ENV | Permanent variables | 📌 Sticky note forever |
| ARG | Build-time variables | ⏱️ Temporary password |
Key Takeaways
- Use COPY for copying files (simple and clear)
- Use ADD only when you need URL download or auto-extract
- Set WORKDIR early to make paths cleaner
- ENV variables live forever in the container
- ARG variables disappear after the build
You’re now ready to write powerful Dockerfiles! 🚀