1. What Nginx Does
Nginx is a web server and reverse proxy.
Common roles:
-
Serve static files: HTML, CSS, JS, images
-
Reverse proxy to apps: Go, Node.js, PHP, Python, ttyd, code-server
-
Handle HTTPS/TLS certificates
-
Route many domains on one server
-
Add authentication, caching, compression, and headers
Typical flow:
Browser
↓ HTTPS
Nginx
↓ proxy_pass / static file / FastCGI
Application or files2. Install Nginx
On Ubuntu/Debian:
sudo apt update
sudo apt install nginxCheck status:
systemctl status nginxEnable on boot:
sudo systemctl enable nginxStart / restart / reload:
sudo systemctl start nginx
sudo systemctl restart nginx
sudo systemctl reload nginxUse reload when only the configuration changed. It is safer than a restart.
3. Main File Structure
Common Ubuntu layout:
/etc/nginx/
├── nginx.conf
├── sites-available/
│ └── example.com
├── sites-enabled/
│ └── example.com -> ../sites-available/example.com
├── conf.d/
└── snippets/Important paths:
/var/www/html default web root
/var/log/nginx/access.log access log
/var/log/nginx/error.log error log
/etc/nginx/nginx.conf main config4. Basic Static Website
Create directory:
sudo mkdir -p /srv/www/example
sudo nano /srv/www/example/index.htmlExample config:
server {
listen 80;
server_name example.com www.example.com;
root /srv/www/example;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}Enable it:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx5. Reverse Proxy Example
For an app running on port 3000:
server {
listen 80;
server_name app.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;
}
}This means:
User visits app.example.com
Nginx receives request
Nginx forwards request to localhost:3000
App responds
Nginx sends response back to user6. HTTPS with Certbot
Install Certbot:
sudo apt install certbot python3-certbot-nginxRequest certificate:
sudo certbot --nginx -d example.com -d www.example.comTest renewal:
sudo certbot renew --dry-runCertbot usually edits the Nginx config automatically.
7. Useful Commands
Test config:
sudo nginx -tReload config:
sudo systemctl reload nginxShow active config:
sudo nginx -TWatch logs:
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.logCheck listening ports:
sudo ss -tulpn | grep nginx8. Basic Security
Hide unused default site:
sudo rm /etc/nginx/sites-enabled/defaultUse firewall:
sudo ufw allow 'Nginx Full'
sudo ufw enableFor basic authentication:
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd usernameNginx config:
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:3000;
}9. How Nginx Works Internally
Nginx has a master process and worker processes.
Master process
├── reads config
├── opens ports
├── manages workers
└── reloads config gracefully
Worker processes
├── accept client connections
├── read requests
├── serve files or proxy requests
└── write responsesNginx is event-driven.
Instead of creating one thread per connection, each worker handles many connections using an event loop.
Simplified:
Worker waits for events:
- new connection
- data available
- upstream response ready
- client ready to receive dataThis is why Nginx handles many simultaneous connections efficiently.
10. Request Processing Flow
Example request:
GET https://notes.example.com/pageNginx roughly does:
1. Accept TCP connection
2. Handle TLS if HTTPS
3. Read HTTP request
4. Choose matching server block by server_name
5. Choose matching location block
6. Serve file or proxy to backend
7. Send response
8. Keep connection alive or close it11. Server Block Matching
Nginx chooses a server block based on:
server_name
listen portExample:
server {
listen 80;
server_name notes.example.com;
}If no exact match is found, Nginx uses the default server for that port.
12. Location Matching
Common location types:
location / {
}Matches everything.
location /api/ {
}Matches paths starting with /api/.
location = /exact {
}Matches exact path only.
location ~ \.php$ {
}Regex match.
13. Static File vs Reverse Proxy
Static website:
root /srv/www/site;
location / {
try_files $uri $uri/ =404;
}Reverse proxy:
location / {
proxy_pass http://127.0.0.1:3000;
}PHP site:
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}14. Important Concepts
root
Maps URL path to filesystem path.
root /srv/www/site;Request:
/about.htmlFile:
/srv/www/site/about.htmltry_files
Tries files in order.
try_files $uri $uri/ /index.html;Useful for single-page apps.
proxy_pass
Forwards request to another service.
proxy_pass http://127.0.0.1:8080;upstream
Defines backend group.
upstream myapp {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
location / {
proxy_pass http://myapp;
}
}15. Mental Model
Think of Nginx as a traffic controller.
Domain name decides server block.
URL path decides location block.
Location decides action:
- serve file
- proxy to app
- pass to PHP-FPM
- reject
- redirect
- require passwordFor personal servers:
One VPS
One public IP
Many domains
Nginx routes each domain to the right app or folderExample:
notes.example.com → static Quartz files
lab.example.com → ttyd service
root.example.com → admin ttyd service
intro.example.com → static Hugo site16. Troubleshooting Checklist
When Nginx does not work:
-
Check DNS points to the server.
-
Check firewall allows port 80/443.
-
Check Nginx is running.
-
Run
sudo nginx -t. -
Check correct
server_name. -
Check config is enabled in
sites-enabled. -
Check backend app is running.
-
Check logs.
Useful commands:
curl -I http://example.com
curl -I https://example.com
sudo nginx -t
sudo systemctl status nginx
sudo journalctl -u nginx -xe
sudo tail -f /var/log/nginx/error.log17. Key Takeaway
Nginx is not just a web server.
It is the front door of the server.
It receives public traffic, decides where each request should go, protects services, handles HTTPS, and lets many apps share one machine cleanly.