docker-reviewer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDocker Reviewer Skill
Docker Reviewer Skill
Purpose
用途
Reviews Dockerfiles and docker-compose configurations for optimization, security, and best practices.
针对Dockerfile和docker-compose配置进行优化、安全及最佳实践审查。
When to Use
适用场景
- Dockerfile code review
- Docker image optimization
- docker-compose.yml review
- Container security audit
- Build time optimization
- Dockerfile代码审查
- Docker镜像优化
- docker-compose.yml配置审查
- 容器安全审计
- 构建时间优化
Project Detection
项目检测条件
- in project
Dockerfile - or
docker-compose.ymldocker-compose.yaml - file
.dockerignore - variants
Dockerfile.*
- 项目中存在文件
Dockerfile - 存在或
docker-compose.yml文件docker-compose.yaml - 存在文件
.dockerignore - 存在变体文件
Dockerfile.*
Workflow
工作流程
Step 1: Analyze Project
步骤1:分析项目
**Base Image**: node:20-alpine
**Build Type**: Multi-stage
**Compose**: v3.8
**Registry**: Docker Hub / ECR / GCR**Base Image**: node:20-alpine
**Build Type**: Multi-stage
**Compose**: v3.8
**Registry**: Docker Hub / ECR / GCRStep 2: Select Review Areas
步骤2:选择审查领域
AskUserQuestion:
"Which areas to review?"
Options:
- Full Docker review (recommended)
- Dockerfile optimization
- Layer caching strategy
- Security hardening
- docker-compose review
multiSelect: true询问用户问题:
"需要审查哪些领域?"
选项:
- 完整Docker审查(推荐)
- Dockerfile优化
- 镜像层缓存策略
- 安全加固
- docker-compose配置审查
multiSelect: trueDetection Rules
检测规则
Image Optimization
镜像优化
| Check | Recommendation | Severity |
|---|---|---|
| Large base image | Use alpine/slim/distroless | HIGH |
| No multi-stage build | Add build stage | MEDIUM |
| Too many layers | Combine RUN commands | MEDIUM |
| Installing dev deps | Separate build/runtime | HIGH |
dockerfile
undefined| 检查项 | 建议 | 严重程度 |
|---|---|---|
| 基础镜像过大 | 使用alpine/slim/distroless镜像 | 高 |
| 未使用多阶段构建 | 添加构建阶段 | 中 |
| 镜像层过多 | 合并RUN命令 | 中 |
| 安装了开发依赖 | 分离构建阶段与运行阶段 | 高 |
dockerfile
undefinedBAD: Large image with dev dependencies
不良示例:包含开发依赖的大镜像
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/index.js"]
FROM node:20
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/index.js"]
Result: ~1GB image
结果:约1GB镜像
GOOD: Multi-stage with alpine
良好示例:使用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"]
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
结果:约150MB镜像
undefinedundefinedLayer Caching
镜像层缓存
| Check | Recommendation | Severity |
|---|---|---|
| COPY . before install | Copy package files first | HIGH |
| No .dockerignore | Add .dockerignore | MEDIUM |
| Changing files early | Order by change frequency | MEDIUM |
dockerfile
undefined| 检查项 | 建议 | 严重程度 |
|---|---|---|
| 在安装依赖前复制全部文件 | 先复制package相关文件 | 高 |
| 缺少.dockerignore文件 | 添加.dockerignore文件 | 中 |
| 频繁变更的文件放在前面 | 按变更频率排序文件复制顺序 | 中 |
dockerfile
undefinedBAD: Cache invalidation on every code change
不良示例:代码变更导致缓存失效
FROM node:20-alpine
WORKDIR /app
COPY . . # Invalidates cache on ANY change
RUN npm install # Always reinstalls
FROM node:20-alpine
WORKDIR /app
COPY . . # 任何变更都会使缓存失效
RUN npm install # 每次都需要重新安装
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
```gitignoreFROM node:20-alpine
WORKDIR /app
COPY package*.json ./ # 仅当依赖变更时缓存失效
RUN npm ci # 依赖未变更时复用缓存
COPY . . # 代码变更不影响npm缓存
RUN npm run build
```gitignore.dockerignore
.dockerignore
node_modules
.git
.gitignore
.md
.env
dist
coverage
.nyc_output
undefinednode_modules
.git
.gitignore
.md
.env
dist
coverage
.nyc_output
undefinedSecurity
安全配置
| Check | Recommendation | Severity |
|---|---|---|
| Running as root | Add USER directive | CRITICAL |
| Latest tag | Pin specific version | HIGH |
| Secrets in build | Use build secrets | CRITICAL |
| No health check | Add HEALTHCHECK | MEDIUM |
dockerfile
undefined| 检查项 | 建议 | 严重程度 |
|---|---|---|
| 以root用户运行 | 添加USER指令 | 严重 |
| 使用latest标签 | 固定具体版本 | 高 |
| 构建过程中包含密钥 | 使用构建密钥 | 严重 |
| 缺少健康检查 | 添加HEALTHCHECK | 中 |
dockerfile
undefinedBAD: 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
FROM node:latest # 未固定版本
WORKDIR /app
COPY . .
ENV API_KEY=secret123 # 密钥被嵌入镜像!
RUN npm install
CMD ["node", "index.js"] # 以root用户运行
GOOD: Secure Dockerfile
良好示例:安全的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
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
创建非root用户
RUN addgroup -g 1001 appgroup &&
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
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
CMD wget --quiet --tries=1 --spider http://localhost:3000/health || exit 1
EXPOSE 3000
CMD ["node", "index.js"]
undefinedRUN addgroup -g 1001 appgroup &&
adduser -u 1001 -G appgroup -s /bin/sh -D appuser
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
CMD wget --quiet --tries=1 --spider http://localhost:3000/health || exit 1
EXPOSE 3000
CMD ["node", "index.js"]
undefinedBuild Secrets (Docker BuildKit)
构建密钥(Docker BuildKit)
dockerfile
undefineddockerfile
undefinedsyntax=docker/dockerfile:1.4
syntax=docker/dockerfile:1.4
FROM node:20-alpine
WORKDIR /app
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
NPM_TOKEN=$(cat /run/secrets/npm_token)
npm ci
RUN --mount=type=secret,id=npm_token
NPM_TOKEN=$(cat /run/secrets/npm_token)
npm ci
NPM_TOKEN=$(cat /run/secrets/npm_token)
npm ci
Build command:
构建命令:
DOCKER_BUILDKIT=1 docker build --secret id=npm_token,src=.npmrc .
DOCKER_BUILDKIT=1 docker build --secret id=npm_token,src=.npmrc .
undefinedundefinedRUN Optimization
RUN命令优化
| Check | Recommendation | Severity |
|---|---|---|
| Multiple RUN for cleanup | Combine in single RUN | MEDIUM |
| No cleanup after install | Remove cache in same layer | MEDIUM |
dockerfile
undefined| 检查项 | 建议 | 严重程度 |
|---|---|---|
| 多次RUN命令用于清理 | 合并为单个RUN命令 | 中 |
| 安装后未清理缓存 | 在同一镜像层中清理缓存 | 中 |
dockerfile
undefinedBAD: Multiple layers, cache not cleaned
不良示例:多镜像层,未清理缓存
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
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/*
apt-get install -y --no-install-recommends curl &&
apt-get clean &&
rm -rf /var/lib/apt/lists/*
undefinedRUN apt-get update &&
apt-get install -y --no-install-recommends curl &&
apt-get clean &&
rm -rf /var/lib/apt/lists/*
apt-get install -y --no-install-recommends curl &&
apt-get clean &&
rm -rf /var/lib/apt/lists/*
undefinedDocker Compose
Docker Compose配置
| Check | Recommendation | Severity |
|---|---|---|
| No resource limits | Add deploy.resources | HIGH |
| No health checks | Add healthcheck | MEDIUM |
| Hardcoded config | Use environment variables | MEDIUM |
| No restart policy | Add restart: unless-stopped | MEDIUM |
yaml
undefined| 检查项 | 建议 | 严重程度 |
|---|---|---|
| 未设置资源限制 | 添加deploy.resources配置 | 高 |
| 缺少健康检查 | 添加healthcheck配置 | 中 |
| 硬编码配置 | 使用环境变量 | 中 |
| 未设置重启策略 | 添加restart: unless-stopped配置 | 中 |
yaml
undefinedBAD: Minimal compose
不良示例:极简配置
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
db:
image: postgres
environment:
POSTGRES_PASSWORD: password123
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:
undefinedversion: '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:
undefinedResponse Template
响应模板
undefinedundefinedDocker Review Results
Docker审查结果
Project: [name]
Base Image: node:20-alpine
Build: Multi-stage | Compose: v3.8
项目: [name]
基础镜像: node:20-alpine
构建方式: 多阶段构建 | Compose版本: v3.8
Image Optimization
镜像优化
| Status | File | Issue |
|---|---|---|
| HIGH | Dockerfile | Using node:latest (~1GB) |
| 状态 | 文件 | 问题 |
|---|---|---|
| 高 | Dockerfile | 使用node:latest(约1GB) |
Layer Caching
镜像层缓存
| Status | File | Issue |
|---|---|---|
| HIGH | Dockerfile:5 | COPY . before npm install |
| 状态 | 文件 | 问题 |
|---|---|---|
| 高 | Dockerfile:5 | 在npm install前复制了全部文件 |
Security
安全配置
| Status | File | Issue |
|---|---|---|
| CRITICAL | Dockerfile | Running as root user |
| 状态 | 文件 | 问题 |
|---|---|---|
| 严重 | Dockerfile | 以root用户运行 |
Compose
Compose配置
| Status | File | Issue |
|---|---|---|
| HIGH | docker-compose.yml | No resource limits |
| 状态 | 文件 | 问题 |
|---|---|---|
| 高 | docker-compose.yml | 未设置资源限制 |
Recommended Actions
建议操作
- Switch to node:20-alpine base image
- Add multi-stage build
- Add USER directive for non-root
- Add resource limits in compose
undefined- 切换为node:20-alpine基础镜像
- 添加多阶段构建
- 添加USER指令使用非root用户
- 在Compose中添加资源限制
undefinedBest Practices
最佳实践
- Base Image: Use alpine/slim/distroless
- Multi-stage: Separate build and runtime
- Caching: Order by change frequency
- Security: Non-root, pinned versions, no secrets
- Compose: Health checks, resource limits
- 基础镜像:使用alpine/slim/distroless镜像
- 多阶段构建:分离构建阶段与运行阶段
- 缓存策略:按变更频率排序文件复制顺序
- 安全配置:使用非root用户、固定版本、不包含密钥
- Compose配置:添加健康检查、资源限制
Integration
集成工具
- : Kubernetes deployments
k8s-reviewer - : Container security
security-scanner - : Build pipelines
ci-cd-reviewer
- :Kubernetes部署配置审查
k8s-reviewer - :容器安全扫描
security-scanner - :构建流水线审查
ci-cd-reviewer