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.
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
| Feature | Vercel | VPS (Nginx + PM2) |
|---|---|---|
| Ease of Use | Extremely high; automated deployments | Requires manual server setup and maintenance |
| Pricing | Usage-based; can get expensive at scale | Predictable, fixed monthly cost |
| Control | Limited by serverless constraints | Full root access, install anything |
| Performance | Possible cold starts on lower tiers | Always-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.
# 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 startupOnce 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.
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