skills/devops/SKILL.md
Docker, CI/CD, deployment, and infrastructure patterns. Use when: writing Dockerfiles, configuring CI/CD pipelines (GitHub Actions), setting up environment variables, deploying to Vercel/AWS, managing multi-stage builds, or configuring monitoring and logging.
npx skillsauth add Awais16/skills-vault devopsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
# Stage 1: Dependencies
FROM node:20-alpine AS deps
RUN corepack enable
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# Stage 2: Build
FROM node:20-alpine AS builder
RUN corepack enable
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN pnpm build
# Stage 3: Production
FROM node:20-alpine 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
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
CMD ["node", "server.js"]
# docker-compose.yml
services:
app:
build:
context: .
target: deps
command: pnpm dev
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/myapp
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
node_modules
.next
.git
.env*.local
Dockerfile
docker-compose.yml
README.md
.github
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint-and-typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
test:
runs-on: ubuntu-latest
needs: lint-and-typecheck
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm test:run
- run: pnpm test:coverage
- uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/
e2e:
runs-on: ubuntu-latest
needs: lint-and-typecheck
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install --with-deps
- run: pnpm build
- run: pnpm test:e2e
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
build:
runs-on: ubuntu-latest
needs: [test, e2e]
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm build
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: actions/checkout@v4
- uses: amondnet/vercel-action@v25
id: deploy
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
# .env.example — committed to git (template only)
DATABASE_URL=postgresql://user:password@localhost:5432/myapp
NEXT_PUBLIC_APP_URL=http://localhost:3000
JWT_SECRET=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
# .env.local — gitignored, local development values
# .env.development — development defaults
# .env.production — production defaults (non-secret only)
// lib/env.ts
import { z } from 'zod';
const envSchema = z.object({
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32),
NEXT_PUBLIC_APP_URL: z.string().url(),
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
STRIPE_SECRET_KEY: z.string().optional(),
});
export const env = envSchema.parse(process.env);
.env.local or files with real secrets.env.example with placeholder valuesNEXT_PUBLIC_ prefix only for values safe to expose to the browser{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"typecheck": "tsc --noEmit",
"format": "prettier --write .",
"format:check": "prettier --check .",
"test": "vitest",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test",
"db:migrate": "prisma migrate dev",
"db:push": "prisma db push",
"db:seed": "prisma db seed",
"db:studio": "prisma studio",
"docker:up": "docker compose up -d",
"docker:down": "docker compose down"
}
}
// app/api/health/route.ts
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';
export async function GET() {
try {
await db.$queryRaw`SELECT 1`;
return NextResponse.json({
status: 'healthy',
timestamp: new Date().toISOString(),
version: process.env.npm_package_version ?? 'unknown',
});
} catch {
return NextResponse.json(
{ status: 'unhealthy', timestamp: new Date().toISOString() },
{ status: 503 },
);
}
}
pnpm buildtools
TypeScript best practices, advanced type patterns, and strict typing. Use when: writing TypeScript code, creating type definitions, fixing type errors, designing type-safe APIs, using generics, creating utility types, or migrating from JavaScript to TypeScript.
development
Testing strategies and patterns for TypeScript/React/Next.js. Use when: writing unit tests, integration tests, e2e tests, setting up Vitest/Jest/Playwright, testing React components, testing API routes, mocking dependencies, or establishing testing patterns.
development
Web application security best practices and OWASP patterns. Use when: implementing authentication, authorization, input validation, sanitization, CSRF/XSS prevention, securing API endpoints, managing secrets, handling file uploads, configuring CORS, or auditing code for security vulnerabilities.
development
React best practices, component patterns, hooks, and state management. Use when: building React components, managing state with Zustand or Context API, writing custom hooks, optimizing renders, handling forms, implementing accessibility, or structuring component architecture.