HxHippy

Dockerfile Basics

Writing Dockerfiles to build custom images.

Last updated: 2025-01-15

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 scratch

RUN - 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 copies

WORKDIR - Working Directory

WORKDIR /app
# All subsequent commands run from /app

WORKDIR /app/src
# Relative paths work too

ENV - Environment Variables

# Single variable
ENV NODE_ENV=production

# Multiple variables
ENV NODE_ENV=production \
    PORT=3000 \
    LOG_LEVEL=info

EXPOSE - Document Ports

# Document which ports the container uses
EXPOSE 80
EXPOSE 443
EXPOSE 3000/tcp
EXPOSE 3001/udp

CMD 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 3000

Complete 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 .
beginner Dockerfile Updated 2025-01-15
  • dockerfile
  • build
  • from
  • run
  • copy
  • cmd