nginx
Installation
SKILL.md
Identity
- Unit:
nginx.service - Config:
/etc/nginx/nginx.conf,/etc/nginx/sites-enabled/,/etc/nginx/conf.d/ - Logs:
journalctl -u nginx,/var/log/nginx/access.log,/var/log/nginx/error.log - User:
www-data(Debian/Ubuntu),nginx(RHEL/Fedora) - Distro install:
apt install nginx/dnf install nginx
Key Operations
- Validate config:
nginx -t - Full config dump:
nginx -T(merged, useful for debugging includes) - Reload (no downtime):
sudo systemctl reload nginx - Restart:
sudo systemctl restart nginx - Test specific config:
nginx -t -c /path/to/test.conf
Expected Ports
- 80/tcp (HTTP), 443/tcp (HTTPS)
- Verify:
ss -tlnp | grep nginx - Firewall:
sudo ufw allow 'Nginx Full'orsudo ufw allow 80,443/tcp
Health Checks
systemctl is-active nginx→activenginx -t 2>&1→ containssyntax is okandtest is successfulcurl -sI http://localhost→ HTTP response (not connection refused)ss -tlnp | grep ':80\|:443'→ nginx listed
Common Failures
| Symptom | Likely cause | Check/Fix |
|---|---|---|
bind() to 0.0.0.0:80 failed |
Port already in use | ss -tlnp | grep :80 — find conflicting process |
502 Bad Gateway |
Upstream service down or wrong address | Check upstream (systemctl status <app>), verify proxy_pass URL |
504 Gateway Timeout |
Upstream too slow | Increase proxy_read_timeout; check upstream performance |
| Config test passes but reload fails | Syntax error in included file | nginx -T 2>&1 | grep -A3 error |
Permission denied on socket |
Wrong socket path or permissions | Check proxy_pass unix:/run/app.sock path and ownership |
SSL: unknown protocol |
HTTP client hitting HTTPS port | Redirect port 80 → 443 or check client |
too many open files |
worker_rlimit_nofile too low |
Raise in nginx.conf and system ulimit |
| 413 Request Entity Too Large | client_max_body_size too small |
Increase to match expected upload size |
Pain Points
- Trailing slash in
proxy_pass:proxy_pass http://backend/strips the location prefix;proxy_pass http://backenddoes not. Deliberately different behavior. - Sites-enabled symlinks: Broken symlinks are silently ignored — nginx won't warn you.
worker_connections×worker_processes: This is the real max client limit, not either alone.default_servermatters: Without it, the first defined vhost catches unmatched requests.server_nameregex ordering:~(regex) checked before literal matches.- Upstream keepalive: Set
keepalivein the upstream block ANDproxy_http_version 1.1+proxy_set_header Connection ""in the location block — both required. try_filesfinal arg is a fallback URI, not a file:try_files $uri $uri/ =404— the=404is a named response code fallback, not a file path.
References
See references/ for:
nginx.conf.annotated— full default config with every directive explainedcommon-patterns.md— reverse proxy, virtual hosts, SSL, load balancing, and static file examplesdocs.md— official documentation links
Related skills