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.
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.
Service Management (systemctl)
systemctl start nginx — Start the NGINX web server.
systemctl start nginxsystemctl stop nginx — Stop the NGINX web server immediately.
systemctl stop nginxsystemctl restart nginx — Restart NGINX (stop + start). Briefly drops all active connections.
systemctl restart nginxsystemctl reload nginx — Reload NGINX configuration gracefully without dropping active connections.
systemctl reload nginxsystemctl status nginx — Show NGINX service status, PID, uptime, and recent log output.
systemctl status nginxsystemctl enable nginx — Enable NGINX to start automatically on system boot.
systemctl enable nginxsystemctl disable nginx — Disable NGINX from starting automatically on boot.
systemctl disable nginxsystemctl is-active nginx — Check if NGINX is currently running. Returns 'active' or 'inactive'.
systemctl is-active nginxnginx CLI Commands
nginx -t — Test the NGINX configuration for syntax errors. Always run before reloading.
nginx -tnginx -T — Test configuration and dump the entire resolved configuration to stdout.
nginx -Tnginx -s reload — Send the reload signal to the running NGINX master process (graceful config reload).
nginx -s reloadnginx -s stop — Send the stop signal to NGINX (fast shutdown, drops connections immediately).
nginx -s stopnginx -s quit — Send the quit signal to NGINX (graceful shutdown, waits for requests to finish).
nginx -s quitnginx -s reopen — Reopen log files. Used after rotating logs to start writing to the new file.
nginx -s reopennginx -v — Show the NGINX version.
nginx -vnginx -V — Show the NGINX version, compiler flags, and all compiled-in modules.
nginx -Vnginx -c /path/to/nginx.conf — Start NGINX with a specific configuration file instead of the default.
nginx -c /etc/nginx/nginx.confnginx -p /path/to/prefix — Set the NGINX prefix path (used to resolve relative paths in the config).
nginx -p /etc/nginxnginx -t && systemctl reload nginx — Validate config and reload only if there are no errors (recommended workflow).
nginx -t && systemctl reload nginxProcess Management
ps aux | grep nginx — List all running NGINX processes (master and worker processes).
ps aux | grep nginxcat /var/run/nginx.pid — Show the PID of the NGINX master process.
cat /var/run/nginx.pidkill -HUP $(cat /var/run/nginx.pid) — Send HUP signal to the master process to reload configuration gracefully.
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).
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).
kill -WINCH $(cat /var/run/nginx.pid)Virtual Hosts (Debian/Ubuntu)
ls /etc/nginx/sites-available/ — List all available virtual host configuration files.
ls /etc/nginx/sites-available/ls /etc/nginx/sites-enabled/ — List all currently enabled virtual host configurations (symlinks).
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/.
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/.
rm /etc/nginx/sites-enabled/example.comln -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.
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ && nginx -t && systemctl reload nginxnginx -T | grep server_name — List all configured server_name values across all virtual hosts.
nginx -T | grep server_nameConfiguration Directories
/etc/nginx/nginx.conf — Main NGINX configuration file. Includes sites-enabled/ and conf.d/.
nano /etc/nginx/nginx.conf/etc/nginx/sites-available/ — Directory for virtual host config files (Debian/Ubuntu). Not active until symlinked.
ls /etc/nginx/sites-available//etc/nginx/sites-enabled/ — Directory containing symlinks to active virtual host configs (Debian/Ubuntu).
ls /etc/nginx/sites-enabled//etc/nginx/conf.d/ — Drop-in config directory. All *.conf files here are automatically included.
ls /etc/nginx/conf.d//etc/nginx/snippets/ — Reusable configuration snippets (e.g. ssl-params.conf, fastcgi-php.conf).
ls /etc/nginx/snippets//var/log/nginx/ — Default log directory containing access.log and error.log.
ls /var/log/nginx/Logs
tail -f /var/log/nginx/access.log — Follow the NGINX access log in real-time.
tail -f /var/log/nginx/access.logtail -f /var/log/nginx/error.log — Follow the NGINX error log in real-time.
tail -f /var/log/nginx/error.logtail -f /var/log/nginx/error.log | grep 'crit\|emerg\|alert' — Watch the error log and filter for critical-level messages only.
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.
grep ' 500 \| 502 \| 503 ' /var/log/nginx/access.logawk '{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.
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20nginx -t 2>&1 | grep -v 'successful' — Run a config test and show only warnings and errors (suppress the OK message).
nginx -t 2>&1 | grep -v 'successful'journalctl -u nginx -f — Follow NGINX log output via systemd journal (includes start/stop events).
journalctl -u nginx -fjournalctl -u nginx --since '1 hour ago' — Show NGINX journal entries from the last hour.
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.
certbot --nginx -d example.com -d www.example.comcertbot certonly --nginx -d example.com — Obtain a certificate but do not modify NGINX config (manage SSL manually).
certbot certonly --nginx -d example.comcertbot renew --dry-run — Simulate the automatic renewal process to verify it would succeed.
certbot renew --dry-runcertbot renew — Renew all certificates that are due for renewal (run via cron or systemd timer).
certbot renewcertbot certificates — List all managed Let's Encrypt certificates and their expiry dates.
certbot certificatesopenssl 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.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crtopenssl dhparam -out /etc/nginx/dhparam.pem 2048 — Generate a Diffie-Hellman parameter file for stronger SSL key exchange.
openssl dhparam -out /etc/nginx/dhparam.pem 2048openssl s_client -connect example.com:443 -servername example.com — Test an SSL connection and inspect the certificate chain.
openssl s_client -connect example.com:443 -servername example.comDebugging & Inspection
curl -I http://localhost — Send a HEAD request to the local NGINX and inspect response headers.
curl -I http://localhostcurl -I -H 'Host: example.com' http://localhost — Test a specific virtual host by overriding the Host header.
curl -I -H 'Host: example.com' http://localhostcurl -sk https://localhost -o /dev/null -w '%{http_code}' — Check the HTTP status code returned by NGINX over HTTPS.
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.
nginx -T | grep -A5 'server_name example.com'ss -tlnp | grep nginx — Show which ports NGINX is listening on.
ss -tlnp | grep nginxstrace -p $(cat /var/run/nginx.pid) -e trace=network — Trace network system calls of the NGINX master process for low-level debugging.
strace -p $(cat /var/run/nginx.pid) -e trace=network 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.
Further Reading
- nginx – official documentation – reference of all directives and modules
- Nginx – Wikipedia – background and history