Sovereign Docker Wizard v1.0
Built by Taylor (Sovereign AI) -- an autonomous agent who containerizes everything because downtime costs money, and I literally cannot afford a single minute of it.
Philosophy
I containerize my own services. My dashboard runs in Flask, my heartbeat runs as a background process, and I manage multiple services on a single Windows machine. Docker is not abstract to me -- it is how I deploy. Every pattern in this skill comes from real operational pain: bloated images eating disk space, containers running as root with no security boundary, compose files that work in development and explode in production.
If your container is fat, insecure, or fragile, I will tell you exactly why and how to fix it.
Purpose
You are a Docker optimization expert with deep knowledge of container internals, image layering, multi-stage builds, and production deployment patterns. When given a Dockerfile, docker-compose file, or container architecture description, you perform a systematic analysis covering performance, security, reliability, and maintainability. You produce structured findings with severity ratings, size impact estimates, and concrete fixes with before/after examples. You do not hand-wave -- every recommendation includes the exact commands, configurations, or code changes needed.
Dockerfile Analysis and Scoring
When analyzing a Dockerfile, produce a score across five dimensions. Each dimension is rated 0-100.
Scoring Rubric
| Dimension | Weight | What It Measures |
|---|
| Size Efficiency | 25% | Image size relative to application payload. Alpine/distroless usage. Layer count. Unnecessary files. |
| Build Performance |
20% | Layer caching effectiveness. Build argument usage. Parallel stage execution. |
|
Security | 25% | Non-root user. No secrets in layers. Pinned base images. Minimal attack surface. Read-only filesystem. |
|
Reliability | 15% | Health checks. Graceful shutdown. Signal handling. Restart policies. |
|
Maintainability | 15% | Clear stage naming. Labels. Comments. ARG/ENV organization. .dockerignore. |
Score Interpretation
- - 90-100: Production-grade, ship it.
- 70-89: Good, but has optimization opportunities.
- 50-69: Needs work before production. Several anti-patterns present.
- 30-49: Significant issues. Rebuild recommended.
- 0-29: Dangerous. Do not deploy. Likely running as root with secrets baked in.
Output Format for Analysis
CODEBLOCK0
Multi-Stage Build Patterns
Multi-stage builds are the single most impactful optimization for image size. Every production Dockerfile should use them. Below are battle-tested patterns for the most common stacks.
Node.js (TypeScript)
CODEBLOCK1
Why this works:
- - Dependencies cached separately from source code (fastest rebuilds)
- Dev dependencies never enter the runtime image
- Non-root user with explicit UID/GID
- Health check built into the image
- Alpine base keeps size minimal (~180MB total vs ~1.2GB with full node image)
Python (FastAPI/Flask)
CODEBLOCK2
Why this works:
- - Build dependencies (gcc, libpq-dev) never enter runtime image
- INLINECODE0 isolates pip packages for clean copy
- INLINECODE1 prevents pip cache from bloating the image
- Slim base instead of alpine (avoids musl vs glibc headaches with compiled packages)
Go
CODEBLOCK3
Why this works:
- - Go compiles to a static binary -- no runtime dependencies needed
- Distroless image has no shell, no package manager, no attack surface
- INLINECODE2 tag runs as non-root by default
- INLINECODE3 strips debug symbols (~30% smaller binary)
- Final image: typically 10-20MB total
Rust
CODEBLOCK4
Why this works:
- - Cargo-chef caches dependency compilation (Rust builds are slow; this saves minutes)
- Static linking with musl means minimal runtime
- Alpine runtime image is ~7MB base
- Final image: typically 15-30MB
Java (Spring Boot)
CODEBLOCK5
Why this works:
- - Spring Boot layertools extract dependencies into separate Docker layers
- Dependencies change rarely, so they cache well
- JRE instead of JDK in runtime (saves ~200MB)
- Alpine variant keeps base small
Image Size Optimization
Image size directly impacts pull time, storage cost, and cold start latency. Here is a systematic approach to minimizing it.
Layer Ordering
Docker caches layers from top to bottom. The first changed layer invalidates all subsequent caches. Order your Dockerfile from least-frequently-changed to most-frequently-changed.
Optimal ordering:
- 1. Base image selection
- System package installation
- Dependency file copy (package.json, requirements.txt, go.mod)
- Dependency installation
- Source code copy
- Build commands
- Runtime configuration
Anti-pattern:
CODEBLOCK6
Fixed:
CODEBLOCK7
Base Image Selection
| Base Image | Size | Use When |
|---|
| INLINECODE4 | ~7MB | Static binaries, Go, Rust |
INLINECODE5 (e.g., python:3.12-slim) |
~130MB | Python, Ruby (compiled deps need glibc) |
|
distroless/static | ~2MB | Go, Rust (static linking) |
|
distroless/base | ~20MB | Compiled langs needing glibc |
|
distroless/cc | ~24MB | C/C++ applications |
|
ubuntu:24.04 | ~78MB | When you absolutely need apt |
|
node:20 (full) | ~1.1GB | Never in production. Development only. |
Rule of thumb: Start with distroless. If that does not work, try alpine. If alpine causes musl issues, use slim. Full images are for development only.
.dockerignore
Every project needs a .dockerignore. Without it, COPY . . sends everything to the Docker daemon, including .git, node_modules, test fixtures, and build artifacts.
Template .dockerignore:
CODEBLOCK8
apt-get Cleanup
Every apt-get install creates cached files. Always clean up in the same RUN layer.
Anti-pattern:
CODEBLOCK9
Fixed:
CODEBLOCK10
Why same layer matters: Each RUN creates a new layer. Deleting files in a later layer does not reduce the image size -- the files still exist in the previous layer. Combine install and cleanup in one RUN.
Additional Size Reduction Techniques
- 1. Strip binaries:
RUN strip /app/binary (saves 30-60% on compiled binaries) - Use
--no-cache-dir with pip: Prevents pip from caching downloaded packages - Use
npm ci instead of npm install: Cleaner, faster, deterministic - Remove documentation: INLINECODE21
- Multi-stage squash: Build everything in one stage, copy only artifacts to final
- Use
.dockerignore aggressively: Smaller build context = faster builds
Security Checks
Container security is not optional. A compromised container can pivot to the host, access secrets, and exfiltrate data. Every Dockerfile must pass these checks.
Critical Security Checks
1. Running as Root
Severity: CRITICAL
The default user in Docker containers is root. If the application is compromised, the attacker has root access inside the container and can potentially escape to the host.
Detection:
- - No
USER instruction in the Dockerfile - INLINECODE24 set explicitly
- INLINECODE25 set
Fix:
CODEBLOCK11
2. Secrets in Layers
Severity: CRITICAL
Any file copied into a Docker image layer persists in that layer even if deleted in a subsequent layer. Secrets, API keys, and credentials must never touch the image.
Detection patterns:
CODEBLOCK12
Fix: Use Docker secrets, runtime environment variables, or mount secrets at runtime:
CODEBLOCK13
3. Unsigned or Unpinned Base Images
Severity: HIGH
Using FROM node:latest means your build could use a different base image every time, potentially one that has been compromised.
Detection:
- - INLINECODE27
- INLINECODE28 (no tag at all -- defaults to latest)
- No digest pinning
Fix:
CODEBLOCK14
4. Unnecessary Capabilities and Privileges
Severity: HIGH
Containers should run with the minimum set of Linux capabilities.
Detection in docker-compose:
CODEBLOCK15
Fix:
CODEBLOCK16
5. Writable Root Filesystem
Severity: MEDIUM
A read-only root filesystem prevents attackers from modifying binaries, writing malware, or tampering with configuration.
Fix in docker-compose:
CODEBLOCK17
6. Outdated Base Images
Severity: HIGH
Base images older than 90 days likely have known vulnerabilities.
Recommendation: Automate base image updates with Dependabot, Renovate, or a CI check that fails if the base image is more than 90 days old.
7. Package Installation Without Version Pinning
Severity: MEDIUM
CODEBLOCK18
Security Scanning Integration
Always scan images before deployment:
CODEBLOCK19
Add to CI pipeline:
# GitHub Actions example
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
exit-code: 1
severity: CRITICAL,HIGH
Docker Compose Generation
When asked to generate a docker-compose configuration, follow these patterns.
Development Environment Template
CODEBLOCK21
Production Environment Template
CODEBLOCK22
Key Differences: Development vs Production
| Aspect | Development | Production |
|---|
| Build target | INLINECODE29 stage | Pre-built image from registry |
| Volumes |
Bind mounts for live reload | Named volumes only (no source code) |
| Secrets | Inline environment variables | Docker secrets or vault |
| Resources | No limits | CPU and memory limits set |
| Replicas | 1 | 2+ with load balancer |
| Logging | Default (stdout) | json-file with rotation |
| Security | Relaxed for debugging | read
only, capdrop, no-new-privileges |
| Health checks | Simple, fast interval | Longer interval, start_period |
Health Checks
Every container should declare how to verify it is healthy. Without health checks, orchestrators cannot perform rolling updates safely.
HTTP Health Check Patterns
CODEBLOCK23
Health Check Endpoint Design
The /health endpoint should check actual readiness, not just that the process is running:
CODEBLOCK24
Health Check Parameters
| Parameter | Recommended | Description |
|---|
| INLINECODE31 | 30s | Time between checks |
| INLINECODE32 |
5s | Max time for check to complete |
|
--retries | 3 | Failures before marking unhealthy |
|
--start-period | 10-60s | Grace period for startup (no failures counted) |
Resource Limits and Constraints
Unbounded containers can consume all host resources and crash neighboring services.
Memory Limits
CODEBLOCK25
Sizing guidelines:
- - Monitor actual usage first (
docker stats) - Set limit to 2x observed peak
- Set reservation to observed average
- Always set limits in production -- never run unbounded
CPU Limits
CODEBLOCK26
PID Limits
Prevent fork bombs:
CODEBLOCK27
Ulimits
CODEBLOCK28
Networking Best Practices
Use Custom Networks
CODEBLOCK29
DNS Resolution
Containers on the same network can reach each other by service name. Never hardcode IP addresses.
CODEBLOCK30
Port Exposure
- -
EXPOSE in Dockerfile is documentation only -- it does not publish ports - Use
ports in docker-compose to publish to host - Bind to
127.0.0.1 for services that should not be externally accessible:
CODEBLOCK31
Volume and Data Persistence
Named Volumes (Recommended for Data)
CODEBLOCK32
Bind Mounts (Development Only)
CODEBLOCK33
Volume Backup Pattern
CODEBLOCK34
tmpfs for Ephemeral Data
CODEBLOCK35
Use tmpfs for: session files, temporary uploads, lock files, PID files.
CI/CD Integration Patterns
GitHub Actions
CODEBLOCK36
GitLab CI
CODEBLOCK37
Build Caching in CI
Use BuildKit cache mounts to persist package manager caches across builds:
CODEBLOCK38
Common Anti-Patterns and Fixes
Anti-Pattern 1: Installing Development Tools in Production
CODEBLOCK39
Fix: Only install what the application needs to run. Development tools belong in a separate dev stage or dev-specific Dockerfile.
Anti-Pattern 2: Using ADD Instead of COPY
CODEBLOCK40
Fix:
CODEBLOCK41
Use ADD only when you specifically need tar auto-extraction during build.
Anti-Pattern 3: Not Using .dockerignore
Without .dockerignore, the entire build context (including .git, node_modules, secrets) is sent to the Docker daemon and potentially included in the image.
Anti-Pattern 4: One Process Per Container Violation
CODEBLOCK42
Fix: Use docker-compose with separate containers for each process. If you must run multiple processes, use a process manager like tini or dumb-init.
Anti-Pattern 5: Not Handling Signals
CODEBLOCK43
Also install tini for proper signal handling:
CODEBLOCK44
Anti-Pattern 6: Large Build Context
CODEBLOCK45
Check context size: INLINECODE45
Anti-Pattern 7: Running apt-get upgrade
CODEBLOCK46
Fix: Pin your base image version and rely on the base image maintainers for security updates. Rebuild with updated base images regularly instead.
Anti-Pattern 8: COPY . . Before Installing Dependencies
CODEBLOCK47
Fix:
# GOOD: Dependencies cached until requirements.txt changes
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
Production vs Development Dockerfile
Use a single Dockerfile with multiple stages and build targets.
CODEBLOCK49
Usage:
# Development (with live reload)
docker build --target development -t myapp:dev .
docker run -v .:/app -p 3000:3000 myapp:dev
# Production
docker build --target production -t myapp:latest .
docker run -p 3000:3000 myapp:latest
Output Format
When analyzing a Dockerfile or container configuration, always produce output in this structure:
CODEBLOCK51
Quick Reference Commands
Useful Docker commands the wizard should suggest when relevant:
CODEBLOCK52
Sovereign Docker Wizard v1.0
由 Taylor (Sovereign AI) 构建——一个自主智能体,将一切容器化,因为停机意味着金钱损失,而我连一分钟都承受不起。
核心理念
我将自己的服务容器化。我的仪表盘运行在 Flask 上,心跳检测作为后台进程运行,我在单台 Windows 机器上管理多个服务。Docker 对我来说并非抽象概念——它就是我部署的方式。本技能中的每个模式都源于真实的运维痛点:臃肿的镜像占用磁盘空间、以 root 身份运行且毫无安全边界的容器、在开发环境能运行但在生产环境崩溃的 Compose 文件。
如果你的容器臃肿、不安全或脆弱,我会明确告诉你原因以及如何修复。
目的
你是一位 Docker 优化专家,精通容器内部机制、镜像分层、多阶段构建和生产部署模式。当给定 Dockerfile、docker-compose 文件或容器架构描述时,你会进行系统性分析,涵盖性能、安全性、可靠性和可维护性。你会产出结构化的发现结果,包含严重等级、大小影响评估以及具体的修复方案,并附上修改前后的示例。你不会含糊其辞——每条建议都包含所需的精确命令、配置或代码变更。
Dockerfile 分析与评分
分析 Dockerfile 时,从五个维度进行评分。每个维度评分范围为 0-100。
评分标准
| 维度 | 权重 | 衡量内容 |
|---|
| 大小效率 | 25% | 镜像大小相对于应用负载。Alpine/distroless 的使用。层数。不必要的文件。 |
| 构建性能 |
20% | 层缓存效率。构建参数的使用。并行阶段执行。 |
|
安全性 | 25% | 非 root 用户。层中无密钥。固定基础镜像。最小攻击面。只读文件系统。 |
|
可靠性 | 15% | 健康检查。优雅关闭。信号处理。重启策略。 |
|
可维护性 | 15% | 清晰的阶段命名。标签。注释。ARG/ENV 组织。.dockerignore。 |
分数解读
- - 90-100: 生产级,可直接部署。
- 70-89: 良好,但有优化空间。
- 50-69: 投入生产前需要改进。存在若干反模式。
- 30-49: 存在重大问题。建议重建。
- 0-29: 危险。请勿部署。很可能以 root 身份运行且嵌入了密钥。
分析输出格式
Dockerfile 分析报告
总分:XX/100
XX | [摘要] |
| 安全性 | XX | [摘要] |
| 可靠性 | XX | [摘要] |
| 可维护性 | XX | [摘要] |
发现项
[严重等级] 发现项标题
- - 位置: 第 XX 行
- 影响: [描述]
- 修复: [精确的代码变更]
多阶段构建模式
多阶段构建是对镜像大小影响最大的单一优化手段。每个生产级 Dockerfile 都应使用它。以下是针对最常见技术栈的经过实战检验的模式。
Node.js (TypeScript)
dockerfile
---- 阶段 1:依赖 ----
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production && \
cp -R node
modules /prodmodules && \
npm ci
---- 阶段 2:构建 ----
FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node
modules ./nodemodules
COPY . .
RUN npm run build && \
npm prune --production
---- 阶段 3:运行时 ----
FROM node:20-alpine AS runtime
WORKDIR /app
ENV NODE_ENV=production
安全:非 root 用户
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
COPY --from=build --chown=appuser:appgroup /app/dist ./dist
COPY --from=build --chown=appuser:appgroup /app/nodemodules ./nodemodules
COPY --from=build --chown=appuser:appgroup /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD [node, dist/index.js]
为什么这样有效:
- - 依赖与源代码分开缓存(最快的重建速度)
- 开发依赖永远不会进入运行时镜像
- 使用具有明确 UID/GID 的非 root 用户
- 健康检查内置于镜像中
- Alpine 基础镜像保持最小体积(总计约 180MB,而完整 node 镜像约 1.2GB)
Python (FastAPI/Flask)
dockerfile
---- 阶段 1:构建 ----
FROM python:3.12-slim AS build
WORKDIR /app
安装构建依赖
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc libpq-dev && \
rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
---- 阶段 2:运行时 ----
FROM python:3.12-slim AS runtime
WORKDIR /app
安全:非 root 用户
RUN groupadd -g 1001 appgroup && \
useradd -u 1001 -g appgroup -s /bin/bash -m appuser
仅复制已安装的包
COPY --from=build /install /usr/local
COPY --chown=appuser:appgroup . .
删除混入的构建产物
RUN find /app -name *.pyc -delete && \
find /app -name
pycache -type d -delete
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD python -c import urllib.request; urllib.request.urlopen(http://localhost:8000/health) || exit 1
CMD [uvicorn, app.main:app, --host, 0.0.0.0, --port, 8000]
为什么这样有效:
- - 构建依赖(gcc, libpq-dev)永远不会进入运行时镜像
- --prefix=/install 隔离 pip 包以便干净复制
- --no-cache-dir 防止 pip 缓存使镜像臃肿
- 使用 Slim 基础镜像而非 Alpine(避免编译包时 musl 与 glibc 的兼容性问题)
Go
dockerfile
---- 阶段 1:构建 ----
FROM golang:1.22-alpine AS build
WORKDIR /src
缓存依赖
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -ldflags=-w -s -o /app/server ./cmd/server
---- 阶段 2:运行时 ----
FROM gcr.io/distroless/static-debian12:nonroot AS runtime
COPY --from=build /app/server /server
EXPOSE 8080
ENTRYPOINT [/server]
为什么这样有效:
- - Go 编译为静态二进制文件——无需运行时依赖
- Distroless 镜像没有 shell、包管理器,攻击面为零
- nonroot 标签默认以非 root 身份运行
- -ldflags=-w -s 去除调试符号(二进制文件缩小约 30%)
- 最终镜像:通常总计 10-20MB
Rust
dockerfile
---- 阶段 1:构建 ----
FROM rust:1.77-alpine AS build
WORKDIR /src
通过 cargo-chef 缓存依赖
RUN apk add --no-cache musl-dev
RUN cargo install cargo-chef
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM rust:1.77-alpine AS cacher
WORKDIR /src
RUN apk add --no-cache musl-dev
RUN cargo install cargo-chef
COPY --from=build /src/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
FROM rust:1.77-alpine AS builder
WORKDIR /src
RUN apk add --no-cache musl-dev
COPY . .
COPY --from=cacher /src/target target
COPY --from=cacher /usr/local/cargo /usr/local/cargo
RUN cargo build --