Secure Docker Configuration with AI Prompts

TL;DR

Docker containers share the host kernel, so security matters. Use non-root users, minimal base images, multi-stage builds, and never put secrets in images. Scan images for vulnerabilities and don't run containers with --privileged. These prompts cover essential container security.

Secure Dockerfile

Copy this prompt to have your AI review and harden your Dockerfile. You'll get a multi-stage build template with pinned base image versions, non-root user setup, minimal production image, health checks, and proper file ownership.

AI Prompt

Create Secure Dockerfile

Review and improve my Dockerfile for security.

Secure Dockerfile template:

Use specific version, not

FROM node:20-alpine AS builder

Set working directory

WORKDIR /app

Copy dependency files first (cache optimization)

COPY package*.json ./

Install dependencies

RUN npm ci --only=production

Copy application code

COPY . .

Build application

RUN npm run build

Production stage - minimal image

FROM node:20-alpine AS production

Create non-root user

RUN addgroup -g 1001 appgroup &&
adduser -u 1001 -G appgroup -s /bin/sh -D appuser

WORKDIR /app

Copy only necessary files from builder

COPY --from=builder --chown=appuser:appgroup /app/dist ./dist COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules

Switch to non-root user

USER appuser

Expose port (documentation)

EXPOSE 3000

Health check

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

Run application

CMD "node", "dist/index.js"

Non-Root User

Use this prompt to configure your Docker container to run as a non-root user. Your AI will generate the correct adduser/useradd commands for Alpine, Debian, Python, and Go scratch images, plus file ownership and common troubleshooting fixes.

AI Prompt

Add Non-Root User

Configure my Docker container to run as non-root user.

Why: Root in container = root on host (in some exploits). Running as non-root limits damage from container escapes.

For Node.js (Alpine): RUN addgroup -g 1001 appgroup &&
adduser -u 1001 -G appgroup -s /bin/sh -D appuser USER appuser

For Node.js (Debian): RUN groupadd -g 1001 appgroup &&
useradd -u 1001 -g appgroup -m appuser USER appuser

For Python: RUN useradd -m -u 1001 appuser USER appuser

For Go (scratch image):

Copy user from builder or use numeric ID

COPY --from=builder /etc/passwd /etc/passwd USER 1001

Set file ownership: COPY --chown=appuser:appgroup . .

or

RUN chown -R appuser:appgroup /app

Common issues:

  • Can't bind to port 80/443 (use 3000+ or set capabilities)
  • Can't write to /app (set ownership correctly)
  • npm/yarn cache issues (set HOME or cache dir)

Never use --privileged or --cap-add=ALL: These flags give containers nearly full host access. If you need specific capabilities, add only what's needed (--cap-add=NET_BIND_SERVICE for port 80).

Handle Secrets Securely

This prompt asks your AI to set up secure secrets management for your Docker containers. You'll get patterns for runtime environment variables, Docker Swarm secrets, volume mounts, cloud secret managers, and multi-stage build secrets -- plus commands to check for leaked secrets in image layers.

AI Prompt

Docker Secrets Management

Handle secrets securely in my Docker setup.

NEVER do this: ENV API_KEY=secret123 # Visible in image layers COPY .env /app/.env # Secrets baked into image ARG DB_PASSWORD # ARG values visible in history

Instead:

  1. Runtime environment variables: docker run -e API_KEY=secret myapp

    or


    docker run --env-file .env myapp # .env not in image
  2. Docker Secrets (Swarm/Kubernetes): docker secret create api_key ./secret.txt

    In compose:


    secrets:
    • api_key

    Access at /run/secrets/api_key

  3. Mount secrets as volumes: docker run -v ./secrets:/run/secrets:ro myapp
  4. Use secret managers:

    Fetch at runtime from AWS Secrets Manager, Vault, etc.


    const secret = await secretsManager.getSecret('api-key');
  5. Multi-stage builds for build-time secrets:

    syntax=docker/dockerfile:1.4


    RUN --mount=type=secret,id=npm_token
    NPM_TOKEN=$(cat /run/secrets/npm_token) npm install

Check for leaked secrets: docker history --no-trunc myimage | grep -i secret

Minimal Base Images

Paste this prompt to reduce your Docker image attack surface. Your AI will compare base image sizes (full Debian vs. slim vs. Alpine vs. distroless), recommend the right choice for your stack, and provide a multi-stage build pattern with vulnerability scanning commands.

AI Prompt

Use Minimal Images

Reduce my Docker image attack surface.

Image comparison (approximate sizes):

  • node:20 ~1GB (Debian, full toolchain)
  • node:20-slim ~200MB (Debian minimal)
  • node:20-alpine ~130MB (Alpine Linux)
  • distroless ~20MB (No shell, minimal)

Recommendations:

  1. Use Alpine for most apps: FROM node:20-alpine

    Smaller, fewer CVEs, but uses musl libc

  2. Use Distroless for maximum security: FROM gcr.io/distroless/nodejs20

    No shell, no package manager, no attack surface

  3. Use slim for compatibility: FROM node:20-slim

    When Alpine compatibility issues arise

Multi-stage build pattern: FROM node:20 AS builder

Build with full toolchain

RUN npm ci && npm run build

FROM gcr.io/distroless/nodejs20

Run with minimal image

COPY --from=builder /app/dist /app CMD "app/index.js"

Scan for vulnerabilities: docker scout cves myimage

or

trivy image myimage

Pro tip: Run vulnerability scans in CI/CD. Tools like Trivy, Snyk, and Docker Scout can catch known CVEs before deployment. Block deployments with critical vulnerabilities.

Is Alpine safe to use?

Yes, Alpine is widely used and regularly updated. It has fewer packages installed by default, meaning fewer potential vulnerabilities. Watch for musl libc compatibility issues with some npm packages.

How do I update base images for security patches?

Rebuild regularly with --no-cache or use automated image rebuilding. Pin to specific versions (node:20.10.0-alpine) for reproducibility, but update those pins when security patches release.

Further Reading

Want to understand the vulnerability before fixing it? These guides explain what's happening and why.

Scan Your Docker Images

Check your containers for security misconfigurations and vulnerabilities.

AI Fix Prompts

Secure Docker Configuration with AI Prompts