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

Introduction

Docker has transformed how we develop, ship, and run applications. But even experienced developers often hit a wall when crafting efficient Dockerfiles or composing multi-service environments. The difference between a bloated 2 GB image and a lean 150 MB image often comes down to a handful of well-designed prompts — not just for Docker itself, but for the AI tools that assist in generating configuration files.

In this article, I’ll share a curated collection of prompts for Docker, organized by expertise level: basic, advanced, and expert. Each prompt includes the task, the exact prompt text, and a realistic example result. Whether you’re just starting with containers or optimizing production pipelines, these prompts will save you time and help you avoid common pitfalls.

Basic Prompts

1. Generate a Minimal Dockerfile for a Python App

Task: Create a simple, secure Dockerfile for a Python Flask application.

Prompt:

Write a Dockerfile for a Python Flask app that:
- Uses python:3.11-slim as base
- Copies only requirements.txt first for layer caching
- Installs dependencies with pip --no-cache-dir
- Creates a non-root user 'appuser'
- Exposes port 5000
- Runs the app with python app.py

Example Result:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

RUN addgroup --system appgroup && adduser --system --ingroup appgroup appuser
USER appuser

COPY . .

EXPOSE 5000

CMD ["python", "app.py"]

2. Basic docker-compose.yml for Web App + Database

Task: Write a docker-compose file with a web service and PostgreSQL.

Prompt:

Generate a docker-compose.yml that:
- Has a 'web' service built from a local Dockerfile
- Has a 'db' service using postgres:15-alpine
- Mounts a volume for PostgreSQL data persistence
- Sets environment variables for DB name, user, and password
- Uses a custom network

Example Result:

version: '3.8'

services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb

  db:
    image: postgres:15-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass

volumes:
  pgdata:

Advanced Prompts

3. Multi-Stage Build for a Go Application

Task: Optimize a Go binary build to produce the smallest possible image.

Prompt:

Create a multi-stage Dockerfile for a Go app:
- Build stage uses golang:1.22-alpine
- Copy go.mod and go.sum first, then run go mod download
- Build with CGO_ENABLED=0 and -ldflags="-s -w"
- Final stage uses scratch
- Copy only the compiled binary from build stage
- Use a distroless base if scratch is too minimal

Example Result:

# Build stage
FROM golang:1.22-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/server .

# Final stage
FROM gcr.io/distroless/static-debian12:nonroot

COPY --from=builder /app/server /server

EXPOSE 8080

ENTRYPOINT ["/server"]

4. Optimize Docker Image Size with .dockerignore

Task: Reduce image size by excluding unnecessary files.

Prompt:

Generate a .dockerignore file for a Node.js project that:
- Excludes node_modules (will be installed in container)
- Excludes .git, .env, *.md files
- Excludes test/ and __tests__/ directories
- Preserves package.json and package-lock.json

Example Result:

node_modules
.git
.env
*.md
test/
__tests__/
.gitignore
Dockerfile
.dockerignore

5. Docker Compose with Health Checks and Dependencies

Task: Ensure services start in the correct order with health checks.

Prompt:

Write a docker-compose.yml with three services:
- redis (image: redis:7-alpine) with a health check using redis-cli ping
- app (build: .) that depends on redis being healthy
- nginx (image: nginx:1.25-alpine) as reverse proxy, depends on app
Include a wait-for-it script or use depends_on condition

Example Result:

version: '3.8'

services:
  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

  app:
    build: .
    depends_on:
      redis:
        condition: service_healthy
    ports:
      - "3000:3000"

  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
    depends_on:
      - app
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro

Expert Prompts

6. Docker Secrets Management with Compose

Task: Avoid hardcoding secrets in docker-compose files.

Prompt:

Write a docker-compose.yml that uses Docker secrets:
- Define a secret 'db_password' from a file ./secrets/db_password.txt
- Mount it to the 'app' service at /run/secrets/db_password
- Also define a secret 'api_key' with an external: true (assuming it's pre-created)
- Set the secret file permissions to 0400

Example Result:

version: '3.8'

services:
  app:
    build: .
    secrets:
      - db_password
      - api_key
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

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

7. Multi-Stage Build with Caching and BuildKit

Task: Leverage BuildKit features for faster rebuilds.

Prompt:

Create a Dockerfile that uses BuildKit cache mounts:
- Use --mount=type=cache for pip packages (Python)
- Use --mount=type=bind for mounting source during build
- Set ARG BUILDKIT_INLINE_CACHE=1
- Demonstrate a multi-stage pattern where the test stage runs unit tests
- The final stage copies only production dependencies

Example Result:

# syntax=docker/dockerfile:1.4
FROM python:3.11-slim AS builder

WORKDIR /app

COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install --no-cache-dir -r requirements.txt

COPY . .

FROM builder AS tester
RUN python -m pytest tests/

FROM python:3.11-slim AS production

WORKDIR /app

COPY --from=builder /app /app

RUN --mount=type=cache,target=/root/.cache/pip \
    pip install --no-cache-dir -r requirements.txt --target /app

USER 1000

CMD ["python", "app.py"]

8. Docker Compose with Profiles for Dev/Prod

Task: Use Docker Compose profiles to switch between development and production configurations.

Prompt:

Write a docker-compose.yml that uses profiles:
- 'dev' profile: mount source code as volume, enable debug port, use Flask dev server
- 'prod' profile: use gunicorn, no volume mounts, add a separate nginx service
- Default profile: 'dev'
- Use environment variables in a .env file for DB credentials

Example Result:

version: '3.8'

services:
  app:
    build: .
    ports:
      - "${APP_PORT:-5000}:5000"
    environment:
      - FLASK_ENV=${FLASK_ENV:-development}
    profiles:
      - dev
    volumes:
      - .:/app

  app-prod:
    build: .
    command: gunicorn -w 4 -b 0.0.0.0:5000 app:app
    ports:
      - "5000:5000"
    profiles:
      - prod

  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
    profiles:
      - prod
    depends_on:
      - app-prod

9. Optimize Layer Caching with Dependency Sorting

Task: Minimize rebuild time by strategically ordering COPY commands.

Prompt:

Generate a Dockerfile for a Rails app that:
- Copies Gemfile and Gemfile.lock first
- Runs bundle install
- Copies the rest of the application
- Uses a multi-stage build to keep final image small
- Include a .dockerignore that excludes tmp/, log/, and vendor/bundle

Example Result:

FROM ruby:3.2-slim AS builder

WORKDIR /app

COPY Gemfile Gemfile.lock ./
RUN bundle install --deployment --without development test

COPY . .

FROM ruby:3.2-slim

WORKDIR /app

COPY --from=builder /app /app
COPY --from=builder /usr/local/bundle /usr/local/bundle

EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]

10. Security Hardening with Non-Root and Read-Only RootFS

Task: Implement security best practices in Docker Compose.

Prompt:

Write a docker-compose.yml that:
- Runs the app container as a non-root user (UID 1001)
- Sets read_only: true for the root filesystem
- Mounts a tmpfs volume at /tmp for writable temp files
- Adds a security_opt: no-new-privileges
- Limits memory and CPU resources

Example Result:

version: '3.8'

services:
  app:
    build: .
    user: "1001:1001"
    read_only: true
    tmpfs:
      - /tmp
    security_opt:
      - no-new-privileges
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'

Conclusion

Mastering Docker prompts — whether for generating Dockerfiles, composing services, or optimizing images — is a skill that pays off in faster builds, smaller images, and more secure deployments. Start with the basic prompts to get a feel for the syntax, then move to advanced patterns like multi-stage builds and caching. At the expert level, you can automate entire pipelines and enforce security policies.

The key takeaway: a well-crafted prompt is like a good Dockerfile — it does exactly what you need and nothing more. Use these examples as a foundation, and adapt them to your specific stack and workflows.

For developers looking to integrate API connectivity into their containerized applications, ASI Biont supports connecting to various services through its API-based platform — learn more at asibiont.com/courses.

← All posts

Comments