10 Docker Prompts for Cleaner Dockerfiles, Smarter Compose Files, and Optimized Images

Why Docker Prompts Matter More Than You Think

If you've ever stared at a Dockerfile that builds for 15 minutes or a docker-compose.yml that refuses to start because of a forgotten volume, you know the pain. Docker is a powerful tool, but its configuration files are notoriously easy to get wrong. One misplaced layer can double your image size, and one missing depends_on can take down a multi-service application.

In this article, I’m sharing a collection of 10 Docker prompts — reusable templates and mental models — that will help you write cleaner Dockerfiles, design more reliable Compose stacks, and optimize your container images for production. These aren't one-off tricks; they are patterns I've refined across dozens of production deployments. Each prompt comes with a concrete example, so you can copy, adapt, and apply them immediately.

1. The Minimalist Dockerfile Prompt

Task: Write a Dockerfile that installs only production dependencies and runs as a non-root user.

Prompt:

FROM node:20-alpine AS base
WORKDIR /app

# Copy only package files first to leverage Docker cache
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# Copy application code
COPY . .

# Switch to non-root user
USER node

EXPOSE 3000

CMD ["node", "dist/server.js"]

Example result: This Dockerfile builds in under 5 seconds on a second run (thanks to layer caching), runs as node user instead of root, and produces an image of ~150 MB. The key insight: copying package.json before the rest of the code ensures npm install is cached unless dependencies change.

2. Multi-Stage Build Prompt

Task: Separate the build environment from the runtime environment using multi-stage builds.

Prompt:

# Stage 1: Build
FROM golang:1.22 AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app ./cmd/server

# Stage 2: Runtime
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata
COPY --from=builder /app /app
EXPOSE 8080
CMD ["/app"]

Example result: The final image is just 12 MB (vs. ~900 MB if using the full Go image). This pattern is standard for compiled languages (Go, Rust, Java with JLink) and reduces attack surface by excluding compilers and package managers.

3. Docker Compose with Health Checks Prompt

Task: Define a multi-service Compose file where each service waits for others to be healthy.

Prompt:

version: "3.9"
services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

  api:
    build: .
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "3000:3000"

Example result: The API service starts only after PostgreSQL's health check passes. This eliminates race conditions during startup — a common source of "connection refused" errors in CI/CD pipelines. According to the official Docker documentation, health checks are available since Docker 1.12 and are now a best practice for any serious deployment.

4. The Layer Ordering Prompt

Task: Optimize Dockerfile layer ordering to maximize cache reuse.

Prompt:

FROM python:3.12-slim

# 1. System dependencies (rarely change)
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc libpq-dev && rm -rf /var/lib/apt/lists/*

# 2. Python dependencies (change when requirements.txt changes)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 3. Application code (changes most often)
COPY . .

Example result: If you change only your application code, Docker reuses cached layers for system packages and Python packages. Build time drops from 3 minutes to 15 seconds for typical Python projects. This follows the principle: least frequently changed layers first.

5. Secrets Management in Compose Prompt

Task: Pass sensitive data (API keys, passwords) to containers without hardcoding them in the Compose file.

Prompt:

version: "3.9"
services:
  app:
    image: myapp:latest
    secrets:
      - db_password
      - api_key

secrets:
  db_password:
    file: ./secrets/db_password.txt
  api_key:
    file: ./secrets/api_key.txt

Example result: Secrets are mounted as files at /run/secrets/db_password inside the container, never exposed in environment variables or committed to version control. Docker Swarm and Kubernetes support similar file-based secrets. For production, use a vault solution like HashiCorp Vault, but for local development, file-based secrets are a solid start.

6. Resource Limits Prompt

Task: Prevent a single container from consuming all host resources.

Prompt:

services:
  worker:
    image: myworker:latest
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 256M
        reservations:
          cpus: '0.25'
          memory: 128M

Example result: The worker container is capped at 50% of one CPU core and 256 MB of RAM. If it tries to exceed, it gets throttled or OOM-killed instead of crashing the host. This is critical in shared environments like CI runners or multi-tenant servers. Docker's resource constraints are documented in the official Docker run reference.

7. .dockerignore Prompt

Task: Exclude unnecessary files from the Docker build context to speed up builds.

Prompt:

node_modules
.git
.env
*.log
.gitignore
Dockerfile
.dockerignore

Example result: A typical Node.js project without .dockerignore sends 50 MB of node_modules to the Docker daemon on every build. With this file, the context shrinks to under 1 MB. Builds start instantly, and the daemon doesn't waste CPU copying useless files.

8. Multi-Architecture Build Prompt

Task: Build images that run on both AMD64 and ARM64 (Apple Silicon, AWS Graviton).

Prompt:

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myapp:latest \
  --push .

Example result: A single command produces and pushes two architecture-specific images under the same tag. Docker automatically pulls the correct variant based on the host architecture. Buildx is available by default in Docker Desktop and Docker Engine 23.0+. This eliminates the need for separate Dockerfiles per architecture.

9. Logging and Debugging Prompt

Task: Capture container logs with timestamps and rotate them to prevent disk exhaustion.

Prompt:

services:
  app:
    image: myapp:latest
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Example result: Logs are capped at three files of 10 MB each (30 MB total). Docker's default logging driver can fill a disk with verbose logs in hours. This prompt ensures logs are available for debugging but never consume more than a defined limit. For centralized logging, consider switching to the fluentd or gelf driver.

10. The Cleanup Prompt

Task: Remove unused Docker resources (containers, images, volumes, networks) in one command.

Prompt:

docker system prune -a --volumes

Example result: On a development machine that builds many images, this can free 10–50 GB of disk space. The -a flag removes all unused images (not just dangling ones), and --volumes removes anonymous volumes. Use this weekly in CI or on local dev machines to avoid "no space left on device" errors.

Conclusion

These 10 prompts represent the difference between a Docker setup that works and one that works well. The multi-stage build prompt alone can shrink images by 90%. The health check prompt eliminates startup race conditions. The resource limits prompt protects your host from runaway containers.

Start with one or two prompts that solve your current problem. For a greenfield project, use the multi-stage build and Compose health check prompts from day one. As your infrastructure grows, layer in secrets management and multi-architecture builds.

Docker's official documentation at docs.docker.com is excellent, but these prompts capture the practical patterns that documentation assumes you already know. Apply them, and your containers will be leaner, more reliable, and easier to debug.

← All posts

Comments