DEV Community

Cover image for Deploying Nginx on DigitalOcean? Here is the Complete Guide
Kuberns
Kuberns

Posted on • Originally published at kuberns.com

Deploying Nginx on DigitalOcean? Here is the Complete Guide

Nginx on DigitalOcean works. You install it on a Droplet, configure it as a reverse proxy, add SSL through Certbot, and manage it yourself from that point forward. The full setup takes 30 to 45 minutes if nothing goes wrong. Most guides stop there. This one does not.

What those guides skip is everything that comes after: the Nginx config that silently serves nothing when one line is wrong, the Certbot certificates that expire quietly when auto-renewal fails, the PM2 process manager you need to keep your Node.js app alive, and the OS patches that are permanently your responsibility.

This guide covers the complete setup and the production realities behind it. It also covers Kuberns, an Agentic AI cloud platform that skips the Nginx stack entirely. If you want a live HTTPS URL in under 5 minutes without touching a server config, that is the path. Otherwise, here is exactly how to do it on DigitalOcean.

You Should Know These Before You Deploy Nginx on DigitalOcean

You Should Know These Before You Deploy Nginx on DigitalOcean

Most Nginx tutorials give you the commands and leave you to figure out the rest. Before you commit to this stack, here is what actually matters in production.

Nginx Config Errors Fail Silently

A misconfigured Nginx server block does not throw a loud error. It either serves nothing, returns a 502, or silently falls through to the wrong site. There is no on-screen warning when your proxy_pass points to the wrong port or your server_name does not match your domain. You have to know to run nginx -t and watch the error log manually.

This becomes a real problem when you are debugging a production outage at 2am and the server appears to be running but requests are not reaching your app.

**_

The silent config failure is one of the most common reasons deployments break in production. Read why your app works locally but breaks after deploy to understand the full class of errors a manual Nginx setup introduces.
_**

SSL Certificates Expire Every 90 Days and Certbot Renewal Breaks

Let’s Encrypt certificates are valid for 90 days. Certbot sets up a systemd timer or cron job to auto-renew them, and most of the time it works. But when it does not, there is no alert. Your certificate expires, your site goes HTTPS-broken, and users see a security warning.

Renewal fails when port 80 is blocked by UFW, when your Nginx config has a syntax error, or when DNS no longer resolves to your Droplet. None of these trigger a notification. You find out when someone tells you the site is broken.

You Are Responsible for Every OS Patch and Security Update

A DigitalOcean Droplet is a Linux virtual machine you manage entirely. That means you own OS security updates, kernel patches, disk space, and firewall rules. DigitalOcean does not patch your server. If a CVE drops for the Ubuntu version your Droplet runs, you need to apply the fix. If your disk fills up, Nginx crashes and takes your app with it.

**_

Not sure what you are actually signing up for with a Droplet? Read what DigitalOcean actually provides at the infrastructure level before you commit to the manual stack.
_**

PM2 and Nginx Together Add Significant Setup Overhead

Nginx handles traffic routing. It does not manage your application process. For a Node.js app, that means you also need PM2 running as a daemon to keep the app alive. That is two separate tools to install, configure, and debug. If PM2 is not set up with pm2 startup and pm2 save, your app stops on every server reboot and does not come back on its own.

**_

Before you go any further, read what you need to know before deploying Node.js on DigitalOcean for the full picture of the PM2 and Nginx dependency chain.
_**

How to Install Nginx on a DigitalOcean Droplet (Step by Step)

Step by step guide to install Nginx on a DigitalOcean Droplet

You need a Droplet running Ubuntu 22.04 LTS, a non-root user with sudo access, and a domain name with its A record pointing to your Droplet IP. Once those are in place, here is the complete setup.

Step 1: Update Your System and Install Nginx

SSH into your Droplet as your sudo user and update the package index before installing anything:

sudo apt update
sudo apt install nginx -y
Enter fullscreen mode Exit fullscreen mode

Nginx installs and starts automatically. Ubuntu registers it as a systemd service, so it will restart on reboot by default.

Step 2: Configure UFW Firewall Rules

Nginx registers three profiles with UFW on installation: Nginx HTTP (port 80 only), Nginx HTTPS (port 443 only), and Nginx Full (both). Allow SSH and the full Nginx profile:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
Enter fullscreen mode Exit fullscreen mode

Use Nginx HTTP while setting up, then switch to Nginx Full once SSL is configured.

Step 3: Verify Nginx Is Running

Check the service status:

systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

You should see active (running). Confirm Nginx is responding on port 80:

curl -I http://localhost
Enter fullscreen mode Exit fullscreen mode

A 200 OK response with a Server: nginx header confirms it is live.

Step 4: Set Up a Server Block for Your Domain

Create a new config file for your domain instead of editing the default:

sudo nano /etc/nginx/sites-available/yourdomain.com
Enter fullscreen mode Exit fullscreen mode

Add a basic server block:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    root /var/www/yourdomain.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
Enter fullscreen mode Exit fullscreen mode

For a Node.js or Python app, the root and try_files lines are replaced by a proxy_pass directive. That is covered in the reverse proxy section below.

Step 5: Enable the Site and Reload Nginx

Create a symlink from sites-available to sites-enabled:

sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
Enter fullscreen mode Exit fullscreen mode

Always test your config before reloading:

sudo nginx -t
Enter fullscreen mode Exit fullscreen mode

If the output says syntax is ok and test is successful, reload:

sudo systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Never skip nginx -t. A config error on reload takes your entire server offline until you fix it.

How to Configure Nginx as a Reverse Proxy on DigitalOcean

If you are running a Node.js, Python, or other backend app on your Droplet, Nginx acts as a reverse proxy. It receives traffic on port 80 and 443, then forwards it to your app process running on an internal port like 3000.

Replace the static file config in your server block with this proxy configuration:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.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;
    }
}
Enter fullscreen mode Exit fullscreen mode

proxy_pass tells Nginx where your app is running. The proxy_set_header lines preserve the original request headers so your app receives the real client IP and connection details. The Upgrade and Connection headers are required for WebSocket support.

Change localhost:3000 to match whatever port your app actually listens on. Test with nginx -t and reload.

**_

Need to set up the Node.js process that Nginx proxies to? The complete Node.js app deployment guide covers every step from PM2 setup to going live.
_**

How to Add SSL to Nginx on DigitalOcean with Let’s Encrypt

Nginx is running on HTTP. To add HTTPS, install Certbot and let it update your Nginx config automatically:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Enter fullscreen mode Exit fullscreen mode

Certbot validates your domain, installs the certificate, and rewrites your Nginx server block to handle HTTPS and redirect HTTP traffic. Your site is live on HTTPS once the command completes.

Certificates expire every 90 days. Certbot sets up a systemd timer to handle renewal automatically. Test it with:

sudo certbot renew --dry-run
Enter fullscreen mode Exit fullscreen mode

If the dry run fails, check that port 80 is open in UFW and your DNS is still pointing to the Droplet.

**_

Setting up Nginx, PM2, and SSL from scratch on a Droplet takes 30 to 45 minutes on a clean server. For teams managing multiple apps or non-standard stacks, the best deployment platforms for small dev teams handle this entire layer automatically.
_**

Common Errors You Find While Deploying Nginx on DigitalOcean

Common errors while deploying Nginx on DigitalOcean

These three errors appear consistently across every Nginx on DigitalOcean setup. Each one points to a deeper reason why the manual stack adds ongoing maintenance overhead.

502 Bad Gateway

Nginx is running but your application is not. The upstream process, the Node.js, Python, or Go app that proxy_pass points to, has crashed or never started. Nginx cannot reach it and returns a 502.

The fix is to restart your app via PM2 or systemd and confirm it is listening on the correct port. But this is also the error that appears at 2am when PM2 was not configured with pm2 startup and a server reboot killed the process silently. On Kuberns, process management is handled by the platform. There is no PM2 to configure, no pm2 save step to forget, and no 502 from a crashed process that was never set to restart automatically.

504 Gateway Timeout

Your app is running but Nginx timed out waiting for a response. This happens when the app takes too long to process a request, when it is overloaded on a small Droplet, or when proxy_pass is pointed at the wrong port and Nginx is waiting for a connection that will never come.

The underlying issue is often resource constraints: a $6/mo Droplet running out of memory under traffic load. Scaling a Droplet vertically requires a manual resize and a reboot.

**_

Autoscaling on a Droplet does not exist natively. See the best DigitalOcean alternatives for platforms that handle traffic spikes automatically without a reboot or manual intervention.
_**

SSL Certificate Expired

Certbot’s auto-renewal timer failed and the certificate was not renewed before the 90-day expiry. Users now see a browser security warning. The site still loads but HTTPS is broken.

This happens when port 80 gets blocked by a UFW rule change, when the Nginx config breaks between renewals, or when the systemd timer was never enabled correctly. There is no alert when it happens. You find out when someone reports the broken padlock. With Kuberns, SSL is provisioned and renewed by the platform. There is no Certbot to manage, no timer to check, and no expired certificate to debug.

**_

The operational overhead adds up fast. See why AI-managed PaaS beats IaaS for developer teams for a direct comparison of what managed platforms handle vs what Droplets leave entirely to you.
_**

The Faster Way to Deploy Without Touching Nginx

Deploy without Nginx setup using Kuberns

Kuberns is an Agentic AI cloud platform that removes the entire manual deployment layer. No Nginx config. No Certbot. No PM2. No server to patch. You connect your GitHub repo and Kuberns takes it from there.

Deploy in 3 steps:

  1. Connect your GitHub repo to Kuberns
  2. Set your environment variables in the dashboard
  3. Click Deploy and get a live HTTPS URL in under 5 minutes

Kuberns auto-detects your stack, installs dependencies, configures a reverse proxy, provisions SSL, and sets up CI/CD on every push to your branch. Everything you spent 45 minutes configuring manually on a Droplet is handled before your first deploy completes.

Here is what Kuberns handles that DigitalOcean leaves to you:

  • Agentic AI deployment reads your repo, detects your stack, and configures everything without a single config file
  • Reverse proxy built in, no Nginx server blocks, no nginx -t, no silent config failures
  • Automatic SSL provisioning and renewal, no Certbot, no 90-day expiry surprises
  • Built-in process management, no PM2, no pm2 startup, no app going down after a reboot
  • One-click autoscaling based on real traffic, no Droplet resize, no reboot, no manual threshold tuning
  • Unified dashboard for deployments, logs, environment variables, domains, and scaling, all in one place
  • CI/CD on every git push, no GitHub Actions workflow to write or maintain
  • Zero OS maintenance, no Ubuntu patches, no disk space monitoring, no CVEs to chase

Deploy on Kuberns without Nginx setup

DigitalOcean vs Kuberns

Conclusion

Setting up Nginx on DigitalOcean is straightforward if you know Linux. The install is clean, the UFW setup is well-documented, and the Certbot integration works when everything is configured correctly. The problem is everything that comes after: the config that breaks silently, the certificates that expire without warning, the PM2 setup that gets forgotten until a reboot kills the app.

For developers who want to understand infrastructure at this level, the manual path has real value. For teams who want to ship features without managing a server stack, the time cost does not make sense anymore.

Kuberns gives you everything a Droplet plus Nginx plus PM2 provides, without any of the manual configuration. Your app goes from GitHub to a live HTTPS URL in under 5 minutes, with autoscaling, CI/CD, and zero server maintenance included.

Deploy your app with one-click Agentic AI on Kuberns

Top comments (0)