Deployment Guide
Deploy your portfolio to production with confidence using this comprehensive deployment guide covering Vercel, Docker, and CI/CD pipelines.
🚀 Vercel Deployment (Recommended)
Vercel offers the best experience for Next.js applications with zero configuration.
Initial Setup
- Install Vercel CLI
pnpm install -g vercel- Login to Vercel
vercel login- Link Project
vercel linkFollow the prompts to connect your project.
Deploy to Production
# Deploy to production
vercel --prod
# Deploy preview
vercelAutomatic Deployments
Connect your GitHub repository for automatic deployments:
- Go to vercel.com/dashboard
- Click "Add New Project"
- Import your GitHub repository
- Configure settings (usually auto-detected)
- Click "Deploy"
Automatic deployment triggers:
- Production: Push to
mainbranch - Preview: Pull requests and other branches
Environment Variables
Add environment variables in Vercel dashboard:
- Go to Project Settings > Environment Variables
- Add your variables:
NEXT_PUBLIC_GITHUB_TOKEN=ghp_xxxxxxxxxxxxx
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx- Select environments (Production, Preview, Development)
Build Configuration
Vercel automatically detects Next.js projects. Custom settings in vercel.json:
{
"buildCommand": "pnpm build",
"devCommand": "pnpm dev",
"installCommand": "pnpm install",
"framework": "nextjs",
"regions": ["iad1"],
"env": {
"NEXT_PUBLIC_APP_URL": "https://mohamedlakssirt.tech"
}
}Performance Optimizations
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
]
}
],
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://your-backend.com/api/:path*"
}
]
}🐳 Docker Deployment
For self-hosted or cloud deployments using Docker.
Production Dockerfile
Already included in the repository:
# Dockerfile
FROM node:20-alpine AS base
# Dependencies
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm
RUN pnpm install --frozen-lockfile
# Builder
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build
# Runner
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
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"]Building Docker Image
# Build production image
docker build -t my-portfolio:latest .
# Build with build args
docker build \
--build-arg NEXT_PUBLIC_GITHUB_TOKEN=ghp_xxx \
-t my-portfolio:latest .Running Docker Container
# Run container
docker run -d \
--name portfolio \
-p 3000:3000 \
--env-file .env.production \
--restart unless-stopped \
my-portfolio:latest
# View logs
docker logs -f portfolio
# Stop container
docker stop portfolio
# Remove container
docker rm portfolioDocker Compose Production
# docker-compose.prod.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
env_file:
- .env.production
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- app
restart: unless-stoppedDeploy with:
docker-compose -f docker-compose.prod.yml up -dDocker Wake-Up System
Smart container management for development/staging:
# Start wake-up system
./scripts/start-wake.sh
# Monitor locally
./scripts/start-wake.sh --monitorFeatures:
- Auto-starts container on first access
- Stops after 30 minutes of inactivity
- NGINX proxy shows loading page during startup
- Monitors access and manages lifecycle
Configuration: docker-compose.yml
services:
nginx-wake-proxy:
image: nginx:alpine
ports:
- "3000:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app
portfolio-app:
build: .
expose:
- "3000"
env_file:
- .env.local☁️ Cloud Providers
AWS Deployment
Using AWS Amplify
- Connect GitHub repository
- Configure build settings:
version: 1
frontend:
phases:
preBuild:
commands:
- npm install -g pnpm
- pnpm install
build:
commands:
- pnpm build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*Using ECS (Docker)
- Push image to ECR:
# Authenticate
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin xxx.dkr.ecr.us-east-1.amazonaws.com
# Tag image
docker tag my-portfolio:latest xxx.dkr.ecr.us-east-1.amazonaws.com/my-portfolio:latest
# Push
docker push xxx.dkr.ecr.us-east-1.amazonaws.com/my-portfolio:latest- Create ECS task definition
- Configure service and load balancer
DigitalOcean App Platform
- Connect GitHub repository
- Configure in dashboard:
- Build Command:
pnpm build - Run Command:
pnpm start - Environment: Node.js 20
- Build Command:
Railway
# Install Railway CLI
npm install -g @railway/cli
# Login
railway login
# Initialize
railway init
# Deploy
railway up🔄 CI/CD Pipeline
GitHub Actions
Automated testing and deployment workflow:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install pnpm
run: npm install -g pnpm
- name: Install dependencies
run: pnpm install
- name: Run linter
run: pnpm lint
- name: Run type check
run: pnpm type-check
- name: Run unit tests
run: pnpm test:unit
- name: Run E2E tests
run: pnpm test:e2e:ci
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install pnpm
run: npm install -g pnpm
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
env:
NEXT_PUBLIC_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
- 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'Deployment Checklist
Before deploying to production:
- Run full test suite:
pnpm validate - Check for security vulnerabilities:
pnpm audit - Update environment variables
- Test build locally:
pnpm build && pnpm start - Verify all API endpoints work
- Check responsive design on all devices
- Test light/dark mode switching
- Verify GitHub stats loading
- Check Core Web Vitals scores
- Review Lighthouse report
- Test in multiple browsers
- Update CHANGELOG.md
- Create git tag for release
Post-Deployment
After successful deployment:
-
Verify Deployment
- Check production URL loads correctly
- Test all major features
- Verify analytics tracking
-
Monitor Performance
- Check Vercel Analytics dashboard
- Review error logs
- Monitor Core Web Vitals
-
Update Documentation
- Document any configuration changes
- Update README if needed
- Record deployment notes
🔐 Security Best Practices
Environment Variables
- Never commit
.env.localto git - Use different tokens for dev/prod
- Rotate tokens regularly
- Use secret management services
Headers
Add security headers in next.config.ts:
const nextConfig = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
},
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
},
{
key: 'X-Content-Type-Options',
value: 'nosniff'
},
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
]
}
];
}
};SSL/TLS
- Always use HTTPS in production
- Configure automatic certificate renewal
- Use tools like Let's Encrypt for free certificates
📊 Monitoring
Vercel Analytics
Built-in analytics for:
- Core Web Vitals
- Page load times
- Error tracking
- User sessions
PostHog
Product analytics for:
- User behavior
- Feature usage
- Conversion funnels
- A/B testing
Error Tracking
Consider adding:
- Sentry for error monitoring
- LogRocket for session replay
- Datadog for infrastructure monitoring