Loading...
Loading...
Good DevOps practices mean your app gets deployed reliably, automatically, and with no surprises. It's the difference between "it works on my machine" and "it works everywhere."
# Dockerfile
FROM node:20-alpine AS base
# Install dependencies
FROM base AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
# Build
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]# docker-compose.yml
services:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://user:pass@db:5432/mydb
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install & Build
run: |
npm ci
npm run build
- name: Run Tests
run: npm test
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
vercel-args: '--prod'# .env.example (commit this)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
NEXTAUTH_SECRET=your-secret-here
OPENAI_API_KEY=sk-...
# .env.local (never commit)
DATABASE_URL=postgresql://real-user:real-pass@prod-host:5432/prod-dbAdd a health check endpoint so load balancers know your app is ready:
// app/api/health/route.ts
export async function GET() {
return Response.json({ status: 'ok', timestamp: new Date().toISOString() })
}A solid DevOps setup pays dividends from day one. Start with Docker for consistent environments, add GitHub Actions for automated deployments, and your team will ship faster with fewer production incidents.