---
name: ci-cd-rules
description: "DevOps 容器构建与 CI/CD 流水线部署规范。适用于所有项目 Dockerfile 编写、镜像打包与 CI 自动化配置。"
globs: ["**/Dockerfile", "**/docker-compose.yml", ".github/workflows/*.yml", "**/gitlab-ci.yml", "Dockerfile"]
alwaysApply: false
updated: 2026-05-22
---

# DevOps 容器构建与 CI/CD 流水线部署规范

> [!IMPORTANT]
> 容器的体积与权限边界直接决定了云原生环境下的安全防御等级与部署时效。AI 助手在设计容器构建方案或 CI 门禁流程时，必须严格限制镜像特权、减小包体积并确立硬性流水线质量关卡。

## 1. 适用场景

当您编写或优化项目 `Dockerfile`、定义 Kubernetes 部署模版，或设计 GitHub Actions / GitLab CI 自动化发布流水线时生效。

## 2. 操作规则

1. **容器多阶段构建 (Multi-Stage Builds)**：
   - 编写 `Dockerfile` 时，必须强制采用 **多阶段构建（Multi-stage builds）** 机制。
   - 仅在第一编译构建阶段包含 SDK 和依赖安装包，在最终运行阶段只拷贝编译产物，以此将最终产物镜像控制在最小体积（通常低于 100MB），减少部署拉取网络开销。
2. **容器非特权运行安全边界 (Non-Root User Enforcement)**：
   - 生产运行环境**绝对禁止**以 root 特权用户身份执行应用进程。
   - 必须在 Dockerfile 最后的运行阶段创建非特权安全组和用户，并通过 **`USER app`** 指令进行非特权运行切换；Debian/Ubuntu 基础镜像通常使用 `groupadd/useradd`，Alpine 基础镜像通常使用 `addgroup/adduser`，命令必须与基础镜像匹配。
3. **流水线硬性测试门禁 (CI Pipeline Gatekeeping)**：
   - 任何合并到主干分支（如 `main`/`master`）的 PR，其 CI 流水线必须强行跑通三项指标：
     - 所有单元测试 100% 通过，且**测试覆盖率必须满足硬性达标线（如 >= 80%）**。
     - 代码格式及 Lint（如 ESLint / Ruff）检查无 Error 阻塞。
     - Trivy / Snyk 镜像安全扫描无致命（Critical/High）安全漏洞，不通过则自动熔断流水线。

## 3. 禁止事项

- 严禁在 Docker 容器镜像的任何一层写入明文的数据库密码、SSH 密钥或外部敏感配置文件。

## 4. 验证方式

- 运行 `docker build --target=production -t app-test .` 并查看最终镜像层级与体积。
- 运行 `docker run --rm app-test whoami` 校验输出是否为非特权用户 `app`。
- 如果 Dockerfile 使用 Alpine 基础镜像，应确认用户创建命令使用 `addgroup/adduser`；如果使用 Debian/Ubuntu 基础镜像，应确认使用 `groupadd/useradd` 或基础镜像已提供的非特权用户。

## 5. 代码对比示例

### ❌ 错误示例（特权 root 用户运行、大体积单阶段构建、泄漏敏感信息）

```dockerfile
# 违反规则 2.1：单阶段构建，混入了全部开发依赖包，镜像体积高达 800MB
# 违反规则 2.2：没有切换 USER 指令，容器内部默认以高危的 root 特权运行应用
# 违反规则 3.1：明文硬编码写入配置与密码
FROM node:18

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm install

COPY . .

# 违反安全规范：直接明文注入数据库凭证
ENV DATABASE_PASSWORD="super-secret-password" 

EXPOSE 3000
CMD [ "npm", "start" ]
```

###  正确方向（完美多阶段构建、精简运行层、非特权 app 用户切换）

```dockerfile
# ==========================================
# 阶段 1：依赖安装与编译构建
# ==========================================
FROM node:18-alpine AS builder

WORKDIR /usr/src/app

COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# ==========================================
# 阶段 2：轻量化安全生产运行镜像
# ==========================================
FROM node:18-alpine AS production

WORKDIR /usr/src/app

# 遵循规则 2.2：在运行镜像中建立隔离的非特权 app 组及用户
RUN addgroup -g 1001 -S app && \
    adduser -u 1001 -S app -G app

# 遵循规则 2.1：仅从构建阶段拷贝极简编译产物，彻底丢弃全部 SDK，体积缩减 90%
COPY --chown=app:app --from=builder /usr/src/app/dist ./dist
COPY --chown=app:app --from=builder /usr/src/app/node_modules ./node_modules
COPY --chown=app:app --from=builder /usr/src/app/package.json ./package.json

# 遵循规则 2.2：切换为非特权 app 用户执行进程，从系统层面封锁容器逃逸漏洞
USER app

EXPOSE 3000
ENV NODE_ENV=production

CMD [ "node", "dist/main.js" ]
```
