SyntaxStudy
Sign Up
Docker Core Dockerfile Instructions
Docker Beginner 1 min read

Core Dockerfile Instructions

A Dockerfile is a text file containing ordered instructions that Docker executes sequentially to build an image. Each instruction creates a new layer. The most fundamental instructions are: FROM (set base image), RUN (execute a command), COPY (copy files from build context), WORKDIR (set working directory), EXPOSE (document a port), ENV (set environment variable), CMD (default command), and ENTRYPOINT (fixed executable). CMD and ENTRYPOINT are often confused. ENTRYPOINT defines the executable that always runs; CMD provides default arguments that can be overridden at runtime with docker run image args. Using both together — ENTRYPOINT ["node"] and CMD ["server.js"] — is idiomatic: the executable is fixed but the script is replaceable. Always use the JSON (exec) form for both to avoid spawning a shell. RUN chains should be combined with && and broken across lines with backslash to minimise layer count. Each RUN creates a layer, so ten separate RUN apt-get install instructions are worse than one combined instruction. The final RUN in an apt installation block should include rm -rf /var/lib/apt/lists/* to remove the package manager cache from the layer.
Example
# Dockerfile for a Node.js application
FROM node:20-alpine AS base

# Set working directory (created if not exists)
WORKDIR /app

# Install OS deps in one layer, clean cache
RUN apk add --no-cache \
    dumb-init \
    curl

# Copy dependency manifests first (cache-friendly)
COPY package.json package-lock.json ./

# Install production dependencies only
RUN npm ci --omit=dev --ignore-scripts

# Copy application source
COPY src/ ./src/
COPY config/ ./config/

# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup \
    && chown -R appuser:appgroup /app

USER appuser

# Document the port (metadata only)
EXPOSE 3000

# Set default environment
ENV NODE_ENV=production PORT=3000

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

# Use dumb-init for proper signal handling
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "src/server.js"]