Writing Dockerfiles: The Recipe for Success
A Dockerfile is a simple text file without an extension. It contains a top-to-bottom list of commands that Docker uses to assemble an image. Think of it as an Automated Installation Guide.
The "Cooking" Analogy
Building an image is like baking a cake:
- FROM: Get the base ingredients (The flour/base image).
- WORKDIR: Clear a space on the kitchen counter (Setting the directory).
- COPY: Put your specific ingredients on the counter (Your code).
- RUN: Mix and bake (Installing dependencies).
- CMD: Serve the cake (Starting the app).
Essential Dockerfile Instructions
Here are the 6 "Power Commands" you will use 90% of the time:
1. FROM (The Foundation)
Every Dockerfile must start with FROM. it tells Docker which base image to use.
- Example:
FROM node:18-alpine(A lightweight version of Node.js).
2. WORKDIR (The Folder)
Sets the working directory inside the container. It's like using cd in your terminal.
- Example:
WORKDIR /app
3. COPY (The Transfer)
Moves files from your Host machine (your laptop) into the Image.
- Example:
COPY . .(Copy everything from the current folder to the/appfolder).
4. RUN (The Build Step)
Executes commands during the build process. Used for installing software.
- Example:
RUN npm install
5. EXPOSE (The Documentation)
Tells Docker which port the container listens on at runtime.
- Example:
EXPOSE 3000
6. CMD (The Launch)
The final command that runs only when the container starts. There can only be one CMD per Dockerfile.
- Example:
CMD ["node", "index.js"]
A Real-World Example (Node.js App)
Here is a standard Dockerfile for a CodeHarborHub project:
# Step 1: Use an official Node.js runtime as a parent image
FROM node:18-alpine
# Step 2: Set the working directory in the container
WORKDIR /usr/src/app
# Step 3: Copy package files first (for better caching)
COPY package*.json ./
# Step 4: Install dependencies
RUN npm install
# Step 5: Copy the rest of your app's source code
COPY . .
# Step 6: Inform Docker the app runs on port 8080
EXPOSE 8080
# Step 7: Define the command to run your app
CMD ["npm", "start"]
The .dockerignore File
Just like .gitignore, we use a .dockerignore file to tell Docker which files NOT to copy into the image. This keeps your images small and secure.
Common entries:
node_modules(We install these fresh inside the container).git.env(Security risk!)Dockerfileitself
Understanding Layers & Caching
Each line in your Dockerfile creates a new Layer.
DevOps Trick: Docker caches layers. If you change your code but don't change your package.json, Docker will skip the npm install step and use the cached version, making your builds 10x faster!
Summary Checklist
- I know that
FROMis the mandatory first line. - I understand the difference between
RUN(build time) andCMD(run time). - I know that
WORKDIRis like a "cd" command inside the container. - I understand that a
.dockerignorefile keeps my image slim.
Always use the Alpine version of images (e.g., python:3.9-alpine) when possible. They are much smaller, meaning faster downloads and less storage used on your server!