Step 4: General housekeeping (drop.conf)
These are sensible defaults to include in any Nginx server block:
# Let's Encrypt renewal path
location ~ /.well-known/acme-challenge {
root /usr/share/nginx/html;
allow all;
}
# Deny access to common sensitive/config files
location ~* \.(yml|yaml|env|bak|swp|dist|config)$ {
deny all;
access_log off;
log_not_found off;
}
# Deny hidden files (anything starting with a dot)
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny backup files ending with ~
location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}
# Quietly handle favicon.ico — serve it if it exists, otherwise return 204
location = /favicon.ico {
access_log off;
log_not_found off;
try_files $uri =204;
}
# Handle robots.txt — Bludit doesn't generate one by default,
# but if you add a static file it'll be served
location = /robots.txt {
try_files $uri /index.php;
}
None of these are Bludit-specific — they're good practice for any site. The robots.txt handler falls back to index.php so that plugins (like a sitemap/SEO plugin) can generate one dynamically.
Step 5: Static file caching
Bludit serves most of its assets as static files — CSS, JS, fonts, images. Caching them aggressively at the Nginx level keeps your server snappy:
# static_caching.conf
# Images and fonts — immutable, cache as long as possible
location ~* \.(png|jpg|jpeg|gif|ico|webp|woff2|woff|ttf)$ {
try_files $uri =404;
expires max;
add_header Pragma public;
add_header Cache-Control "public, no-transform";
}
# CSS, JS, SVG, text — cache aggressively but allow revalidation
location ~* \.(css|js|html|htm|txt|xml|svg)$ {
gzip_static on;
try_files $uri =404;
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
gzip_static on tells Nginx to serve pre-compressed .gz versions of files when the client supports it — so style.css.gz gets served instead of style.css with on-the-fly compression. If you're minifying your assets during the build step, gzip them too and Nginx will use them directly.
The try_files $uri =404; in both blocks prevents PHP from processing requests for missing static files — a missing image returns a clean 404 instead of firing up Bludit.
Step 6: PHP-FPM configuration
A clean PHP handler for Bludit:
# php.conf
location ~ \.php$ {
try_files $uri =404;
fastcgi_intercept_errors off;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
What each directive does:
try_files $uri =404;— Prevents PHP from executing non-existent scripts. A request for/wp-login.phpon a Bludit site returns 404 instead of passing it to PHP-FPM.fastcgi_intercept_errors off;— Lets Bludit handle its own error pages rather than Nginx intercepting them.- The
fastcgi_paramsinclude ships with your Nginx installation. If you set up PHP-FPM from scratch, make sure it containsfastcgi_param SCRIPT_FILENAME $request_filename;— some minimal distributions omit it.
On a production site with image galleries or busy comment sections, you may want to limit concurrent PHP connections to prevent a single visitor from hogging resources:
# Inside the php.conf location block:
limit_conn phplimit 10;
This requires a limit_conn_zone defined in your main nginx.conf:
limit_conn_zone $binary_remote_addr zone=phplimit:10m;
Step 7: The sitemap plugin
Bludit's sitemap plugin writes sitemap.xml inside /bl-content/workspaces/sitemap/, not the document root. To expose it at the standard /sitemap.xml URL, add an alias:
location = /sitemap.xml {
alias /var/www/mysite.com/public_html/bl-content/workspaces/sitemap/sitemap.xml;
}
This location block must come before the generic location / block so it matches first.