Nginx is a high-performance HTTP server and reverse proxy, widely used to serve static files, terminate SSL, and forward requests to application backends such as PHP-FPM or Node.js.
Nginx ("engine-x") acts as the entry point for web traffic on your server. It listens on ports 80 (HTTP) and 443 (HTTPS), reads its configuration to determine how to handle each request, and either serves a file directly or proxies the request to another process.
In a typical PHP stack, Nginx handles the connection and static assets, while dynamic requests are passed to PHP-FPM. A separate process that executes PHP and returns the result. Nginx then sends that result back to the client.
SSL termination also happens at Nginx. It decrypts the incoming HTTPS request, processes it, and can optionally re-encrypt traffic before forwarding it upstream.
The configuration below is a clean, production-ready nginx server block for a PHP site with SSL. It covers HTTPS, a redirect from HTTP, the web root, and PHP-FPM passthrough.
# ----------------------------------------------- # HTTP → HTTPS redirect # ----------------------------------------------- server { listen 80; listen [::]:80; server_name panel.yourdomain.com; return 301 https://$host$request_uri; } # ----------------------------------------------- # Main HTTPS server block # ----------------------------------------------- server { listen 443 ssl; listen [::]:443 ssl; server_name panel.yourdomain.com; # --- SSL certificates (Cloudflare Origin) --- ssl_certificate /etc/ssl/cf/origin.pem; ssl_certificate_key /etc/ssl/cf/origin.key; # --- Modern SSL settings --- ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; # --- Web root --- root /var/www/yoursite/public; index index.php index.html; # --- Try file, then directory, then 404 --- location / { try_files $uri $uri/ /index.php?$query_string; } # --- PHP-FPM passthrough --- location ~ \.php$ { fastcgi_pass unix:/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } # --- Block access to hidden files (.env, .git, etc.) --- location ~ /\. { deny all; } # --- Static asset caching --- location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff2)$ { expires 30d; add_header Cache-Control "public, no-transform"; } }
After saving the file, enable it and reload Nginx:
ln -s /etc/nginx/sites-available/yoursite.conf \ /etc/nginx/sites-enabled/
nginx -t systemctl reload nginx
server_name The domain(s) this block responds to. Nginx matches the host header of the request against this value.
server_name
root — The filesystem path Nginx looks in when serving files. For PHP frameworks like Laravel, this should point to the public/ subfolder, not the project root.
root
public/
try_files $uri $uri/ /index.php?$query_string Nginx first checks if the request maps to a real file and if not then it checks for a directory. Finally it falls back to index.php. This is required for single-entry-point frameworks.
try_files $uri $uri/ /index.php?$query_string
index.php
fastcgi_pass unix:/run/php/php8.2-fpm.sock Hands the request to PHP-FPM via a Unix socket. Adjust the PHP version in the path to match the version installed on your machine. (php8.1-fpm.sock, php8.3-fpm.sock, etc.).
fastcgi_pass unix:/run/php/php8.2-fpm.sock
php8.1-fpm.sock
php8.3-fpm.sock
location ~ /\. This blocks any request whose path contains a dot-prefixed segment. This prevents access to .env, .git, and similar sensitive files.
location ~ /\.
.env
.git
nginx -t
systemctl reload nginx
systemctl restart nginx
tail -f /var/log/nginx/error.log