Self-hosting your Next.js application offers greater control over your deployment environment and can be more cost-effective than using managed hosting services. This guide walks you through the complete process of deploying a Next.js application using Nginx as a reverse proxy and PM2 as a process manager.

Self-Hosting a Next.js Application with Nginx and PM2

Nextjs
self hosting
Self-hosting your Next.js application offers greater control over your deployment environment and can be more cost-effective than using managed hosting services. This guide walks you through the complete process of deploying a Next.js application using Nginx as a reverse proxy and PM2 as a process manager.

Preparing Your Application

Before deployment, optimize your application by excluding unnecessary files and directories:
zip -r archive.zip . -x ".next/*" "node_modules/*" ".env" ".git/*
This command creates a compressed archive of your project while excluding build artifacts, dependencies, environment variables, and Git history.

Server Setup

Begin by creating and organizing your website directory:
# Create website directory
mkdir -p /var/www/example.com
cd /var/www/example.com

# Upload and extract files
unzip archive.zip
mv project-master/* .
mv project-master/.* . 2>/dev/null || true
rmdir project-master

# Set permissions
sudo chown -R www-data:www-data /var/www/example.com/public
sudo chmod -R 775 /var/www/example.com/public
These commands establish a proper directory structure and set appropriate permissions for your web server.

Nginx Configuration

Create a dedicated Nginx configuration file to handle requests to your application:
sudo nano /etc/nginx/sites-available/example.com
Add the following configuration:
# HTTP configuration - for redirection to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    
    # Directory for Let's Encrypt verification
    location /.well-known/acme-challenge/ {
        root /var/www/html;
        allow all;
    }
}

# HTTPS configuration (will be updated by Certbot automatically)
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;
    
    # Static files location
    location /uploads/ {
        alias /var/www/example.com/public/uploads/;
        autoindex on;
        expires max;
    }
    
    # Next.js static assets
    location /_next/ {
        proxy_pass http://localhost:3000/_next/;
        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;
    }
    
    # Forward all other requests to Next.js
    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;
    }
}
This configuration handles both HTTP and HTTPS traffic, with specific locations for static files, Next.js assets, and proxying requests to your application.

Activating Your Configuration

Enable the configuration and verify it works correctly:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

SSL Certificate Setup

Secure your site with a free SSL certificate from Let's Encrypt:
sudo certbot --nginx -d example.com -d www.example.com
This command automatically configures HTTPS and redirects HTTP traffic to HTTPS.

Running Your Application with PM2

Start your Next.js application using PM2 for persistent execution:
cd /var/www/example.com
PORT=3000 pm2 start npm --name "example-app" -- start

# Or if using pnpm:
# PORT=3000 pm2 start pnpm --name "example-app" -- start

# Save PM2 configuration for auto-restart on server reboot
pm2 save
PM2 ensures your application stays running even after server restarts and provides easy management of your Node.js processes.
By following these steps, you'll have a production-ready Next.js application running on your own server with proper HTTP/HTTPS handling, performance optimization, and process management.