mcpField
D
docker-ops

docker-ops

github.com/0xdarkmatter云与 DevOps7845 次安装2 周前更新
代码仓库

关于 docker-ops

docker-ops 是面向容器化应用开发者的 Docker 运维技能,涵盖镜像构建、Compose、缓存与安全实践。

主要功能

  1. 01Dockerfile 最佳实践
  2. 02多阶段构建指南
  3. 03优化镜像层缓存
  4. 04Compose 服务模式
  5. 05容器安全建议
  6. 06排查常见问题

适用场景

  1. 01设计生产环境 Dockerfile
  2. 02缩减镜像体积与构建时间
  3. 03编排服务与网络
  4. 04检查容器安全设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/0xdarkmatter/claude-mods --skill docker-ops

安装后在 Claude Code 中输入/docker-ops确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
.gitkeep
references/
compose-patterns.md
multi-stage-builds.md
optimization.md
scripts/
.gitkeep

详细介绍

Docker 操作

构建、运行和编排容器化应用的全面 Docker 模式。

Dockerfile 最佳实践

实践应该做不应该做
基础镜像FROM node:20-slimFROM node:latest
层缓存先复制依赖文件,再复制源代码在 RUN install 之前执行 COPY . .
安装软件包apt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/*为更新和安装分别使用独立的 RUN
用户USER nonroot(如有需要则创建)在生产环境中以 root 身份运行
多阶段构建将构建阶段与运行阶段分开将编译器工具链打包进去
密钥--mount=type=secret(BuildKit)COPY .env . 或 ARG PASSWORD
ENTRYPOINT 与 CMD固定二进制文件使用 ENTRYPOINT,默认值使用 CMD依赖 shell 形式处理信号
WORKDIRWORKDIR /appRUN cd /app && ...
.dockerignore包含 .git、node_modules、__pycache__完全不使用 .dockerignore
标签LABEL org.opencontainers.image.*不添加元数据

多阶段构建决策树

按语言选择运行时基础镜像:

Go ──────────── CGO disabled? ──── Yes ──► scratch or distroless/static
                                   No ───► distroless/base or alpine

Rust ─────────── Static musl? ──── Yes ──► scratch or distroless/static
                                   No ───► distroless/cc or debian-slim

Node.js ──────── Need native? ──── Yes ──► node:20-slim
                                   No ───► node:20-alpine (smaller)

Python ────────── Need C libs? ─── Yes ──► python:3.12-slim
                                   No ───► python:3.12-slim (still slim)

Java ──────────── JRE only ──────────────► eclipse-temurin:21-jre-alpine

参见: references/multi-stage-builds.md,了解各语言完整的注释示例。

层缓存规则

Docker 会缓存每一层。第 N 层缓存未命中时,之后的所有层都会失效。

哪些情况会使缓存失效
触发条件效果
COPY/ADD 中的文件发生更改使此层及之后的所有层失效
RUN 命令文本发生更改使此层及之后的所有层失效
ARG 值发生更改从 ARG 声明所在层开始使后续层失效
--no-cache 标志使所有内容失效
基础镜像更新使所有内容失效
最佳层顺序
# 1. Base image (changes rarely)
FROM python:3.12-slim

# 2. System dependencies (changes rarely)
RUN apt-get update && apt-get install -y --no-install-recommends \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

# 3. Dependency files (changes occasionally)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 4. Application code (changes frequently)
COPY src/ ./src/

# 5. Runtime config (changes frequently)
CMD ["python", "-m", "app"]

经验法则: 按更改频率从低到高排列各层。

.dockerignore 要点

# Version control
.git
.gitignore

# Dependencies (rebuilt in container)
node_modules
__pycache__
*.pyc
.venv
vendor/

# Build artifacts
dist/
build/
target/
*.egg-info

# IDE and editor
.vscode
.idea
*.swp
*.swo

# Docker files (prevent recursive context)
Dockerfile*
docker-compose*
.dockerignore

# Environment and secrets
.env
.env.*
*.pem
*.key

# Documentation and tests (unless needed)
docs/
tests/
*.md
LICENSE

重要原因: 如果没有 .dockerignore,docker build 会将整个上下文目录发送给守护进程。仅 .git 文件夹就可能增加数百 MB。

Docker Compose 快速参考

服务定义
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
      target: production        # Multi-stage target
    image: myapp:latest
    ports:
      - "8080:8000"
    environment:
      DATABASE_URL: postgres://db:5432/app
    env_file:
      - .env
    volumes:
      - ./src:/app/src          # Bind mount (dev)
      - app-data:/app/data      # Named volume (persistent)
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    restart: unless-stopped
    networks:
      - backend
卷和网络
volumes:
  app-data:           # Named volume (Docker-managed)
  db-data:
    driver: local

networks:
  backend:
    driver: bridge
  frontend:
    driver: bridge

参见: references/compose-patterns.md,了解包括配置文件、监视模式和覆盖文件在内的完整模式。

PHP/CMS 项目中有 .ddev/ 文件夹? DDEV 会生成自己的 compose 文件;不要 手动编写并行的技术栈。请使用 ddev-ops(额外服务放在 .ddev/docker-compose.<name>.yaml 中,其中的 Compose 语法属于本技能)。

安全快速参考

领域建议
用户以非 root 身份运行:RUN adduser -D appuser && USER appuser
基础镜像固定摘要:FROM python:3.12-slim@sha256:abc123...
文件系统只读根文件系统:docker run --read-only --tmpfs /tmp
功能全部移除,仅添加所需项:--cap-drop=ALL --cap-add=NET_BIND_SERVICE
密钥BuildKit 密钥:RUN --mount=type=secret,id=key cat /run/secrets/key
扫描扫描镜像:trivy image myapp:latest 或 grype myapp:latest
不用 latest始终使用具体标签并固定版本
最小化镜像尽可能使用 distroless 或 scratch
不使用 SUIDRUN find / -perm /6000 -type f -exec chmod a-s {} +
网络后端服务使用内部网络
非 Root 用户模式
# Debian/Ubuntu-based
RUN groupadd -r appuser && useradd -r -g appuser -d /app -s /sbin/nologin appuser
COPY --chown=appuser:appuser . /app
USER appuser

# Alpine-based
RUN addgroup -S appuser && adduser -S -G appuser appuser
COPY --chown=appuser:appuser . /app
USER appuser

# Distroless (built-in nonroot user)
FROM gcr.io/distroless/static:nonroot
USER nonroot:nonroot

常见易错点

易错点问题解决方法
镜像过大将构建工具、node_modules 打包进最终镜像使用多阶段构建
缓存失效在 RUN npm install 之前执行 COPY . .先复制锁定文件,安装依赖,再复制源代码
镜像层中包含密钥COPY .env . 或 ARG SECRET=... 会将密钥写入镜像历史记录使用 --mount=type=secret 或运行时环境变量
PID 1 问题应用无法接收 SIGTERM,产生僵尸进程使用 tini 作为 init,或使用 CMD 的 exec 形式
时区容器使用 UTC设置 TZ 环境变量或安装 tzdata
DNS 缓存Alpine 的 musl DNS 问题使用 RUN apk add --no-cache libc6-compat 或切换到 slim
apt 缓存apt-get update 使用了旧镜像层的缓存始终在同一个 RUN 中组合执行 update && install
信号丢失Shell 形式(CMD npm start)会通过 /bin/sh 包装命令使用 exec 形式:CMD ["node", "server.js"]
构建上下文过大向守护进程发送数 GB 的数据添加 .dockerignore,使用 docker build --progress=plain 检查
镜像层过多每个 RUN 都会创建一个镜像层使用 && 链接相关命令
PID 1 / 信号处理修复
# Option 1: Use tini as init process
RUN apt-get update && apt-get install -y --no-install-recommends tini \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["tini", "--"]
CMD ["node", "server.js"]

# Option 2: Docker init flag (Docker 23.0+)
# docker run --init myapp

# Option 3: Node.js - handle signals in code
# process.on('SIGTERM', () => { server.close(); process.exit(0); });

必备 Docker 命令

# Build
docker build -t myapp:1.0 .
docker build -t myapp:1.0 --target production .    # Multi-stage target
docker build --no-cache -t myapp:1.0 .              # Force rebuild

# Run
docker run -d --name myapp -p 8080:8000 myapp:1.0
docker run --rm -it myapp:1.0 /bin/sh               # Interactive debug
docker run --read-only --tmpfs /tmp myapp:1.0        # Read-only root

# Inspect
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
docker history myapp:1.0                             # Layer breakdown
docker inspect myapp:1.0 | jq '.[0].Config'         # Image config

# Debug running container
docker exec -it myapp /bin/sh
docker logs -f myapp
docker stats myapp

# Cleanup
docker system prune -a --volumes                     # Remove everything unused
docker image prune -a                                # Remove unused images

参考文件

文件内容
references/multi-stage-builds.md各语言的多阶段构建模式(Go、Rust、Node、Python)
references/compose-patterns.mdCompose 服务、网络、配置组、监视、覆盖配置
references/optimization.md镜像大小、BuildKit、安全扫描、调试

在 RUN 步骤中,只能根据锁定文件安装依赖:使用 npm ci(或包管理器的冻结安装命令)和 composer install --no-dev --optimize-autoloader。各包管理器需要使用什么命令,以及为什么在镜像中运行 npm install 是个错误,可参阅 package-manager-ops。

评论

支持 Markdown