If you're working with Docker, mastering Dockerfiles is essential! A Dockerfile is a script that defines how your Docker image is built. In this post, I'll break down essential Dockerfile instructions with examples, comparisons, and best practices. π₯
1οΈβ£ FROM β Define Base Image
Every Dockerfile must start with FROM
, which specifies the base image.
πΉ Example:
FROM node:18
π Best Practice: Use slim or alpine versions for smaller images:
FROM node:18-slim
β Reduces image size and improves security.
2οΈβ£ WORKDIR β Set Working Directory
Defines where the app runs inside the container.
πΉ Example:
WORKDIR /app
π Why use it?
βοΈ Avoids cd
commands.
βοΈ Keeps the directory structure clean.
3οΈβ£ COPY vs ADD β Copying Files
Both copy files into the container, but ADD can also extract archives.
Instruction | Function | Extracts .tar.gz ? |
Supports URLs? |
---|---|---|---|
COPY | Copies files/folders | β No | β No |
ADD | Copies + extracts files | β Yes | β Yes |
πΉ Example:
COPY package.json .
ADD my-archive.tar.gz /data/
β
Best Practice: Use COPY
unless you need extraction.
4οΈβ£ RUN β Execute Commands During Build
Used to install dependencies or configure the container.
πΉ Example:
RUN apt-get update && apt-get install -y curl
β
Best Practice: Use &&
to reduce layers.
5οΈβ£ CMD vs ENTRYPOINT β Whatβs the Difference?
These define how the container starts, but they work differently.
Instruction | Purpose | Can Be Overridden? |
---|---|---|
CMD | Default command | β Yes |
ENTRYPOINT | Fixed command | β No |
πΉ CMD Example:
CMD ["node", "app.js"]
πΉ ENTRYPOINT Example:
ENTRYPOINT ["java", "-jar", "app.jar"]
β
Use CMD if users might override the command.
β
Use ENTRYPOINT for fixed commands like Docker CLI tools.
6οΈβ£ EXPOSE β Define Port
Tells Docker which port the app will use.
πΉ Example:
EXPOSE 3000
π Note: EXPOSE does not actually open the port! You still need -p
when running the container.
docker run -p 3000:3000 my-app
7οΈβ£ ENV β Set Environment Variables
Used to define configuration variables.
πΉ Example:
ENV NODE_ENV=production
π Best Practice: Use .env
files for secrets instead of hardcoding values.
8οΈβ£ VOLUME β Persistent Storage
Ensures data is not lost when the container stops.
πΉ Example:
VOLUME /data
β Useful for: Databases, logs, and file storage.
9οΈβ£ ARG vs ENV β Build vs Runtime Variables
Instruction | Purpose | Available at Runtime? |
---|---|---|
ARG | Temporary build-time variable | β No |
ENV | Runtime configuration | β Yes |
πΉ Example:
ARG BUILD_VERSION=1.0
ENV APP_ENV=production
β
Use ARG for build-time secrets.
β
Use ENV for runtime configs.
π₯ Optimized Dockerfile Example
FROM node:18-slim
WORKDIR /app
COPY package.json .
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
β Best Practices Applied:
- Uses a slim base image.
- Sets a working directory.
-
Minimizes layers in
RUN
. - Avoids unnecessary files.
- Uses CMD for flexibility.
π Summary
Instruction | Purpose |
---|---|
FROM | Defines the base image |
WORKDIR | Sets working directory |
COPY vs ADD | Copies files (ADD also extracts) |
RUN | Executes build commands |
CMD vs ENTRYPOINT | Defines how the container runs |
EXPOSE | Declares port usage |
ENV | Sets environment variables |
ARG | Temporary build-time variables |
VOLUME | Persistent storage |
π‘ Final Tip
Always use multi-stage builds and minimize image size for better performance!
Did you find this guide helpful? Drop a comment below! π
Top comments (0)