agent-ops-docker-review
skillDocker image reviews, optimization, and step-building guidance. Analyzes Dockerfiles for best practices, security issues, and anti-patterns.
opencodeclaudecursor
apm::install
apm install @majiayu000/agent-ops-docker-reviewapm::skill.md
---
name: agent-ops-docker-review
description: "Docker image reviews, optimization, and step-building guidance. Analyzes Dockerfiles for best practices, security issues, and anti-patterns."
license: MIT
compatibility: [opencode, claude, cursor]
metadata:
category: analysis
related: [agent-ops-state]
---
# Docker Review Skill
Analyze Dockerfiles for best practices, security issues, and optimization opportunities.
## Modes
| Mode | Command | Purpose |
|------|---------|---------|
| Review | `/docker-review` | Analyze existing Dockerfile, produce findings report |
| Optimize | `/docker-optimize` | Suggest specific changes with before/after comparison |
| Build | `/docker-build` | Interactive step-by-step Dockerfile creation |
| Scan | `/docker-scan` | Run security scanners on built images (requires Docker) |
## Review Mode
### Trigger
```
/docker-review [path/to/Dockerfile]
```
If no path provided, search for `Dockerfile` in project root.
### Procedure
1. **Locate Dockerfile**
- Check provided path or search common locations
- If not found, offer to create one (switches to Build mode)
2. **Static Analysis**
- Parse Dockerfile instructions
- Check against best practices rules (see below)
- Identify anti-patterns and security issues
3. **Generate Report**
- Output to `.agent/docker-review.md`
- Categorize findings by severity
- Provide fix suggestions for each finding
### Output Format
```markdown
# Docker Review Report
**File:** Dockerfile
**Date:** YYYY-MM-DD
**Base Image:** python:3.11-slim
## Summary
| Severity | Count |
|----------|-------|
| 🔴 Error | 2 |
| 🟡 Warning | 5 |
| 🔵 Info | 3 |
## Findings
### 🔴 Error: Running as root user
**Line 1-end**
No USER instruction found. Container will run as root.
**Fix:**
```dockerfile
# Add before CMD/ENTRYPOINT
RUN useradd -r -s /bin/false appuser
USER appuser
```
### 🟡 Warning: Unpinned base image version
...
```
## Best Practices Rules
### Security (🔴 Error level)
| ID | Rule | Description |
|----|------|-------------|
| SEC001 | Non-root user | Container must not run as root |
| SEC002 | No secrets in build | No passwords, API keys, or tokens in Dockerfile |
| SEC003 | COPY over ADD | Use COPY unless ADD features needed (URL, tar extraction) |
| SEC004 | Minimal base | Prefer alpine, slim, or distroless images |
### Optimization (🟡 Warning level)
| ID | Rule | Description |
|----|------|-------------|
| OPT001 | Pin versions | Pin base image and package versions |
| OPT002 | Combine RUN | Chain RUN commands to reduce layers |
| OPT003 | Clean in same layer | Remove caches in same RUN as install |
| OPT004 | Order by change frequency | Put least-changing instructions first |
| OPT005 | Use .dockerignore | Exclude unnecessary files from context |
| OPT006 | Multi-stage builds | Separate build and runtime stages |
### Maintainability (🔵 Info level)
| ID | Rule | Description |
|----|------|-------------|
| MNT001 | Use LABEL | Add maintainer, version, description labels |
| MNT002 | HEALTHCHECK | Define health check for orchestrators |
| MNT003 | Explicit EXPOSE | Document exposed ports |
| MNT004 | ARG for versions | Use build args for version pinning |
## Optimize Mode
### Trigger
```
/docker-optimize [path/to/Dockerfile]
```
### Procedure
1. Run Review mode analysis
2. Generate optimized Dockerfile with all fixes applied
3. Show before/after comparison
4. Estimate size reduction (if possible)
### Output
Creates `.agent/references/dockerfile-optimized.md`:
```markdown
# Optimized Dockerfile
## Changes Applied
1. ✅ SEC001: Added non-root user
2. ✅ OPT002: Combined 5 RUN commands into 2
3. ✅ OPT006: Converted to multi-stage build
## Estimated Impact
- Layers: 12 → 6 (50% reduction)
- Size: ~450MB → ~120MB (estimated, multi-stage)
## Original
```dockerfile
FROM python:3.11
COPY . /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
```
## Optimized
```dockerfile
# Build stage
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Runtime stage
FROM python:3.11-slim
WORKDIR /app
RUN useradd -r -s /bin/false appuser
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --chown=appuser:appuser . .
USER appuser
EXPOSE 8000
HEALTHCHECK CMD curl -f http://localhost:8000/health || exit 1
CMD ["python", "app.py"]
```
```
## Build Mode (Interactive)
### Trigger
```
/docker-build
```
### Procedure
1. **Interview** (one question at a time):
- What language/runtime? (Python, Node, Go, .NET, Java, Rust, other)
- What is the entry point? (main.py, npm start, ./app, etc.)
- What port(s) to expose?
- Any build steps needed? (compile, bundle, etc.)
- Any system dependencies? (apt packages, etc.)
2. **Generate Dockerfile** using language-specific template
3. **Generate .dockerignore** if not exists
4. **Review** the generated files with user
### Language Templates
#### Python Template
```dockerfile
# syntax=docker/dockerfile:1
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
WORKDIR /app
# Security: non-root user
RUN useradd -r -s /bin/false appuser && \
chown -R appuser:appuser /app
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --chown=appuser:appuser . .
USER appuser
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8000/health || exit 1
CMD ["python", "-m", "{{entry_point}}"]
```
#### Node.js Template
```dockerfile
# syntax=docker/dockerfile:1
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:20-alpine
WORKDIR /app
# Security: non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S appuser -u 1001 -G nodejs
COPY --from=builder /app/node_modules ./node_modules
COPY --chown=appuser:nodejs . .
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "{{entry_point}}"]
```
#### Go Template
```dockerfile
# syntax=docker/dockerfile:1
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o /app/main .
FROM scratch
COPY --from=builder /app/main /main
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
USER 65534:65534
EXPOSE 8080
ENTRYPOINT ["/main"]
```
#### .NET Template
```dockerfile
# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /out --no-restore
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
# Security: non-root user
RUN useradd -r -s /bin/false appuser
COPY --from=builder /out .
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:8080/health || exit 1
ENTRYPOINT ["dotnet", "{{assembly}}.dll"]
```
## Scan Mode
### Trigger
```
/docker-scan [image-name]
```
### Prerequisites
- Docker installed and running
- Image must be built locally or pullable
### Procedure
1. **Check tool availability**:
- `trivy` (preferred) — vulnerability scanner
- `grype` (alternative) — vulnerability scanner
- `dockle` — CIS benchmark linter
- `dive` — layer analysis
2. **Run available scanners**:
```bash
# Trivy
trivy image --severity HIGH,CRITICAL {{image}}
# Grype
grype {{image}} --only-fixed
# Dockle
dockle {{image}}
# Dive
dive {{image}} --ci
```
3. **Aggregate results** into report
### Output
```markdown
# Docker Security Scan Report
**Image:** myapp:latest
**Date:** YYYY-MM-DD
## Vulnerability Summary
| Severity | Count | Fixed Available |
|----------|-------|-----------------|
| Critical | 2 | 2 |
| High | 5 | 3 |
| Medium | 12 | 8 |
## Critical Vulnerabilities
### CVE-2024-1234 — OpenSSL Buffer Overflow
- **Package:** openssl 1.1.1k
- **Fixed in:** 1.1.1l
- **Action:** Update base image or add `RUN apt-get update && apt-get install -y openssl`
## CIS Benchmark Results
- ✅ CIS-DI-0001: Create user for container
- ❌ CIS-DI-0005: Content trust not enabled
- ✅ CIS-DI-0006: HEALTHCHECK instruction defined
## Layer Efficiency
- Total size: 245MB
- Wasted space: 12MB (4.9%)
- Largest layers:
1. /usr/lib (89MB) — system libraries
2. /app/node_modules (67MB) — dependencies
```
## External Tool Integration
### Hadolint (if available)
```bash
# Check if hadolint is available
hadolint --version
# Run hadolint
hadolint Dockerfile --format json
```
Parse hadolint output and merge with built-in rules. Hadolint rules take precedence when available.
### Tool Detection
At skill start, check for available tools:
```
🔧 Tool Detection:
- hadolint: ✅ v2.12.0 (enhanced linting)
- trivy: ✅ v0.48.0 (vulnerability scanning)
- dive: ❌ not found
- dockle: ❌ not found
Running with: hadolint + trivy
```
## Forbidden Behaviors
- Never run `docker build` without user confirmation
- Never push images to registries
- Never modify Dockerfile without showing diff first
- Never store secrets in generated Dockerfiles