9.3 部署CI与安全加固


9.3 部署、CI 与安全加固

第三道防线把应用安全送到生产。本节四块内容:按站点形态选部署目标(把 6.3 的 preset 知识变成决策)、多环境配置(2.2 纪律的落地)、CI/CD 流水线(把 9.1 测试与 8.3 预算接进来)、安全四课(响应头、校验、密钥、依赖)。

部署目标:一张决策表

3.3 的 routeRules 决定"每页怎么渲染",本节决定"整个站点跑在哪":

站点形态 部署目标 Nitro preset 要点
纯静态(文档/博客) 静态托管/CDN generate 产物 零服务器成本,全球分发
动态 SSR 为主 Node 服务器/容器 node-server 自管运维,可控性最高
混合渲染 + 弹性需求 Vercel/Netlify 类 vercel/netlify 平台托管函数,预览环境佳
全球低延迟轻逻辑 边缘网络 cloudflare 6.3 的边缘约束清单过一遍

决策依据回看 1.2 与 6.3:内容变化频率、流量模式、团队运维能力、预算。没有银弹目标,只有匹配——纯静态站硬上 Node 服务器是浪费,重数据库的 SSR 站硬塞边缘是自虐。

容器化是最通用的形态(不锁云厂商):

# 多阶段构建:产物小、攻击面小 FROM node:20-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine WORKDIR /app COPY --from=build /app/.output ./.output EXPOSE 3000 CMD ["node", ".output/server/index.mjs"]

产物镜像不含源码与 node_modules 全量(Nitro 产物自带裁剪后的依赖),体积通常在一百 MB 内。

图 9-1:从代码到生产的流水线

图 9-1:从代码到生产的流水线

流水线配置示例(GitHub Actions 语法,其他平台等价):

name: ci on: [push] jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm audit --audit-level=high # 第四课:依赖审计 - run: npx vitest run # 单测 - run: npm run build # 构建 - run: npx playwright test # E2E 对产物 - name: 性能预算 run: npx lighthouse http://localhost:3000 --chrome-flags="--headless" | node scripts/check-budget.mjs # 8.3 的预算脚本

多环境:一份产物,三种配置

2.2 的纪律在此兑现:构建一次,环境变量区分 dev/staging/prod:

# 预发:连预发数据库,开详细日志 NUXT_PUBLIC_API_BASE=https://api.staging.example.com NUXT_DB_PASSWORD=staging-pass node .output/server/index.mjs # 生产:正式数据库,精简日志 NUXT_PUBLIC_API_BASE=https://api.example.com NUXT_DB_PASSWORD=prod-pass

健康检查端点是运维接口,一行代码:

// server/api/health.get.ts:负载均衡与平台的存活探测 export default defineEventHandler(() => ({ status: 'ok', uptime: process.uptime(), version: useRuntimeConfig().public.version, }))

安全四课的代码位

第一课,响应头。Nitro 路由规则统一注入:

export default defineNuxtConfig({ nitro: { routeRules: { '/**': { headers: { 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'Referrer-Policy': 'strict-origin-when-cross-origin', }, }, }, }, })

内容安全策略(CSP)从严起步:先 report-only 观察违规,再逐步收紧 default-src——一上来就严策略会白屏一片。

第二课,服务端校验。前端校验是体验,服务端校验是边界:

// server/api/orders.post.ts:每个字段显式校验类型与范围 const body = await readBody(event) if (typeof body.productId !== 'number' || body.productId <= 0) { throw createError({ statusCode: 400, statusMessage: 'productId 非法' }) } if (typeof body.quantity !== 'number' || body.quantity < 1 || body.quantity > 99) { throw createError({ statusCode: 400, statusMessage: 'quantity 越界' }) }

第三课,密钥复查。发布前在产物里搜密钥(2.2 的自查法),并确认 cookie 的 httpOnly、secure 属性到位。

第四课,依赖审计。流水线卡 high 级漏洞,紧急漏洞走应急分支——安全债的利息比功能债高。

⚠️ 常见坑:环境变量写进 docker 镜像。镜像会进仓库、被人拉取,等于密钥公开。密钥只在运行时注入(编排层的环境变量配置),镜像保持无密。

💡 关键直觉:CI/CD 的本质是"把每次发布要做对的一百件事变成只需要做对一次的配置"——关卡设在流水线里,人的失误被机器的重复性兜住。

本节要点回顾

  • 目标决策表:静态站上 CDN、动态站 Node 容器、弹性需求平台托管、轻逻辑走边缘——匹配而非追新;
  • 容器化:多阶段构建,产物镜像百 MB 内且不含源码;
  • 流水线五关:安装审计、双层测试、构建预算、预发验证、人工确认发布;
  • 多环境:一份产物加 NUXT_ 环境变量;健康检查端点一行;
  • 安全四课:响应头统一注入、服务端显式校验、密钥产物复查、依赖审计进关卡。

作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U