Dockerfile Fundamentals
A Dockerfile is a text file with instructions for building a Docker image.
Basic Structure
# Comment
FROM base-image:tag
# Build-time instructions
RUN command
COPY source destination
WORKDIR /app
# Runtime configuration
ENV KEY=value
EXPOSE port
CMD ["executable", "param1"]Common Instructions
FROM - Base Image
# Official images
FROM ubuntu:22.04
FROM node:20-alpine
FROM python:3.12-slim
# Specific digest (immutable)
FROM nginx@sha256:abc123...
# Scratch (empty) image
FROM scratchRUN - Execute Commands
# Shell form
RUN apt-get update && apt-get install -y curl
# Exec form
RUN ["apt-get", "install", "-y", "curl"]
# Multi-line (combine to reduce layers)
RUN apt-get update && \
apt-get install -y \
curl \
wget \
vim && \
rm -rf /var/lib/apt/lists/*COPY and ADD
# Copy files
COPY package.json /app/
COPY src/ /app/src/
# Copy with ownership
COPY --chown=node:node . /app
# ADD can extract archives and fetch URLs
ADD app.tar.gz /app/
ADD https://example.com/file.txt /app/
# Prefer COPY over ADD for simple copiesWORKDIR - Working Directory
WORKDIR /app
# All subsequent commands run from /app
WORKDIR /app/src
# Relative paths work tooENV - Environment Variables
# Single variable
ENV NODE_ENV=production
# Multiple variables
ENV NODE_ENV=production \
PORT=3000 \
LOG_LEVEL=infoEXPOSE - Document Ports
# Document which ports the container uses
EXPOSE 80
EXPOSE 443
EXPOSE 3000/tcp
EXPOSE 3001/udpCMD vs ENTRYPOINT
# CMD - Default command (can be overridden)
CMD ["node", "server.js"]
CMD ["python", "app.py"]
# ENTRYPOINT - Main executable (append arguments)
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"] # Default args
# Combined: python app.py --port 8080
# Override: docker run myapp --port 3000Complete Examples
Node.js Application
FROM node:20-alpine
WORKDIR /app
# Install dependencies first (better caching)
COPY package*.json ./
RUN npm ci --only=production
# Copy application code
COPY . .
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "server.js"]Python Application
FROM python:3.12-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY . .
# Non-root user
RUN useradd --create-home appuser
USER appuser
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]Building Images
# Basic build
docker build -t myapp:1.0 .
# Build with different Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .
# Build with build arguments
docker build --build-arg VERSION=1.0 -t myapp .
# Build with no cache
docker build --no-cache -t myapp .
# Build for different platform
docker build --platform linux/amd64 -t myapp . - dockerfile
- build
- from
- run
- copy
- cmd