Back to Blog
Web Development & DevOps

Deploying Next.js to a VPS using Nginx and PM2

A guide and technical notes on manually deploying a Next.js application to a Linux VPS. Discussing PM2 configuration, Nginx reverse proxy, and setting up domain and SSL.

Next.jsNode.jsPM2NginxVPS UbuntuCloudflare DNSSSL
Deretan server menyala di dalam rak data center
Infrastruktur server fisik yang menjadi tulang punggung deployment VPS modern. · © Taylor Vick

Managed Hosting (Vercel) vs Manual VPS

Platforms like Vercel or Netlify offer tremendous convenience (managed hosting) due to their automated, zero-config deployment pipelines. However, in certain business scenarios where server customization, internal database installation, or massive scale cost-savings are required, utilizing a Virtual Private Server (VPS) becomes the more logical choice.

With a VPS, we possess root access (full control) over the Linux environment. This means we are free to install additional security modules, modify firewall rules, and run multiple concurrent applications on a single machine without hidden costs. Additionally, there are no 'cold starts' because the application process is always-on.

Comparison Table

FeatureVercelVPS (Nginx + PM2)
Ease of UseExtremely high; automated deploymentsRequires manual server setup and maintenance
PricingUsage-based; can get expensive at scalePredictable, fixed monthly cost
ControlLimited by serverless constraintsFull root access, install anything
PerformancePossible cold starts on lower tiersAlways-on without cold start delays

Next.js Deployment Pipeline

The manual deployment process necessitates several sequential steps to ensure the application is accessible publicly and securely. It is highly recommended to enable 'standalone' mode in next.config.js prior to building for optimized results.

  • Server Preparation: Updating the VPS and installing the latest Node.js version.
  • Code Duplication: Cloning the project repository to the server using SSH or Git.
  • Production Build: Running dependency installation and building the project (npm run build).
  • Process Management: Running the project via PM2 to prevent termination when the terminal closes.
  • Reverse Proxy: Directing public traffic using Nginx to the localized application.
  • Security: Implementing SSL/TLS certificates using Certbot (Let's Encrypt).

PM2 Configuration

PM2 is an advanced process manager for Node.js applications that enables us to keep the application alive indefinitely, automatically restart it upon encountering crashes, and reload it with zero downtime.

terminalbash
# Install PM2 globally
npm install -g pm2

# Build the Next.js app
npm run build

# Run Next.js with PM2 on port 3000
pm2 start npm --name "web-portfolio" -- run start

# Save PM2 state to restart automatically on reboot
pm2 save
pm2 startup

Once executed, PM2 monitors the application status. You can monitor the logs in real-time using the `pm2 logs` command.

Setting up Nginx as a Reverse Proxy

By default, Next.js applications run on localhost port 3000. To make them accessible via standard web ports (80 for HTTP and 443 for HTTPS), we require Nginx as a Reverse Proxy.

/etc/nginx/sites-available/portofolionginx
server {
    listen 80;
    server_name fajargeran.my.id www.fajargeran.my.id;

    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 block instructs Nginx to capture any inbound external web requests and efficiently forward them to the internally running Next.js application.

Securing .env, SSL, and the Update Process

It is critically important to never commit your .env file into your GitHub repository. Instead, create the .env file directly within the VPS using a text editor like nano or vim. After the app is running, use Certbot to automatically generate a free SSL certificate to ensure secure connections (HTTPS).

When updating the application, the flow is quite straightforward: git pull for the latest code, npm install if new packages were added, npm run build to rebuild, and finally pm2 restart web-portfolio to apply the changes without disrupting active users.

Butuh bantuan deploy ke server Anda?

Jika bisnis Anda membutuhkan transisi ke VPS pribadi atau instalasi server internal, mari kita diskusikan solusinya.

Hubungi Saya
© 2026 Fajar Geran Arifin. All rights reserved.