18 Prompts for Docker: From Dockerfile to Multi-Stage Builds

Introduction

Docker has transformed software delivery, but its power comes with complexity. Crafting efficient Dockerfiles, orchestrating services with Compose, and shrinking image sizes require precision and best practices. This article provides 18 actionable prompts — ready-to-use templates and commands — that solve real-world Docker challenges. Whether you’re a beginner or a seasoned DevOps engineer, these prompts will help you build smaller, faster, and more secure containers.

Each prompt includes a task, the exact prompt or snippet, and an example result. I’ve sourced recommendations from the official Docker documentation (docs.docker.com) and the Dockerfile best practices guide (docs.docker.com/develop/develop-images/dockerfile_best-practices).

Basic Prompts: Getting Started with Dockerfiles

1. Create a Minimal Dockerfile for a Node.js App

Task: Write a Dockerfile for a simple Express server.
Prompt:

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

Example Result: The resulting image is ~150 MB (vs. ~900 MB for full Node). Uses npm ci for deterministic builds and alpine to reduce size.

2. Set a Non-Root User for Security

Task: Avoid running containers as root.
Prompt:

FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

Example Result: The container runs with minimal privileges, reducing attack surface. Docker’s security best practices (docs.docker.com/engine/security) recommend this for production.

3. Use .dockerignore to Exclude Unnecessary Files

Task: Prevent node_modules and logs from being copied.
Prompt:

node_modules
npm-debug.log
.git
.env

Example Result: Build context shrinks from 200 MB to 50 KB, speeding up image transfer and reducing cache invalidation.

4. Multi-Stage Build for a Go Binary

Task: Build a tiny Go binary with zero dependencies.
Prompt:

FROM golang:1.21 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server .

FROM scratch
COPY --from=builder /app/server /
CMD ["/server"]

Example Result: Final image is ~10 MB. The scratch base has no shell or libraries, minimizing vulnerabilities. This aligns with Docker’s multi-stage docs (docs.docker.com/build/building/multi-stage).

5. Cache Apt Packages with Layer Ordering

Task: Speed up builds by caching apt-get install layers.
Prompt:

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

Example Result: If curl is added later, the cached layer remains usable until the package list changes. The rm command reduces image size by ~30 MB.

6. Use Healthcheck in Dockerfile

Task: Make Docker restart unhealthy containers automatically.
Prompt:

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

Example Result: Docker Engine marks the container as unhealthy if the endpoint fails, triggering restarts in orchestration tools like Docker Swarm.

Advanced Prompts: Docker Compose & Networking

7. Define a Multi-Service Compose File

Task: Run a web app with PostgreSQL.
Prompt:

version: "3.9"
services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 5s

Example Result: docker compose up starts both services; web waits for a healthy database. The healthcheck prevents race conditions.

8. Use Named Volumes for Persistent Data

Task: Keep database data after container restart.
Prompt:

services:
  db:
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:

Example Result: Data survives docker compose down. Named volumes are managed by Docker and can be backed up easily.

9. Limit Container Resources

Task: Prevent a container from consuming all CPU/RAM.
Prompt:

services:
  app:
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 256M

Example Result: The container is capped at 0.5 CPU cores and 512 MB RAM. In swarm mode, this ensures fair resource distribution.

10. Use Profiles to Start Selective Services

Task: Run only the database during development.
Prompt:

services:
  db:
    profiles: ["dev", "prod"]
  web:
    profiles: ["prod"]

Example Result: docker compose --profile dev up starts only db, avoiding unnecessary builds.

11. Custom Network for Service Isolation

Task: Separate frontend and backend traffic.
Prompt:

services:
  frontend:
    networks:
      - front
  backend:
    networks:
      - back
networks:
  front:
  back:

Example Result: frontend cannot reach the database directly, enforcing security boundaries.

12. Use Secrets in Compose (Swarm)

Task: Pass passwords without hardcoding.
Prompt:

services:
  web:
    secrets:
      - db_password
secrets:
  db_password:
    file: ./secrets/db_password.txt

Example Result: The secret is mounted as a file at /run/secrets/db_password inside the container, never exposed in the image.

Expert Prompts: Optimization & Debugging

13. Squash Image Layers for Smaller Size

Task: Merge all layers into one.
Prompt:

docker build --squash -t myapp:latest .

Example Result: Reduces image size by eliminating intermediate files (e.g., build artifacts). Note: --squash is experimental in Docker 24+; verify with docker build --help.

14. Use BuildKit for Parallel Layers

Task: Speed up builds with concurrent execution.
Prompt:

export DOCKER_BUILDKIT=1
docker build --progress=plain -t myapp .

Example Result: BuildKit runs independent layers in parallel, cutting build time by up to 40% (based on Docker Inc. benchmarks).

15. Analyze Image Layers with docker history

Task: Find which layer bloats the image.
Prompt:

docker history --no-trunc myapp:latest

Example Result: Shows each layer’s size and command. For example, you may discover that apt-get install left 200 MB of cached packages.

16. Use dive for Visual Layer Inspection

Task: Interactively explore layer content.
Prompt:

dive myapp:latest

Example Result: The tool shows wasted space (e.g., duplicated files). It’s maintained by Alex Goodman (github.com/wagoodman/dive).

17. Pin Base Image Digests for Reproducibility

Task: Avoid unexpected tag updates.
Prompt:

FROM node:18-alpine@sha256:abc123...

Example Result: The build always uses the exact same image, even if node:18-alpine is updated. Get the digest via docker pull node:18-alpine && docker images --digests.

18. Use docker scout for Vulnerability Scanning

Task: Check images for known CVEs.
Prompt:

docker scout quickview myapp:latest

Example Result: Lists vulnerabilities by severity. Docker Scout, integrated in Docker Desktop 4.12+, uses the CVE database from Snyk and NVD.

Conclusion

These 18 prompts cover the entire Docker lifecycle — from writing secure Dockerfiles to optimizing production images. Start with the basic templates to standardize your builds, then adopt multi-stage builds and layer analysis to shrink images. Finally, use scanning and digests for production-grade security.

Try one prompt today: review your current Dockerfile and apply the non-root user change. Your containers will be safer immediately. For deeper learning, consult the official Dockerfile reference (docs.docker.com/engine/reference/builder).

← All posts

Comments