Dockerfile Snippets - CodeSwordsman

Copy-ready snippets from a minimal image to multi-stage builds, layer caching, non-root users and slim images.

Docker 23+ / BuildKitUpdated 2026-10-2924 commands

Minimal Image

A minimal runnable Node image skeleton

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Use the JSON array form for CMD so it skips the shell.

Pin a minor base image tag so builds stay reproducible

FROM node:20-alpine3.20

Add source metadata labels to trace the image

LABEL org.opencontainers.image.source="https://github.com/acme/my-app"

Document the listening port; it does not publish anything

EXPOSE 3000

Multi-stage Build

Multi-stage Go build that ships only the binary

FROM golang:1.22-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=build /out/app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]

Build the frontend, then serve it with Nginx

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:1.25-alpine
COPY --from=build /app/dist /usr/share/nginx/html

Static binaries can run from scratch for the smallest size

FROM scratch
COPY --from=build /out/app /app
ENTRYPOINT ["/app"]

scratch has no shell or CA certs; copy them if needed.

Layering & Cache

Copy manifests first so code edits reuse the dependency layer

COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .

Cache the package manager directory with BuildKit

RUN --mount=type=cache,target=/root/.npm \
    npm ci --omit=dev

Requires BuildKit, enabled by default since Docker 23.

Use .dockerignore to shrink context and keep secrets out

node_modules
dist
.git
.env
Dockerfile

Set ownership during copy to skip an extra chown layer

COPY --chown=node:node . .

User & Runtime

Create and switch to a non-root user for the process

RUN addgroup -S app && adduser -S app -G app
USER app

Ensure the working directory is writable before switching.

Declare a health check for orchestrators to poll

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
    CMD wget -qO- http://127.0.0.1:3000/health || exit 1

Slim images may lack curl; use wget or a bundled script.

Fix the entrypoint while letting CMD be overridden

ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["--config", "/etc/app/config.yaml"]

In exec form they concatenate; shell form ignores CMD.

Declare the stop signal for graceful shutdown

STOPSIGNAL SIGTERM

Build Args & Targets

Pass build-time variables; never use it for secrets

docker build --build-arg NODE_ENV=production -t my-app:1.0 .

ARG values stay in image history and show up in docker history.

Build only up to one stage to debug intermediate output

docker build --target build -t my-app:builder .

Build the image for a given architecture

docker build --platform linux/amd64 -t my-app:1.0 .

Cross-arch builds need buildx and can be slow locally.

Rebuild ignoring all cache to debug stale layers

docker build --no-cache -t my-app:1.0 .

Point to another Dockerfile; the last argument is the context

docker build -f docker/Dockerfile.prod -t my-app:1.0 .

Shrink the Image

Install and clean apt lists within a single layer

RUN apt-get update \
    && apt-get install -y --no-install-recommends curl ca-certificates \
    && rm -rf /var/lib/apt/lists/*

Install production dependencies and drop the npm cache

RUN npm ci --omit=dev && npm cache clean --force

Prefer alpine or slim images as the base

FROM node:20-slim

Use --no-cache on Alpine to skip manual index cleanup

RUN apk add --no-cache curl

Related tools

This website uses cookies to ensure you get the best experience on our website. Privacy Policy.