nginx — web server and reverse proxy
cheat sheet · Ubuntu 24.04 · nginx 1.24 https://lab.dimsanych.ru/en/wiki/nginx/Cheat sheet
-
sudo nginx -tcheck the config (sudo only) -
sudo systemctl reload nginxapply, keep connections -
sudo nginx -T | grep -n server_namewhich sites nginx sees -
ls -l /etc/nginx/sites-enabled/enabled sites -
curl -i -H 'Host: docs.lab.test' http://127.0.0.1/who answers -
sudo tail -n 5 /var/log/nginx/error.logwhy 404, 403, 502 -
sudo tail -n 5 /var/log/nginx/access.logwhat was asked, the code -
sudo ss -tlnp | grep nginxwhich ports it listens on
Configuration
The Debian and Ubuntu layout:
/etc/nginx/nginx.conf— common settings, with anincludeof sites at the bottom;/etc/nginx/sites-available/— site files;/etc/nginx/sites-enabled/— links to enabled sites; nginx reads only these;/var/log/nginx/access.loganderror.log— the logs.
Enable a site
A file in sites-available without a link in sites-enabled is invisible to
nginx. To disable a site, remove the link; the file stays.
nginx -t checks the whole config and names the file and line of an error.
reload re-reads the config without dropping connections; with an error in the
config nginx keeps the old one. systemctl reload returns at once, while the
new worker processes take connections a moment later: a curl on the same
line may still see the old state.
Logs
access.log has a line for every request, error.log says why a request
failed and what broke at start. The default access.log format is
combined:
Field by field: $remote_addr (client address), -, $remote_user,
[$time_local], "$request" (method, path, version), $status (code),
$body_bytes_sent (body size), "$http_referer", "$http_user_agent" — the
user agent "curl/8.5.0" did not fit in the example. log_format defines
your own format — in a site file outside the server block:
$request_time is how many seconds nginx spent on the request. Files with
.1 and .2.gz next to a log are older ones that logrotate moves aside and
compresses on schedule (/etc/logrotate.d/nginx).
Proxy: path and headers
Whether there is a URI after the address in proxy_pass decides which path the
application receives:
location /api/ and proxy_pass |
Request /api/x goes out as |
|---|---|
http://127.0.0.1:3003 |
/api/x — path unchanged |
http://127.0.0.1:3003/ |
/x — /api/ replaced with / |
By default the application sees Host: 127.0.0.1:3003 — the address from
proxy_pass. The site name and the client address are passed in headers:
HTTPS and the redirect from HTTP
ssl_certificate is the chain file: the site
certificate first, the intermediate after it. $request_uri is the path with
the query after ?: http://shop.lab.test/x?y=1 redirects to
https://shop.lab.test/x?y=1. Certificates and how they are checked —
openssl-tls.