Claude-skill-registry docker-reviewer

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/docker-reviewer" ~/.claude/skills/majiayu000-claude-skill-registry-docker-reviewer && rm -rf "$T"
manifest: skills/data/docker-reviewer/SKILL.md
source content

Docker Reviewer Skill

Purpose

Reviews Dockerfiles and docker-compose configurations for optimization, security, and best practices.

When to Use

  • Dockerfile code review
  • Docker image optimization
  • docker-compose.yml review
  • Container security audit
  • Build time optimization

Project Detection

  • Dockerfile
    in project
  • docker-compose.yml
    or
    docker-compose.yaml
  • .dockerignore
    file
  • Dockerfile.*
    variants

Workflow

Step 1: Analyze Project

**Base Image**: node:20-alpine
**Build Type**: Multi-stage
**Compose**: v3.8
**Registry**: Docker Hub / ECR / GCR

Step 2: Select Review Areas

AskUserQuestion:

"Which areas to review?"
Options:
- Full Docker review (recommended)
- Dockerfile optimization
- Layer caching strategy
- Security hardening
- docker-compose review
multiSelect: true

Detection Rules

Image Optimization

CheckRecommendationSeverity
Large base imageUse alpine/slim/distrolessHIGH
No multi-stage buildAdd build stageMEDIUM
Too many layersCombine RUN commandsMEDIUM
Installing dev depsSeparate build/runtimeHIGH
# BAD: Large image with dev dependencies
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/index.js"]
# Result: ~1GB image

# GOOD: Multi-stage with alpine
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/index.js"]
# Result: ~150MB image

Layer Caching

CheckRecommendationSeverity
COPY . before installCopy package files firstHIGH
No .dockerignoreAdd .dockerignoreMEDIUM
Changing files earlyOrder by change frequencyMEDIUM
# BAD: Cache invalidation on every code change
FROM node:20-alpine
WORKDIR /app
COPY . .                    # Invalidates cache on ANY change
RUN npm install             # Always reinstalls

# GOOD: Leverage layer caching
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./       # Only invalidates on package change
RUN npm ci                  # Cached if packages unchanged
COPY . .                    # Code changes don't affect npm cache
RUN npm run build
# .dockerignore
node_modules
.git
.gitignore
*.md
.env*
dist
coverage
.nyc_output

Security

CheckRecommendationSeverity
Running as rootAdd USER directiveCRITICAL
Latest tagPin specific versionHIGH
Secrets in buildUse build secretsCRITICAL
No health checkAdd HEALTHCHECKMEDIUM
# BAD: Security issues
FROM node:latest           # Unpinned version
WORKDIR /app
COPY . .
ENV API_KEY=secret123      # Secret in image!
RUN npm install
CMD ["node", "index.js"]   # Running as root

# GOOD: Secure Dockerfile
FROM node:20.10-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20.10-alpine
WORKDIR /app

# Create non-root user
RUN addgroup -g 1001 appgroup && \
    adduser -u 1001 -G appgroup -s /bin/sh -D appuser

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

USER appuser

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

EXPOSE 3000
CMD ["node", "index.js"]

Build Secrets (Docker BuildKit)

# syntax=docker/dockerfile:1.4

FROM node:20-alpine
WORKDIR /app

# Mount secret during build (not stored in layer)
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) \
    npm ci

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

RUN Optimization

CheckRecommendationSeverity
Multiple RUN for cleanupCombine in single RUNMEDIUM
No cleanup after installRemove cache in same layerMEDIUM
# BAD: Multiple layers, cache not cleaned
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean

# GOOD: Single layer with cleanup
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

Docker Compose

CheckRecommendationSeverity
No resource limitsAdd deploy.resourcesHIGH
No health checksAdd healthcheckMEDIUM
Hardcoded configUse environment variablesMEDIUM
No restart policyAdd restart: unless-stoppedMEDIUM
# BAD: Minimal compose
version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: password123

# GOOD: Production-ready compose
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:${DB_PASSWORD}@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d app"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

Response Template

## Docker Review Results

**Project**: [name]
**Base Image**: node:20-alpine
**Build**: Multi-stage | **Compose**: v3.8

### Image Optimization
| Status | File | Issue |
|--------|------|-------|
| HIGH | Dockerfile | Using node:latest (~1GB) |

### Layer Caching
| Status | File | Issue |
|--------|------|-------|
| HIGH | Dockerfile:5 | COPY . before npm install |

### Security
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | Dockerfile | Running as root user |

### Compose
| Status | File | Issue |
|--------|------|-------|
| HIGH | docker-compose.yml | No resource limits |

### Recommended Actions
1. [ ] Switch to node:20-alpine base image
2. [ ] Add multi-stage build
3. [ ] Add USER directive for non-root
4. [ ] Add resource limits in compose

Best Practices

  1. Base Image: Use alpine/slim/distroless
  2. Multi-stage: Separate build and runtime
  3. Caching: Order by change frequency
  4. Security: Non-root, pinned versions, no secrets
  5. Compose: Health checks, resource limits

Integration

  • k8s-reviewer
    : Kubernetes deployments
  • security-scanner
    : Container security
  • ci-cd-reviewer
    : Build pipelines