Skip to main content

Nginx

Nginx is a high-performance web server and reverse proxy. It’s commonly used to:

  • serve static websites,
  • proxy traffic to apps (Node, Python, PHP, Go),
  • terminate HTTPS,
  • handle routing, timeouts, and basic caching.

This guide shows a minimal, reliable setup on Ubuntu/Debian: install Nginx, proxy to an app on :3000, enable HTTPS, and verify everything works.


Install Nginx (Ubuntu / Debian)

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
  • enable --now starts Nginx and ensures it runs on boot.
  • The service is managed by systemd.

Check status:

systemctl status nginx

Where Nginx configuration lives

  • Main config: /etc/nginx/nginx.conf

  • Site configs:

    • Available: /etc/nginx/sites-available/
    • Enabled: /etc/nginx/sites-enabled/
  • Logs:

    • Access: /var/log/nginx/access.log
    • Error: /var/log/nginx/error.log

Basic reverse proxy (app on :3000)

Create a site config:

sudo nano /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com;

location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
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;
}
}

Enable and reload:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
  • nginx -t checks config syntax
  • reload applies changes without downtime

Enable HTTPS (Let’s Encrypt)

Use Certbot with the Nginx plugin:

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo certbot --nginx -d example.com
  • Certbot automatically edits your Nginx config
  • Certificates renew via systemd timers

Check renewal:

systemctl list-timers | grep certbot

Verify everything

curl -I http://example.com
curl -I https://example.com
sudo nginx -t

Common issues

502 Bad Gateway

  • App not running on the target port
  • Wrong proxy_pass address
  • App bound to localhost incorrectly

Config not applied

  • Forgot nginx -t
  • Forgot systemctl reload nginx

Timeouts

  • App is slow → adjust proxy_read_timeout
  • Long requests need explicit tuning

Useful commands

sudo systemctl reload nginx
sudo systemctl restart nginx
sudo systemctl stop nginx
sudo nginx -t
tail -f /var/log/nginx/error.log

When to use Nginx

  • You want full control over routing and headers
  • You run apps directly on a VM or bare metal
  • You need predictable, low-level behavior

When not to use Nginx

  • You don’t want to manage servers or certificates
  • You prefer automatic HTTPS and routing out of the box
  • You deploy containerized apps frequently

Key takeaways

  • Nginx is a fast, stable reverse proxy and web server
  • proxy_pass forwards traffic to your app
  • Always test configs before reloading
  • Logs are your first debugging tool
  • HTTPS with Certbot is reliable and automated

Deploy without manual setup

If you don’t want to manage servers, configs, or certificates:

👉 Deploy an app with automatic HTTPS

Hostim.dev provides HTTPS, domains, logs, metrics, and persistence by default—no Nginx config required.