重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
deployment by mgd34msu/goodvibes-plugin
npx skills add https://github.com/mgd34msu/goodvibes-plugin --skill deploymentscripts/
validate-deployment.sh
references/
deployment-platforms.md
此技能指导您使用现代平台和工具将应用程序部署到生产环境。在部署 Next.js、全栈应用、容器化服务或无服务器函数时,可使用此工作流。
根据您的应用程序需求选择合适的平台:
何时使用:
设置:
# 安装 Vercel CLI
npm install -g vercel
# 部署
vercel --prod
环境变量:
# 设置生产环境密钥
vercel env add DATABASE_URL production
vercel env add NEXTAUTH_SECRET production
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
何时使用:
设置:
# 安装 Railway CLI
npm install -g @railway/cli
# 登录并部署
railway login
railway up
railway.json:
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS",
"buildCommand": "npm run build"
},
"deploy": {
"startCommand": "npm start",
"healthcheckPath": "/api/health",
"healthcheckTimeout": 100,
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 3
}
}
何时使用:
设置:
# 安装 Fly CLI
curl -L https://fly.io/install.sh | sh
# 初始化并部署
fly launch
fly deploy
fly.toml:
app = "my-app"
primary_region = "sjc"
[build]
dockerfile = "Dockerfile"
[env]
PORT = "8080"
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
timeout = "5s"
path = "/api/health"
[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 256
何时使用:
有关 Dockerfile 示例,请参阅 references/deployment-platforms.md。
何时使用:
服务:
切勿将密钥提交到 git。始终使用 .env.example 进行文档记录:
.env.example:
# 数据库
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
# 身份验证
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="generate-with-openssl-rand-base64-32"
# 外部 API
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
# 功能开关
NEXT_PUBLIC_ENABLE_ANALYTICS="false"
在构建时验证环境变量以快速失败:
src/env.mjs:
import { z } from 'zod';
const server = z.object({
DATABASE_URL: z.string().url(),
NEXTAUTH_SECRET: z.string().min(32),
STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
});
const client = z.object({
NEXT_PUBLIC_APP_URL: z.string().url(),
});
const processEnv = {
DATABASE_URL: process.env.DATABASE_URL,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
};
const merged = server.merge(client);
const parsed = merged.safeParse(processEnv);
if (!parsed.success) {
console.error('[FAIL] Invalid environment variables:', parsed.error.flatten().fieldErrors);
throw new Error('Invalid environment variables');
}
export const env = parsed.data;
在应用程序顶部导入以在启动时验证:
import { env } from './env.mjs';
// 使用经过类型化、验证的环境变量
const db = new PrismaClient({
datasources: { db: { url: env.DATABASE_URL } },
});
创建 .github/workflows/deploy.yml:
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
build:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
SKIP_ENV_VALIDATION: true
deploy:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
通过适当的缓存加速 CI/CD:
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-nextjs-
创建优化的生产环境 Dockerfile:
Dockerfile(Next.js):
FROM node:20-alpine AS base
# 仅在需要时安装依赖项
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
# 仅在需要时重新构建源代码
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
# 生产环境镜像,复制所有文件并运行 next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# 为预渲染缓存设置正确的权限
RUN mkdir .next
RUN chown nextjs:nodejs .next
# 自动利用输出跟踪来减小镜像大小
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
next.config.js:
module.exports = {
output: 'standalone', // Docker 必需
};
从 Docker 构建中排除不必要的文件:
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
.gitignore
.env*.local
.vscode
.idea
dist
build
coverage
*.md
!README.md
# 构建镜像
docker build -t my-app .
# 使用环境变量运行
docker run -p 3000:3000 \
-e DATABASE_URL="postgresql://..." \
-e NEXTAUTH_SECRET="..." \
my-app
为监控创建健康检查端点:
app/api/health/route.ts:
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function GET() {
try {
// 检查数据库连接
await prisma.$queryRaw`SELECT 1`;
return NextResponse.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
database: 'connected',
});
} catch (error) {
return NextResponse.json(
{
status: 'unhealthy',
timestamp: new Date().toISOString(),
database: 'disconnected',
error: error instanceof Error ? error.message : 'Unknown error',
},
{ status: 503 }
);
}
}
向 Dockerfile 添加健康检查:
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
Vercel 和 Railway 会自动为拉取请求创建预览部署。
Railway 的 GitHub Actions:
on:
pull_request:
branches: [main]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Railway (PR)
uses: bervProject/railway-deploy@main
with:
railway_token: ${{ secrets.RAILWAY_TOKEN }}
service: ${{ secrets.RAILWAY_SERVICE }}
- name: Comment PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '[DEPLOY] Preview deployed to: https://pr-${{ github.event.number }}.myapp.com'
})
# 列出部署
vercel ls
# 将之前的部署提升到生产环境
vercel promote <deployment-url>
将新版本与旧版本一起部署,然后切换流量:
# 部署新版本(绿色)
fly deploy --strategy bluegreen
# 健康检查通过后自动切换流量
# 如果需要回滚:
fly releases rollback
逐步将流量切换到新版本:
Fly.io 金丝雀:
# 部署金丝雀(10% 流量)
fly deploy --strategy canary
# 如果成功,提升到 100%
fly releases promote
npm install @sentry/nextjs
sentry.client.config.ts:
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
environment: process.env.NODE_ENV,
enabled: process.env.NODE_ENV === 'production',
});
sentry.server.config.ts:
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
environment: process.env.NODE_ENV,
});
使用外部服务监控可用性:
每 1-5 分钟监控一次您的 /api/health 端点。
Vercel:
Railway:
自托管:
# 使用 Docker 日志驱动
docker run --log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-app
在部署前运行迁移:
GitHub Actions:
- name: Run migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Railway: 添加到 railway.json:
{
"deploy": {
"startCommand": "npx prisma migrate deploy && npm start"
}
}
切勿自动运行破坏性迁移:
首先进行向后兼容的迁移
生产环境需要手动批准
使用 precision_exec 运行带有期望的部署命令:
precision_exec:
commands:
- cmd: "npm run build"
expect:
exit_code: 0
- cmd: "docker build -t my-app ."
expect:
exit_code: 0
- cmd: "npm run typecheck"
expect:
exit_code: 0
verbosity: minimal
验证部署健康状况:
precision_fetch:
requests:
- url: "https://my-app.com/api/health"
method: GET
expect:
status: 200
body_contains: '"status":"healthy"'
在部署前,检查缺失的配置:
discover:
queries:
- id: env_example
type: glob
patterns: [".env.example"]
- id: dockerfile
type: glob
patterns: ["Dockerfile", "docker-compose.yml"]
- id: ci_config
type: glob
patterns: [".github/workflows/*.yml"]
- id: health_check
type: grep
pattern: '/api/health|/health'
glob: "**/*.{ts,tsx,js,jsx}"
output_mode: count_only
运行验证脚本:
./plugins/goodvibes/skills/outcome/deployment/scripts/validate-deployment.sh /path/to/project
该脚本检查:
问题: 由于未设置环境变量导致部署失败。
解决方案: 在 .env.example 中记录所有变量,并在构建时使用 zod 进行验证。
问题: 无服务器函数耗尽了数据库连接。
解决方案: 使用连接池(PgBouncer、Prisma Accelerate、Supabase pooler)。
// 在无服务器环境中使用连接池
const prisma = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL, // 使用池化连接字符串
},
},
});
问题: Docker 镜像过大,冷启动缓慢。
解决方案: 使用多阶段构建、Next.js 的独立输出、正确的 .dockerignore。
问题: Prisma 迁移在每次容器启动时都运行。
解决方案: 在 CI/CD 中将迁移步骤与应用程序启动分开。
问题: 错误的部署破坏了生产环境且无法轻松修复。
解决方案: 使用支持即时回滚的平台(Vercel、Railway、Fly.io)或保留之前的 Docker 镜像。
关键原则:
后续步骤:
validate-deployment.sh有关详细的平台配置和模板,请参阅 references/deployment-platforms.md。
每周安装数
49
仓库
GitHub 星标数
6
首次出现
2026年2月17日
安全审计
安装于
github-copilot49
codex49
kimi-cli49
gemini-cli49
opencode49
amp49
scripts/
validate-deployment.sh
references/
deployment-platforms.md
This skill guides you through deploying applications to production using modern platforms and tools. Use this workflow when deploying Next.js, full-stack apps, containerized services, or serverless functions.
Choose the right platform based on your application needs:
When to use:
Setup:
# Install Vercel CLI
npm install -g vercel
# Deploy
vercel --prod
Environment variables:
# Set production secrets
vercel env add DATABASE_URL production
vercel env add NEXTAUTH_SECRET production
When to use:
Setup:
# Install Railway CLI
npm install -g @railway/cli
# Login and deploy
railway login
railway up
railway.json:
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS",
"buildCommand": "npm run build"
},
"deploy": {
"startCommand": "npm start",
"healthcheckPath": "/api/health",
"healthcheckTimeout": 100,
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 3
}
}
When to use:
Setup:
# Install Fly CLI
curl -L https://fly.io/install.sh | sh
# Initialize and deploy
fly launch
fly deploy
fly.toml:
app = "my-app"
primary_region = "sjc"
[build]
dockerfile = "Dockerfile"
[env]
PORT = "8080"
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
timeout = "5s"
path = "/api/health"
[[vm]]
cpu_kind = "shared"
cpus = 1
memory_mb = 256
When to use:
See references/deployment-platforms.md for Dockerfile examples.
When to use:
Services:
Never commit secrets to git. Always use .env.example for documentation:
.env.example:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
# Authentication
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="generate-with-openssl-rand-base64-32"
# External APIs
STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
# Feature Flags
NEXT_PUBLIC_ENABLE_ANALYTICS="false"
Validate environment variables at build time to fail fast:
src/env.mjs:
import { z } from 'zod';
const server = z.object({
DATABASE_URL: z.string().url(),
NEXTAUTH_SECRET: z.string().min(32),
STRIPE_SECRET_KEY: z.string().startsWith('sk_'),
});
const client = z.object({
NEXT_PUBLIC_APP_URL: z.string().url(),
});
const processEnv = {
DATABASE_URL: process.env.DATABASE_URL,
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL,
};
const merged = server.merge(client);
const parsed = merged.safeParse(processEnv);
if (!parsed.success) {
console.error('[FAIL] Invalid environment variables:', parsed.error.flatten().fieldErrors);
throw new Error('Invalid environment variables');
}
export const env = parsed.data;
Import at the top of your app to validate on startup:
import { env } from './env.mjs';
// Use typed, validated env
const db = new PrismaClient({
datasources: { db: { url: env.DATABASE_URL } },
});
Create .github/workflows/deploy.yml:
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
NODE_VERSION: '20'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
build:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
SKIP_ENV_VALIDATION: true
deploy:
runs-on: ubuntu-latest
needs: [build]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
Speed up CI/CD with proper caching:
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.npm
.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-nextjs-
Create an optimized production Dockerfile:
Dockerfile (Next.js):
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
next.config.js:
module.exports = {
output: 'standalone', // Required for Docker
};
Exclude unnecessary files from the Docker build:
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
.gitignore
.env*.local
.vscode
.idea
dist
build
coverage
*.md
!README.md
# Build the image
docker build -t my-app .
# Run with environment variables
docker run -p 3000:3000 \
-e DATABASE_URL="postgresql://..." \
-e NEXTAUTH_SECRET="..." \
my-app
Create a health check endpoint for monitoring:
app/api/health/route.ts:
import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function GET() {
try {
// Check database connection
await prisma.$queryRaw`SELECT 1`;
return NextResponse.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
database: 'connected',
});
} catch (error) {
return NextResponse.json(
{
status: 'unhealthy',
timestamp: new Date().toISOString(),
database: 'disconnected',
error: error instanceof Error ? error.message : 'Unknown error',
},
{ status: 503 }
);
}
}
Add health check to Dockerfile:
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/api/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
Vercel and Railway automatically create preview deployments for pull requests.
GitHub Actions for Railway:
on:
pull_request:
branches: [main]
jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Railway (PR)
uses: bervProject/railway-deploy@main
with:
railway_token: ${{ secrets.RAILWAY_TOKEN }}
service: ${{ secrets.RAILWAY_SERVICE }}
- name: Comment PR
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '[DEPLOY] Preview deployed to: https://pr-${{ github.event.number }}.myapp.com'
})
# List deployments
vercel ls
# Promote a previous deployment to production
vercel promote <deployment-url>
Deploy new version alongside old, then switch traffic:
# Deploy new version (green)
fly deploy --strategy bluegreen
# Traffic switches automatically after health checks pass
# Rollback if needed:
fly releases rollback
Gradually shift traffic to new version:
Fly.io canary:
# Deploy canary (10% traffic)
fly deploy --strategy canary
# Promote to 100% if successful
fly releases promote
npm install @sentry/nextjs
sentry.client.config.ts:
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
environment: process.env.NODE_ENV,
enabled: process.env.NODE_ENV === 'production',
});
sentry.server.config.ts:
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
environment: process.env.NODE_ENV,
});
Use external services to monitor availability:
Monitor your /api/health endpoint every 1-5 minutes.
Vercel:
Railway:
Self-hosted:
# Use Docker logging driver
docker run --log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-app
Run migrations before deployment:
GitHub Actions:
- name: Run migrations
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Railway: Add to railway.json:
{
"deploy": {
"startCommand": "npx prisma migrate deploy && npm start"
}
}
Never run destructive migrations automatically:
Backwards compatible migrations first
Manual approval for production
Use precision_exec to run deployment commands with expectations:
precision_exec:
commands:
- cmd: "npm run build"
expect:
exit_code: 0
- cmd: "docker build -t my-app ."
expect:
exit_code: 0
- cmd: "npm run typecheck"
expect:
exit_code: 0
verbosity: minimal
Validate deployment health:
precision_fetch:
requests:
- url: "https://my-app.com/api/health"
method: GET
expect:
status: 200
body_contains: '"status":"healthy"'
Before deploying, check for missing configuration:
discover:
queries:
- id: env_example
type: glob
patterns: [".env.example"]
- id: dockerfile
type: glob
patterns: ["Dockerfile", "docker-compose.yml"]
- id: ci_config
type: glob
patterns: [".github/workflows/*.yml"]
- id: health_check
type: grep
pattern: '/api/health|/health'
glob: "**/*.{ts,tsx,js,jsx}"
output_mode: count_only
Run the validation script:
./plugins/goodvibes/skills/outcome/deployment/scripts/validate-deployment.sh /path/to/project
The script checks:
Problem: Deployment fails because environment variables aren't set.
Solution: Document all variables in .env.example and validate at build time with zod.
Problem: Serverless functions exhaust database connections.
Solution: Use connection pooling (PgBouncer, Prisma Accelerate, Supabase pooler).
// Use connection pooler in serverless
const prisma = new PrismaClient({
datasources: {
db: {
url: process.env.DATABASE_URL, // Use pooled connection string
},
},
});
Problem: Large Docker images, slow cold starts.
Solution: Use multi-stage builds, standalone output for Next.js, proper .dockerignore.
Problem: Prisma migrations run on every container start.
Solution: Separate migration step from app startup in CI/CD.
Problem: Bad deployment breaks production with no easy fix.
Solution: Use platforms with instant rollback (Vercel, Railway, Fly.io) or maintain previous Docker images.
Key Principles:
Next Steps:
validate-deployment.sh on your projectFor detailed platform configurations and templates, see references/deployment-platforms.md.
Weekly Installs
49
Repository
GitHub Stars
6
First Seen
Feb 17, 2026
Security Audits
Gen Agent Trust HubFailSocketFailSnykPass
Installed on
github-copilot49
codex49
kimi-cli49
gemini-cli49
opencode49
amp49
蓝绿部署(Blue-Green Deployment)完整指南:实现零停机发布与快速回滚
151 周安装
投资组合分析器 - AI金融分析工具,审查风险、资产配置、税损收割与再平衡策略
189 周安装
.NET 项目结构与构建配置指南:slnx迁移、Directory.Build.props与集中式包管理
187 周安装
XCUITest 自动化测试指南:编写可靠、可维护的 iOS UI 测试
189 周安装
CloudKit 参考指南:SwiftData、CKSyncEngine 与原始 API 结构化数据同步
188 周安装
Seedance提示词设计器:AI视频生成提示词优化工具,多模态素材智能整合
186 周安装
PM Architect:AI驱动的项目管理协调器,智能协调待办事项、工作委派与路线图规划
188 周安装