Files
2025-11-30 08:47:38 +08:00

3.8 KiB

Dockerfile Reference

Basic Structure

# Base image
FROM ubuntu:22.04

# Metadata
LABEL maintainer="team@example.com"
LABEL version="1.0"

# Environment
ENV APP_HOME=/app
WORKDIR $APP_HOME

# Install dependencies
RUN apt-get update && apt-get install -y \
    package1 \
    package2 \
    && rm -rf /var/lib/apt/lists/*

# Copy files
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

# Non-root user
RUN useradd -r -s /bin/false appuser
USER appuser

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:8080/health || exit 1

# Entry point
ENTRYPOINT ["python"]
CMD ["app.py"]

Multi-Stage Builds

Reduce final image size by separating build and runtime:

# Build stage
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# Runtime stage
FROM alpine:3.18
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]

Common Base Images

Image Size Use Case
alpine ~5MB Minimal, production
debian:slim ~80MB Compatibility
ubuntu ~75MB Development
distroless ~20MB Security-focused
scratch 0MB Static binaries only

Instructions Reference

FROM

FROM image:tag
FROM image:tag AS builder
FROM --platform=linux/amd64 image:tag

RUN

# Shell form
RUN apt-get update && apt-get install -y package

# Exec form
RUN ["executable", "param1", "param2"]

COPY vs ADD

# COPY - preferred for local files
COPY ./src /app/src
COPY --chown=user:group files /app/

# ADD - can extract tars, fetch URLs (use sparingly)
ADD archive.tar.gz /app/

ENV vs ARG

# ARG - build-time only
ARG VERSION=1.0

# ENV - persists in image
ENV APP_VERSION=$VERSION

EXPOSE

EXPOSE 8080
EXPOSE 443/tcp
EXPOSE 53/udp

Documentation only - doesn't publish ports.

ENTRYPOINT vs CMD

# ENTRYPOINT - main executable
ENTRYPOINT ["python"]

# CMD - default arguments (can be overridden)
CMD ["app.py"]

# Combined: python app.py
# Override: docker run image other.py -> python other.py

USER

RUN useradd -r -s /bin/false appuser
USER appuser

HEALTHCHECK

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost/health || exit 1

Best Practices

Layer Caching

Order from least to most frequently changed:

# Rarely changes - cached
FROM node:18-alpine
WORKDIR /app

# Changes when deps change
COPY package*.json ./
RUN npm install

# Changes frequently - rebuild each time
COPY . .

Reduce Layers

Combine RUN commands:

# Bad - 3 layers
RUN apt-get update
RUN apt-get install -y package
RUN rm -rf /var/lib/apt/lists/*

# Good - 1 layer
RUN apt-get update && \
    apt-get install -y package && \
    rm -rf /var/lib/apt/lists/*

Security

# Use specific tags
FROM node:18.17.0-alpine  # Not :latest

# Non-root user
USER nobody

# Read-only filesystem
# (Set at runtime with --read-only)

# No secrets in image
# (Use build args or runtime secrets)

.dockerignore

.git
.gitignore
node_modules
*.log
.env
Dockerfile
docker-compose.yaml
README.md

Build Commands

# Basic build
docker build -t myimage:tag .

# With build args
docker build --build-arg VERSION=1.0 -t myimage .

# No cache
docker build --no-cache -t myimage .

# Specific Dockerfile
docker build -f Dockerfile.prod -t myimage .

# Multi-platform
docker buildx build --platform linux/amd64,linux/arm64 -t myimage .

Debugging Builds

# Build with progress output
docker build --progress=plain -t myimage .

# Inspect layers
docker history myimage

# Check image size
docker images myimage