14 Prompts for Docker: From Dockerfile to Multi-Stage Optimization

14 Prompts for Docker: From Dockerfile to Multi-Stage Optimization

Docker has become the de facto standard for containerization, but writing efficient Dockerfiles, orchestrating services with Compose, and trimming image sizes often requires more than just basic knowledge. Whether you're a DevOps engineer or a developer new to containers, the right prompt can save hours of trial and error. This collection provides copy-paste ready prompts that cover Dockerfile best practices, multi-stage builds, Compose configuration, debugging, and security hardening. Each prompt includes a clear explanation, a concrete example, and a usage scenario.

1. Crafting an Optimized Dockerfile for a Python App

Purpose: Generate a lean, production-ready Dockerfile for a Python application using best practices like layer caching, minimal base images, and non-root users.

Prompt:

Create a Dockerfile for a Python Flask application that:
- Uses python:3.11-slim as the base image
- Installs dependencies from requirements.txt
- Creates a non-root user 'appuser'
- Copies only necessary files (use .dockerignore)
- Exposes port 5000
- Runs the app with gunicorn
- Uses multi-stage build to reduce final image size

Example output:

FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

FROM python:3.11-slim
RUN useradd -m appuser
WORKDIR /home/appuser
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY app.py .
USER appuser
EXPOSE 5000
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]

Usage: Ideal for deploying Python microservices. The multi-stage approach keeps the final image under 200 MB.

2. Reducing Image Size with Multi-Stage Builds

Purpose: Explicitly separate build-time dependencies from runtime dependencies to shrink image size.

Prompt:

Write a multi-stage Dockerfile for a Go application that:
- Stage 1: Uses golang:1.21-alpine to compile the binary
- Stage 2: Uses alpine:3.18 as the runtime image
- Copies only the compiled binary
- Sets the binary as the entrypoint

Example output:

FROM golang:1.21-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app -ldflags="-s -w" .

FROM alpine:3.18
RUN apk add --no-cache ca-certificates
COPY --from=builder /app /app
CMD ["/app"]

Usage: The final image is ~10 MB instead of 300 MB. Use for statically compiled languages (Go, Rust, C).

3. Debugging a Container with Docker Compose Overrides

Purpose: Create a development override that mounts volumes and keeps the container alive for debugging.

Prompt:

Create a docker-compose.override.yml that:
- Mounts the current directory to /app
- Overrides the command to 'tail -f /dev/null'
- Sets environment variable DEBUG=1
- Opens port 9229 for Node.js inspector

Example output:

version: '3.8'
services:
  app:
    volumes:
      - .:/app
    command: tail -f /dev/null
    environment:
      - DEBUG=1
    ports:
      - "9229:9229"

Usage: Run docker compose up -d then docker compose exec app bash to interact with the container.

4. Writing a Docker Compose File for a Full-Stack App

Purpose: Define a multi-service setup with a frontend, backend, and database, including health checks and networks.

Prompt:

Write a docker-compose.yml for a web app with:
- React frontend (nginx)
- Node.js API backend
- PostgreSQL database
- A shared network 'appnet'
- Health checks on the API and database
- Volume for DB persistence

Example output:

version: '3.8'
services:
  db:
    image: postgres:15-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
    networks:
      - appnet
  api:
    build: ./api
    depends_on:
      db:
        condition: service_healthy
    networks:
      - appnet
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - api
    networks:
      - appnet
volumes:
  pgdata:
networks:
  appnet:

Usage: A robust starting point for local development. Health checks prevent the frontend from starting before the API is ready.

5. Optimizing Layer Caching in Dockerfile

Purpose: Arrange COPY and RUN instructions to maximize Docker's build cache.

Prompt:

Refactor this Dockerfile to improve layer caching:
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build

Example output:

FROM node:18
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

Usage: The dependency layer only rebuilds when package.json changes, cutting build times by up to 70% in CI/CD pipelines.

6. Using Docker BuildKit for Faster Builds

Purpose: Enable BuildKit features like secret mounts and cache mounts.

Prompt:

Write a Dockerfile that uses BuildKit secrets to pass an npm token securely:
- Use --mount=type=secret for the token
- Use --mount=type=cache for npm cache
- Build with DOCKER_BUILDKIT=1

Example output:

# syntax=docker/dockerfile:1
FROM node:18
WORKDIR /app
COPY package.json .
RUN --mount=type=cache,target=/root/.npm \
    --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) \
    npm install
COPY . .

Build command: DOCKER_BUILDKIT=1 docker build --secret id=npm_token,src=.npm_token .

Usage: Keeps credentials out of the final image and speeds up repeated installs.

7. Health Checks in Docker Compose

Purpose: Define custom health checks to ensure service readiness.

Prompt:

Add a health check to a Docker Compose service that:
- Pings an HTTP endpoint every 5 seconds
- Retries 3 times before marking unhealthy
- Uses curl inside the container

Example output:

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

Usage: Prevents traffic routing to unhealthy containers in orchestration tools.

8. Environment-Specific Compose Files

Purpose: Use multiple Compose files to manage dev, staging, and production environments.

Prompt:

Create a base compose file and an override for production that:
- Sets environment variables via .env.prod
- Uses different port mappings
- Adds a reverse proxy (Traefik)

Example base (docker-compose.yml):

version: '3.8'
services:
  app:
    image: myapp:latest
    env_file: .env

Example override (docker-compose.prod.yml):

services:
  app:
    ports:
      - "80:3000"
    env_file: .env.prod
  proxy:
    image: traefik:v2.10
    command: --providers.docker
    ports:
      - "443:443"

Usage: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

9. Debugging Container Networking

Purpose: Inspect inter-container connectivity and DNS resolution.

Prompt:

Run a temporary container on the same network to debug:
- Use alpine with curl, ping, and dig
- Attach to the service's network
- Test connection to another service by name

Example command:

docker run --rm -it --network myapp_appnet alpine ash -c "apk add bind-tools curl; curl http://api:3000/health; dig db"

Usage: Quickly diagnose DNS or firewall issues without modifying the service image.

10. Security Scanning with Docker Scout

Purpose: Use Docker Scout to scan images for vulnerabilities and generate a report.

Prompt:

Scan the local image 'myapp:latest' for vulnerabilities using Docker Scout:
- Output a summary table
- Filter by critical and high severity
- Suggest fixes for the top 3 findings

Example command:

docker scout quickview myapp:latest
docker scout recommendations myapp:latest --only-cve-fix-available --severity critical,high

Usage: Integrate into CI to block builds with critical vulnerabilities. Docker Scout is free for public images.

11. Building a Minimal nginx Image

Purpose: Create a custom nginx image that serves a static site, with minimal size.

Prompt:

Write a Dockerfile that:
- Uses nginx:alpine
- Copies a custom nginx.conf
- Copies static HTML files
- Changes the default server to /usr/share/nginx/html
- Runs nginx as non-root

Example output:

FROM nginx:alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY static/ /usr/share/nginx/html
RUN chown -R 1001:0 /usr/share/nginx/html && chmod -R g+r /usr/share/nginx/html
USER 1001
EXPOSE 8080

Usage: The image is ~22 MB and runs without privileges.

12. Automating Cleanup of Unused Docker Objects

Purpose: Write a script to prune unused containers, images, and volumes.

Prompt:

Create a daily cron job script that:
- Removes all stopped containers older than 24 hours
- Deletes dangling images (none:<none>)
- Keeps volumes in use by any container
- Logs the results to /var/log/docker-prune.log

Example script:

#!/bin/bash
docker container prune -f --filter "until=24h" >> /var/log/docker-prune.log 2>&1
docker image prune -f >> /var/log/docker-prune.log 2>&1
docker volume prune -f >> /var/log/docker-prune.log 2>&1
echo "Prune completed at $(date)" >> /var/log/docker-prune.log

Usage: Prevents disk exhaustion on CI runners or development machines.

13. Converting a Docker Run Command to Compose

Purpose: Translate a complex docker run command into a Compose service definition.

Prompt:

Convert this docker run command to a docker-compose service:
docker run -d --name myapp -p 8080:3000 -e DB_HOST=db.mysite.com -v /data:/app/data --restart unless-stopped myapp:1.0

Example output:

services:
  myapp:
    image: myapp:1.0
    container_name: myapp
    ports:
      - "8080:3000"
    environment:
      - DB_HOST=db.mysite.com
    volumes:
      - /data:/app/data
    restart: unless-stopped

Usage: Makes complex setups reproducible and version-controlled.

14. Using Docker Compose Profiles for Selective Services

Purpose: Define profiles to start only certain services (e.g., only database for testing).

Prompt:

Add profiles to a docker-compose.yml so that:
- Services 'api' and 'frontend' belong to profile 'full'
- Service 'db' belongs to profile 'core'
- Running without --profile starts only 'db'

Example output:

services:
  db:
    image: postgres:15
  api:
    image: myapi
    profiles: ["full"]
  frontend:
    image: myfrontend
    profiles: ["full"]

Usage: docker compose up starts only the DB; docker compose --profile full up starts everything.

Conclusion

These 14 prompts cover the most common Docker scenarios: writing efficient Dockerfiles, orchestrating services with Compose, debugging, security, and automation. By using these ready-to-use prompts, you can accelerate your workflow, reduce image sizes, and avoid common pitfalls. Start by applying the multi-stage build prompt to your current project, then move on to health checks and profiles. The official Docker documentation (docs.docker.com) remains your best reference for deeper dives. Try one prompt today and see the difference in your build times and container behavior.

← All posts

Comments