Skip to main content

Deployment Options Overview

Thalyson’s Portfolio is a Next.js application that can be deployed to various platforms. This guide covers multiple deployment strategies, from the recommended Vercel deployment to self-hosted options.
Recommended: Deploy to Vercel for the best Next.js experience with zero configuration, automatic HTTPS, and global CDN.

Platform Comparison

PlatformBest ForDifficultyNext.js Support
VercelProduction appsEasyExcellent
NetlifyStatic sitesEasyGood
AWS AmplifyAWS ecosystemMediumGood
DockerSelf-hostedAdvancedExcellent
VPS/CloudFull controlAdvancedExcellent
Vercel is the company behind Next.js and provides the best deployment experience with zero configuration.

Prerequisites

  • GitHub/GitLab/Bitbucket account with your repository
  • Vercel account (free tier available)
  • Project built successfully locally (npm run build)

Step-by-Step Vercel Deployment

1

Create Vercel Account

Visit vercel.com and sign up with your GitHub, GitLab, or Bitbucket account.
2

Import Repository

  1. Click “Add New Project”
  2. Select “Import Git Repository”
  3. Choose your portfolio repository
  4. Grant Vercel access if prompted
Vercel automatically detects Next.js projects and configures build settings.
3

Configure Project Settings

Vercel auto-detects the following from package.json:5-11:
  • Framework Preset: Next.js
  • Build Command: npm run build
  • Output Directory: .next (automatic)
  • Install Command: npm install
  • Development Command: npm run dev
You typically don’t need to change these settings.
4

Configure Environment Variables

If your project uses environment variables, add them in the Vercel dashboard:
  1. Go to Project Settings → Environment Variables
  2. Add each variable:
    • Key: NEXT_PUBLIC_API_URL
    • Value: https://api.example.com
    • Environment: Production, Preview, Development
Remember: Only variables prefixed with NEXT_PUBLIC_ are exposed to the browser. Server-side variables should not have this prefix.
5

Deploy

Click “Deploy” and wait for the build to complete (usually 1-3 minutes).Vercel will:
  • Install dependencies
  • Run npm run build
  • Deploy to global CDN
  • Generate a unique preview URL
6

Verify Deployment

Once deployed, Vercel provides:
  • Production URL: your-project.vercel.app
  • Deployment logs: Full build and runtime logs
  • Performance insights: Core Web Vitals
  • Preview deployments: For every branch/PR

Environment Variables Configuration

# Available in browser (prefix with NEXT_PUBLIC_)
NEXT_PUBLIC_API_URL=https://api.example.com
NEXT_PUBLIC_SITE_URL=https://thalyson.dev
NEXT_PUBLIC_ANALYTICS_ID=UA-XXXXXXXXX
1

Navigate to Settings

Go to your project dashboard → Settings → Environment Variables
2

Add Variables

  • Enter variable name (e.g., NEXT_PUBLIC_API_URL)
  • Enter value
  • Select environments: Production, Preview, Development
3

Redeploy

After adding variables, trigger a new deployment:
git commit --allow-empty -m "Trigger deployment"
git push
Or click “Redeploy” in the Vercel dashboard.

Custom Domain Setup

1

Add Domain in Vercel

  1. Go to Project Settings → Domains
  2. Enter your domain (e.g., thalyson.dev)
  3. Click “Add”
2

Configure DNS Records

Add these records to your domain registrar:For apex domain (thalyson.dev):
Type: A
Name: @
Value: 76.76.21.21
For www subdomain (www.thalyson.dev):
Type: CNAME
Name: www
Value: cname.vercel-dns.com
3

Wait for DNS Propagation

DNS changes can take 24-48 hours to propagate. Vercel automatically provisions SSL certificates once DNS is configured.
4

Verify HTTPS

Once configured, your site is automatically available via HTTPS with auto-renewing certificates.
Vercel automatically redirects HTTP to HTTPS and handles SSL certificate renewal.

Preview Deployments

Vercel creates automatic preview deployments for:
  • Every commit: Pushed to any branch
  • Every pull request: With unique URL
  • Every branch: Continuous deployment
Preview deployments are perfect for:
  • Testing changes before merging
  • Sharing work with team/clients
  • Running end-to-end tests
  • QA and review processes
Preview URL format: your-project-git-branch-name.vercel.app

Alternative Deployment Platforms

Netlify Deployment

Netlify is another popular platform for deploying Next.js applications.
1

Install Netlify CLI

npm install -g netlify-cli
2

Configure Build Settings

Create netlify.toml in your project root:
[build]
  command = "npm run build"
  publish = ".next"

[[plugins]]
  package = "@netlify/plugin-nextjs"
3

Deploy

netlify login
netlify init
netlify deploy --prod
Netlify’s Next.js support is good but not as comprehensive as Vercel. Some Next.js features may require additional configuration.

AWS Amplify Deployment

Deploy to AWS Amplify for integration with AWS services.
1

Install Amplify CLI

npm install -g @aws-amplify/cli
amplify configure
2

Initialize Amplify

amplify init
amplify add hosting
3

Configure Build Settings

Create amplify.yml:
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm install
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
4

Deploy

amplify push
amplify publish

Docker Deployment

For containerized deployments, use Docker with the official Next.js example.
1

Create Dockerfile

Create Dockerfile in project root:
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 ./
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 . .

# Set environment variables for build
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

# 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

CMD ["node", "server.js"]
2

Update next.config.ts

Enable standalone output mode in next.config.ts:
const nextConfig = {
  output: 'standalone',
  // ... rest of your config
}
3

Build and Run

# Build Docker image
docker build -t thalyson-portfolio .

# Run container
docker run -p 3000:3000 thalyson-portfolio
4

Docker Compose (Optional)

Create docker-compose.yml:
version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
    restart: unless-stopped
Run with:
docker-compose up -d

Self-Hosted (VPS/Cloud) Deployment

Deploy to your own server with PM2 or systemd.
1

Prepare Server

Install Node.js 20+ on your server:
# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
2

Clone and Build

git clone https://github.com/yourusername/portfolio.git
cd portfolio
npm install
npm run build
3

Install PM2

npm install -g pm2
4

Create PM2 Ecosystem File

Create ecosystem.config.js:
module.exports = {
  apps: [{
    name: 'thalyson-portfolio',
    script: 'npm',
    args: 'start',
    cwd: '/path/to/portfolio',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    }
  }]
}
5

Start with PM2

pm2 start ecosystem.config.js
pm2 save
pm2 startup
6

Configure Nginx Reverse Proxy

Create /etc/nginx/sites-available/portfolio:
server {
    listen 80;
    server_name thalyson.dev www.thalyson.dev;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
Enable and restart:
sudo ln -s /etc/nginx/sites-available/portfolio /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
7

Setup SSL with Let's Encrypt

sudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx -d thalyson.dev -d www.thalyson.dev

Environment Variables for Production

Required Variables

Depending on your features, you may need:
NEXT_PUBLIC_API_URL=https://api.thalyson.dev
API_SECRET_KEY=your-secret-key
Security Best Practices:
  • Never commit .env files to Git
  • Use different values for development and production
  • Rotate secrets regularly
  • Use platform-specific secret management when possible

Performance Monitoring

Vercel Analytics

Vercel provides built-in analytics:
npm install @vercel/analytics
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  )
}

Core Web Vitals Monitoring

Track Core Web Vitals in production:
// app/layout.tsx
import { SpeedInsights } from '@vercel/speed-insights/next'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <SpeedInsights />
      </body>
    </html>
  )
}
This tracks:
  • LCP (Largest Contentful Paint)
  • FID (First Input Delay)
  • CLS (Cumulative Layout Shift)
  • FCP (First Contentful Paint)
  • TTFB (Time to First Byte)

Third-Party Monitoring

// Install Sentry
npm install @sentry/nextjs

// Initialize in app/layout.tsx
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  environment: process.env.VERCEL_ENV || 'development',
  tracesSampleRate: 1.0,
})

Post-Deployment Checklist

After deploying, verify everything works:
1

Functional Testing

  • All pages load correctly
  • Navigation works across all routes
  • Forms submit successfully
  • Images load and are optimized
  • Links work (internal and external)
  • Contact form sends emails
2

Performance Testing

  • Run Lighthouse audit (target: 90+ scores)
  • Check Core Web Vitals
  • Verify image optimization (WebP/AVIF served)
  • Test mobile performance
  • Check First Contentful Paint < 1.8s
  • Verify Time to Interactive < 3.8s
3

SEO Verification

  • Meta tags are correct
  • Open Graph images display
  • Sitemap is accessible (/sitemap.xml)
  • Robots.txt is configured
  • Structured data is valid
  • Social media cards render correctly
4

Security Checks

  • HTTPS is enforced
  • Security headers are set
  • No sensitive data exposed
  • API keys are in environment variables
  • CORS is properly configured
  • Rate limiting is in place
5

Monitoring Setup

  • Analytics tracking works
  • Error tracking is configured
  • Performance monitoring active
  • Uptime monitoring enabled
  • Alert notifications configured

Continuous Deployment Setup

Automated Deployments

With Vercel, deployments are automatic:
  1. Push to Git: Every push triggers a build
  2. Pull Requests: Get preview deployments
  3. Main Branch: Automatically deploys to production

GitHub Actions (Alternative CI/CD)

Create .github/workflows/deploy.yml:
name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run linter
        run: npm run lint
      
      - name: Build project
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
      
      - 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'

Rollback Procedures

Vercel Rollback

1

Access Deployments

Go to your project dashboard → Deployments
2

Find Previous Deployment

Locate the last known good deployment
3

Promote to Production

Click the three dots → Promote to Production
Rollbacks are instant on Vercel. Your site reverts to the selected deployment immediately.

Manual Rollback

For self-hosted deployments:
# Git-based rollback
git revert <commit-hash>
git push origin main

# Or reset to previous commit
git reset --hard <previous-commit>
git push -f origin main

# Then rebuild and deploy
npm run build
pm2 restart thalyson-portfolio
Always test rollbacks in a staging environment first. Keep detailed deployment logs for troubleshooting.

Troubleshooting Common Deployment Issues

Possible causes:
  • Environment variables not set
  • Different Node.js versions
  • Missing dependencies
Solutions:
# Match production Node version locally
nvm install 20
nvm use 20

# Clear cache and rebuild
rm -rf .next node_modules
npm install
npm run build
Cause: Remote image domains not configuredSolution: Verify next.config.ts:9-16 includes all image domains:
images: {
  remotePatterns: [
    {
      protocol: "https",
      hostname: "res.cloudinary.com"
    },
    // Add other domains here
  ]
}
Cause: Routes not properly configuredSolution: Ensure API routes are in app/api/ directory and properly exported
Cause: Variables not set in deployment platformSolution:
  1. Add variables in platform dashboard
  2. Redeploy after adding variables
  3. Verify variable names match exactly (case-sensitive)

Next Steps

After successful deployment:
  1. Monitor Performance: Set up analytics and error tracking
  2. SEO Optimization: Submit sitemap to Google Search Console
  3. Social Media: Test Open Graph cards on social platforms
  4. CDN: Verify global CDN distribution
  5. Backups: Set up automated backups if self-hosted
  6. Documentation: Keep deployment docs updated
Join the Vercel Discord or Next.js GitHub Discussions for community support.

Build docs developers (and LLMs) love