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

Introduction

Docker has revolutionized how we build, ship, and run applications. Yet many developers still write bloated Dockerfiles or struggle with Compose networking. This collection of 17 battle-tested prompts will help you craft efficient Dockerfiles, optimize images, and orchestrate containers like a pro. Each prompt includes a real-world example and explanation—no fluff, just practical value.

Core Dockerfile Prompts

1. Generate a Production-Ready Dockerfile

Prompt: "Write a multi-stage Dockerfile for a Node.js app that first builds with npm ci, then copies only production dependencies to a slim base image."

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Why it works: Multi-stage builds reduce final image size by discarding build tools. Alpine keeps the base under 5 MB.

2. Optimize Layer Caching

Prompt: "Restructure this Dockerfile to maximize layer caching: copy package files first, then run npm install, then copy source code."

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Why it works: Docker caches layers. By copying rarely-changed files first, rebuilds skip dependency installation unless requirements.txt changes.

3. Use .dockerignore to Exclude Unnecessary Files

Prompt: "Create a .dockerignore file that excludes node_modules, .git, and test files for a Node.js project."

node_modules
.git
.gitignore
tests/
*.md
.DS_Store

Why it works: Reduces build context size from ~200 MB to under 1 MB, speeding up builds and transfers.

4. Set Non-Root User for Security

Prompt: "Add a non-root user to the Dockerfile to run the application securely."

FROM node:18-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
WORKDIR /app
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Why it works: Running as root inside a container is a security risk. This follows the principle of least privilege.

Docker Compose Prompts

5. Create a Development Compose File with Hot Reload

Prompt: "Write a docker-compose.yml for a React app with a volume mount for hot reloading and a development server on port 3000."

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development

Why it works: Volumes sync local changes instantly; anonymous volume for node_modules prevents overwriting.

6. Define Dependencies Between Services

Prompt: "Extend the Compose file to include a PostgreSQL database and make the web service wait for it."

services:
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret
  web:
    build: .
    depends_on:
      - db
    ports:
      - "3000:3000"

Why it works: depends_on ensures startup order, though you still need a health check in code.

7. Use Health Checks for Reliable Orchestration

Prompt: "Add a health check to the web service that pings /health every 30 seconds."

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
  interval: 30s
  timeout: 10s
  retries: 3

Why it works: Docker restarts unhealthy containers automatically, improving uptime.

8. Set Resource Limits

Prompt: "Limit memory and CPU for each service in Compose."

services:
  web:
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

Why it works: Prevents a single container from starving the host, critical in production.

Image Optimization Prompts

9. Reduce Image Size with Distroless Base Images

Prompt: "Switch from ubuntu:latest to a distroless base for a Go application."

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

FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app/app /app
CMD ["/app"]

Why it works: Distroless images contain only runtime essentials—no shell, no package manager—reducing size by 90%.

10. Clean Up Package Manager Caches in Same Layer

Prompt: "Combine apt-get update and install with cache cleanup in one RUN command."

RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

Why it works: Each RUN creates a layer. Cleaning in the same layer prevents caching stale package lists.

11. Use COPY --chown Instead of RUN chown

Prompt: "Copy files and set ownership in one step."

COPY --chown=appuser:appgroup . /app

Why it works: Avoids an extra layer and reduces image size.

12. Squash Layers for Final Image

Prompt: "Add --squash to docker build command to merge all layers."

docker build --squash -t myapp:latest .

Why it works: Combines all layers into one, useful for images with many intermediate steps. Note: experimental feature.

Advanced Orchestration Prompts

13. Use BuildKit for Parallel Builds

Prompt: "Enable BuildKit and build with cache mounts."

export DOCKER_BUILDKIT=1
docker build --cache-from myapp:latest -t myapp:latest .

Why it works: BuildKit parallelizes stages, uses inline cache, and supports secrets without leaving traces.

14. Define Networks for Service Isolation

Prompt: "Create two networks in Compose: frontend and backend. Only backend can access the database."

networks:
  frontend:
  backend:
services:
  web:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend

Why it works: Isolates database from public access, improving security.

15. Use Environment Files for Configuration

Prompt: "Store environment variables in a .env file and reference in Compose."

DB_HOST=db
DB_PORT=5432
services:
  web:
    env_file: .env

Why it works: Keeps secrets out of Compose files and enables different configs per environment.

16. Implement Rolling Updates with Replicas

Prompt: "Run 3 replicas of the web service with rolling update strategy."

services:
  web:
    image: myapp:latest
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s

Why it works: Ensures zero-downtime deployments by updating one container at a time.

17. Debug with docker exec and Interactive Mode

Prompt: "Start a temporary container with interactive shell to debug network issues."

docker run -it --rm --network myapp_default alpine sh

Why it works: Alpine’s small size (5 MB) makes it perfect for debugging without polluting production images.

Conclusion

These 17 prompts cover the entire Docker workflow—from writing efficient Dockerfiles to orchestrating multi-service applications. Adopting multi-stage builds, distroless bases, and proper caching can shrink your images by 80-90% and speed up deployments. Start by picking one prompt that addresses your current pain point (e.g., image size or security) and integrate it into your next project. For deeper dives, consult the official Docker documentation and Best practices for writing Dockerfiles.

← All posts

Comments