Next.js provides multiple deployment options, and developers can choose the most suitable deployment method based on project requirements. Here are the main deployment options and best practices for Next.js:
1. Vercel (Recommended)
Vercel is the hosting platform provided by the creators of Next.js, offering the best Next.js deployment experience.
Pros
- Zero configuration deployment
- Automatic HTTPS
- Global CDN
- Edge function support
- Preview deployments
- Automatic optimization
Deployment Steps
bash# 1. Install Vercel CLI npm i -g vercel # 2. Login to Vercel vercel login # 3. Deploy vercel # 4. Production deployment vercel --prod
Configuration File
javascript// vercel.json { "buildCommand": "npm run build", "outputDirectory": ".next", "framework": "nextjs", "regions": ["iad1"], "functions": { "app/api/**/*.js": { "maxDuration": 30 } }, "headers": [ { "source": "/(.*)", "headers": [ { "key": "X-Content-Type-Options", "value": "nosniff" }, { "key": "X-Frame-Options", "value": "DENY" } ] } ] }
2. Self-Hosting (Docker)
Containerize Next.js application with Docker and deploy to any Docker-supported platform.
Dockerfile
dockerfile# Multi-stage build FROM node:18-alpine AS base # Dependencies stage FROM base AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci # Build stage FROM base AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build # Runtime stage FROM base AS runner WORKDIR /app ENV NODE_ENV production RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static USER nextjs EXPOSE 3000 ENV PORT 3000 ENV HOSTNAME "0.0.0.0" CMD ["node", "server.js"]
docker-compose.yml
yamlversion: '3.8' services: nextjs: build: . ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=${DATABASE_URL} restart: unless-stopped
Build and Run
bash# Build image docker build -t nextjs-app . # Run container docker run -p 3000:3000 nextjs-app # Use docker-compose docker-compose up -d
3. Node.js Server
Deploy Next.js application to traditional Node.js servers.
Using PM2
javascript// ecosystem.config.js module.exports = { apps: [{ name: 'nextjs-app', script: 'node_modules/next/dist/bin/next', args: 'start -p 3000', instances: 'max', exec_mode: 'cluster', env: { NODE_ENV: 'production', PORT: 3000 }, error_file: './logs/err.log', out_file: './logs/out.log', log_date_format: 'YYYY-MM-DD HH:mm:ss Z' }] };
bash# Install PM2 npm install -g pm2 # Start application pm2 start ecosystem.config.js # Check status pm2 status # View logs pm2 logs # Restart application pm2 restart nextjs-app
Using Nginx Reverse Proxy
nginxserver { listen 80; server_name example.com; 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; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
4. Static Export
For simple applications that don't need server-side functionality, export as static HTML.
Configuration
javascript// next.config.js module.exports = { output: 'export', images: { unoptimized: true } };
Build and Deploy
bash# Build npm run build # Output in out/ directory # Can deploy to any static hosting service, such as: # - GitHub Pages # - Netlify # - AWS S3 + CloudFront # - Firebase Hosting
5. Cloud Platform Deployment
AWS
Using AWS Amplify
bash# Install Amplify CLI npm install -g @aws-amplify/cli # Initialize amplify init # Add hosting amplify add hosting # Publish amplify publish
Using AWS Lambda
javascript// app/api/hello/route.js export const runtime = 'edge'; export async function GET() { return Response.json({ message: 'Hello from Edge!' }); }
Google Cloud
Using Cloud Run
bash# Build image gcloud builds submit --tag gcr.io/PROJECT_ID/nextjs-app # Deploy to Cloud Run gcloud run deploy nextjs-app \ --image gcr.io/PROJECT_ID/nextjs-app \ --platform managed \ --region us-central1 \ --allow-unauthenticated
Azure
Using Azure Static Web Apps
bash# Install Azure CLI npm install -g @azure/static-web-apps-cli # Deploy swa deploy ./out --env production
6. CI/CD Integration
GitHub Actions
yamlname: Deploy to Vercel 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: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Run tests run: npm test - name: Build run: npm run build - name: Deploy to Vercel uses: amondnet/vercel-action@v20 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} vercel-org-id: ${{ secrets.ORG_ID }} vercel-project-id: ${{ secrets.PROJECT_ID }} vercel-args: '--prod'
GitLab CI
yamlimage: node:18 stages: - test - build - deploy test: stage: test script: - npm ci - npm test build: stage: build script: - npm ci - npm run build artifacts: paths: - .next/ deploy: stage: deploy script: - npm install -g vercel - vercel --prod --token=$VERCEL_TOKEN only: - main
Environment Variable Management
.env Files
bash# .env.local (local development) DATABASE_URL=postgresql://localhost/mydb API_KEY=your_api_key # .env.production (production) DATABASE_URL=postgresql://prod-db-host/mydb API_KEY=prod_api_key
Vercel Environment Variables
bash# Use Vercel CLI vercel env add DATABASE_URL production # Or set in Vercel Dashboard
Performance Optimization
1. Enable Compression
javascript// next.config.js module.exports = { compress: true, };
2. Optimize Images
javascript// next.config.js module.exports = { images: { formats: ['image/avif', 'image/webp'], deviceSizes: [640, 750, 828, 1080, 1200, 1920], }, };
3. Enable SWC Minification
javascript// next.config.js module.exports = { swcMinify: true, };
Monitoring and Logging
Using Vercel Analytics
javascript// pages/_app.js import { Analytics } from '@vercel/analytics/react'; export default function App({ Component, pageProps }) { return ( <> <Component {...pageProps} /> <Analytics /> </> ); }
Using Sentry
javascript// sentry.client.config.js import * as Sentry from '@sentry/nextjs'; Sentry.init({ dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, tracesSampleRate: 1.0, });
Deployment Best Practices
- Use Vercel: Get the best Next.js deployment experience
- Environment variables: Use .env files to manage environment variables
- CI/CD: Set up automated deployment workflows
- Monitoring: Use monitoring tools to track application performance
- Backup: Regularly backup databases and important files
- Testing: Run complete test suite before deployment
- Progressive deployment: Use blue-green deployment or canary releases
- Documentation: Document deployment processes and configurations
By properly choosing deployment methods and following best practices, you can ensure that Next.js applications run stably and efficiently in production environments.