# nginx — Web Server, Reverse Proxy and Load Balancer

> Practical guide to nginx — service management, CLI commands, config testing, virtual hosts, TLS with Certbot and log analysis on Debian/Ubuntu and RHEL.

Source: https://www.jpkc.com/db/en/cheatsheets/web-servers/nginx/

<!-- PROSE:intro -->
NGINX is one of the most widely deployed web servers on the internet, and it shines wherever many concurrent connections meet limited resources: thanks to its event-driven architecture, a single worker process handles thousands of connections in parallel. Beyond serving static files, NGINX acts as a reverse proxy, load balancer and TLS terminator in front of your applications. You control it through the lean `nginx` command and – on systemd distributions – through `systemctl`. This guide gathers the commands you reach for daily: service management, config testing, virtual hosts, certificates with Certbot and log analysis.
<!-- PROSE:intro:end -->

## Service Management (systemctl)

`systemctl start nginx` — Start the NGINX web server.

```bash
systemctl start nginx
```

`systemctl stop nginx` — Stop the NGINX web server immediately.

```bash
systemctl stop nginx
```

`systemctl restart nginx` — Restart NGINX (stop + start). Briefly drops all active connections.

```bash
systemctl restart nginx
```

`systemctl reload nginx` — Reload NGINX configuration gracefully without dropping active connections.

```bash
systemctl reload nginx
```

`systemctl status nginx` — Show NGINX service status, PID, uptime, and recent log output.

```bash
systemctl status nginx
```

`systemctl enable nginx` — Enable NGINX to start automatically on system boot.

```bash
systemctl enable nginx
```

`systemctl disable nginx` — Disable NGINX from starting automatically on boot.

```bash
systemctl disable nginx
```

`systemctl is-active nginx` — Check if NGINX is currently running. Returns 'active' or 'inactive'.

```bash
systemctl is-active nginx
```

## nginx CLI Commands

`nginx -t` — Test the NGINX configuration for syntax errors. Always run before reloading.

```bash
nginx -t
```

`nginx -T` — Test configuration and dump the entire resolved configuration to stdout.

```bash
nginx -T
```

`nginx -s reload` — Send the reload signal to the running NGINX master process (graceful config reload).

```bash
nginx -s reload
```

`nginx -s stop` — Send the stop signal to NGINX (fast shutdown, drops connections immediately).

```bash
nginx -s stop
```

`nginx -s quit` — Send the quit signal to NGINX (graceful shutdown, waits for requests to finish).

```bash
nginx -s quit
```

`nginx -s reopen` — Reopen log files. Used after rotating logs to start writing to the new file.

```bash
nginx -s reopen
```

`nginx -v` — Show the NGINX version.

```bash
nginx -v
```

`nginx -V` — Show the NGINX version, compiler flags, and all compiled-in modules.

```bash
nginx -V
```

`nginx -c /path/to/nginx.conf` — Start NGINX with a specific configuration file instead of the default.

```bash
nginx -c /etc/nginx/nginx.conf
```

`nginx -p /path/to/prefix` — Set the NGINX prefix path (used to resolve relative paths in the config).

```bash
nginx -p /etc/nginx
```

`nginx -t && systemctl reload nginx` — Validate config and reload only if there are no errors (recommended workflow).

```bash
nginx -t && systemctl reload nginx
```

## Process Management

`ps aux | grep nginx` — List all running NGINX processes (master and worker processes).

```bash
ps aux | grep nginx
```

`cat /var/run/nginx.pid` — Show the PID of the NGINX master process.

```bash
cat /var/run/nginx.pid
```

`kill -HUP $(cat /var/run/nginx.pid)` — Send HUP signal to the master process to reload configuration gracefully.

```bash
kill -HUP $(cat /var/run/nginx.pid)
```

`kill -USR1 $(cat /var/run/nginx.pid)` — Reopen log files by sending USR1 signal (equivalent to nginx -s reopen).

```bash
kill -USR1 $(cat /var/run/nginx.pid)
```

`kill -WINCH $(cat /var/run/nginx.pid)` — Gracefully shut down worker processes (master stays alive, used during upgrades).

```bash
kill -WINCH $(cat /var/run/nginx.pid)
```

## Virtual Hosts (Debian/Ubuntu)

`ls /etc/nginx/sites-available/` — List all available virtual host configuration files.

```bash
ls /etc/nginx/sites-available/
```

`ls /etc/nginx/sites-enabled/` — List all currently enabled virtual host configurations (symlinks).

```bash
ls /etc/nginx/sites-enabled/
```

`ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/` — Enable a virtual host by creating a symlink in sites-enabled/.

```bash
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
```

`rm /etc/nginx/sites-enabled/example.com` — Disable a virtual host by removing the symlink from sites-enabled/.

```bash
rm /etc/nginx/sites-enabled/example.com
```

`ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginx` — Enable a site, validate config, and reload NGINX in one step.

```bash
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginx
```

`nginx -T | grep server_name` — List all configured server_name values across all virtual hosts.

```bash
nginx -T | grep server_name
```

## Configuration Directories

`/etc/nginx/nginx.conf` — Main NGINX configuration file. Includes sites-enabled/ and conf.d/.

```bash
nano /etc/nginx/nginx.conf
```

`/etc/nginx/sites-available/` — Directory for virtual host config files (Debian/Ubuntu). Not active until symlinked.

```bash
ls /etc/nginx/sites-available/
```

`/etc/nginx/sites-enabled/` — Directory containing symlinks to active virtual host configs (Debian/Ubuntu).

```bash
ls /etc/nginx/sites-enabled/
```

`/etc/nginx/conf.d/` — Drop-in config directory. All *.conf files here are automatically included.

```bash
ls /etc/nginx/conf.d/
```

`/etc/nginx/snippets/` — Reusable configuration snippets (e.g. ssl-params.conf, fastcgi-php.conf).

```bash
ls /etc/nginx/snippets/
```

`/var/log/nginx/` — Default log directory containing access.log and error.log.

```bash
ls /var/log/nginx/
```

## Logs

`tail -f /var/log/nginx/access.log` — Follow the NGINX access log in real-time.

```bash
tail -f /var/log/nginx/access.log
```

`tail -f /var/log/nginx/error.log` — Follow the NGINX error log in real-time.

```bash
tail -f /var/log/nginx/error.log
```

`tail -f /var/log/nginx/error.log | grep 'crit\|emerg\|alert'` — Watch the error log and filter for critical-level messages only.

```bash
tail -f /var/log/nginx/error.log | grep 'crit\|emerg'
```

`grep ' 500 \| 502 \| 503 ' /var/log/nginx/access.log` — Find 5xx server error responses in the access log.

```bash
grep ' 500 \| 502 \| 503 ' /var/log/nginx/access.log
```

`awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20` — Show the top 20 IP addresses by request count from the access log.

```bash
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
```

`nginx -t 2>&1 | grep -v 'successful'` — Run a config test and show only warnings and errors (suppress the OK message).

```bash
nginx -t 2>&1 | grep -v 'successful'
```

`journalctl -u nginx -f` — Follow NGINX log output via systemd journal (includes start/stop events).

```bash
journalctl -u nginx -f
```

`journalctl -u nginx --since '1 hour ago'` — Show NGINX journal entries from the last hour.

```bash
journalctl -u nginx --since '1 hour ago'
```

## SSL / TLS & Certbot

`certbot --nginx -d example.com -d www.example.com` — Obtain and automatically install a Let's Encrypt certificate for NGINX.

```bash
certbot --nginx -d example.com -d www.example.com
```

`certbot certonly --nginx -d example.com` — Obtain a certificate but do not modify NGINX config (manage SSL manually).

```bash
certbot certonly --nginx -d example.com
```

`certbot renew --dry-run` — Simulate the automatic renewal process to verify it would succeed.

```bash
certbot renew --dry-run
```

`certbot renew` — Renew all certificates that are due for renewal (run via cron or systemd timer).

```bash
certbot renew
```

`certbot certificates` — List all managed Let's Encrypt certificates and their expiry dates.

```bash
certbot certificates
```

`openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/self.key -out /etc/nginx/ssl/self.crt` — Generate a self-signed SSL certificate valid for 365 days.

```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
```

`openssl dhparam -out /etc/nginx/dhparam.pem 2048` — Generate a Diffie-Hellman parameter file for stronger SSL key exchange.

```bash
openssl dhparam -out /etc/nginx/dhparam.pem 2048
```

`openssl s_client -connect example.com:443 -servername example.com` — Test an SSL connection and inspect the certificate chain.

```bash
openssl s_client -connect example.com:443 -servername example.com
```

## Debugging & Inspection

`curl -I http://localhost` — Send a HEAD request to the local NGINX and inspect response headers.

```bash
curl -I http://localhost
```

`curl -I -H 'Host: example.com' http://localhost` — Test a specific virtual host by overriding the Host header.

```bash
curl -I -H 'Host: example.com' http://localhost
```

`curl -sk https://localhost -o /dev/null -w '%{http_code}'` — Check the HTTP status code returned by NGINX over HTTPS.

```bash
curl -sk https://localhost -o /dev/null -w '%{http_code}'
```

`nginx -T | grep -A5 'server_name example.com'` — Find the full server block for a specific domain in the dumped configuration.

```bash
nginx -T | grep -A5 'server_name example.com'
```

`ss -tlnp | grep nginx` — Show which ports NGINX is listening on.

```bash
ss -tlnp | grep nginx
```

`strace -p $(cat /var/run/nginx.pid) -e trace=network` — Trace network system calls of the NGINX master process for low-level debugging.

```bash
strace -p $(cat /var/run/nginx.pid) -e trace=network
```

<!-- PROSE:outro -->
## Conclusion

NGINX rewards a disciplined workflow: validate every change with `nginx -t` before you reload with `nginx -s reload` or `systemctl reload nginx` – the reload is graceful, so active connections never get dropped. After a log rotation, `nginx -s reopen` makes NGINX start writing to the fresh log files. If you want to fine-tune server, location and upstream blocks, you'll find the matching directives in the [nginx-conf configuration reference](https://www.jpkc.com/db/en/cheatsheets/web-servers/nginx-conf/).

## Further Reading

- [nginx – official documentation](https://nginx.org/en/docs/) – reference of all directives and modules
- [Nginx – Wikipedia](https://en.wikipedia.org/wiki/Nginx) – background and history
<!-- PROSE:outro:end -->

## Related Commands

- [apache](https://www.jpkc.com/db/en/cheatsheets/web-servers/apache/) – the classic web server with modular configuration
- [caddy](https://www.jpkc.com/db/en/cheatsheets/web-servers/caddy/) – modern web server with automatic HTTPS
- [certbot](https://www.jpkc.com/db/en/cheatsheets/web-servers/certbot/) – obtain and renew Let's Encrypt certificates

