To install Bludit CMS with Nginx on Rocky Linux 8, you will configure PHP-FPM, SELinux, firewalld, and HTTPS before opening Bludit’s browser installer. A fresh VPS with DNS ready should be publishing a working flat-file site in about 15 minutes, without MariaDB or MySQL.
Prerequisites
- A fresh Rocky Linux 8.10 VPS with at least 1 GB RAM, 10 GB of free disk space, and a public IPv4 address.
- Root access or a sudo-enabled user connected over SSH. The commands below use
sudo. - A domain such as
YOUR_DOMAINwith an A record pointing to the VPS. Keep TCP ports 80 and 443 available for the site and certificate validation. - A strong, unique Bludit administrator password stored in a password manager.
- A VPSLake Linux VPS is suitable for a small Bludit site.
- Bludit’s requirements call for PHP 8.0 or newer plus the
mbstring,gd,dom, andjsonmodules; this guide uses Rocky Linux 8’s PHP 8.2 AppStream.
Step 1: Install Nginx, PHP 8.2, and firewalld
Rocky Linux 8 uses DNF module streams, so select the PHP and Nginx versions before installing PHP-FPM and the extensions Bludit needs.
sudo dnf update -y
sudo dnf module reset nginx php -y
sudo dnf module enable nginx:1.24 php:8.2 -y
sudo dnf install -y epel-release
sudo dnf install -y firewalld nginx php php-fpm php-cli php-curl php-gd php-mbstring php-opcache php-xml php-zip curl unzip bind-utils certbot python3-certbot-nginx policycoreutils-python-utils
sudo sed -ri 's/^[;[:space:]]*user[[:space:]]*=.*/user = nginx/; s/^[;[:space:]]*group[[:space:]]*=.*/group = nginx/; s/^[;[:space:]]*listen\.owner[[:space:]]*=.*/listen.owner = nginx/; s/^[;[:space:]]*listen\.group[[:space:]]*=.*/listen.group = nginx/' /etc/php-fpm.d/www.conf
sudo systemctl enable --now firewalld nginx php-fpm
sudo systemctl restart php-fpm
php -v
php -m | grep -E 'dom|gd|json|mbstring'
The version should begin with PHP 8.2, and the module check should print dom, gd, json, and mbstring on separate lines. PHP-FPM’s Rocky Linux socket is /run/php-fpm/www.sock; the Nginx server block will use that path.
Step 2: Download Bludit and limit write access
Bludit stores pages, users, settings, and uploads as files, so protect the application code and give PHP-FPM write access only to bl-content.
Download the current Bludit 3.x release from the official distribution URL and unpack it under /var/www:
cd /tmp
curl -fL -o bludit-3.22.0.zip https://www.bludit.com/releases/bludit-3-22-0.zip
unzip -q bludit-3.22.0.zip -d /tmp
sudo install -d /var/www/bludit
sudo cp -a /tmp/bludit-3.22.0/. /var/www/bludit/
sudo chown -R root:nginx /var/www/bludit
sudo find /var/www/bludit -type d -exec chmod 0750 {} \;
sudo find /var/www/bludit -type f -exec chmod 0640 {} \;
sudo chown -R nginx:nginx /var/www/bludit/bl-content
sudo find /var/www/bludit/bl-content -type d -exec chmod 0770 {} \;
sudo find /var/www/bludit/bl-content -type f -exec chmod 0660 {} \;
The archive is pinned to 3.22.0 so a later release cannot silently alter the files during this setup. Do not make the entire document root writable: Bludit’s content directory is the part that must change when you create pages or upload media.
Rocky Linux 8 normally runs SELinux in enforcing mode. Add persistent labels for read-only application files and the writable content tree, then apply them:
sudo semanage fcontext -a -t httpd_sys_content_t '/var/www/bludit(/.*)?'
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/bludit/bl-content(/.*)?'
sudo restorecon -Rv /var/www/bludit
Step 3: Create the Nginx server block
Bludit’s router sends unknown paths to index.php, while the protected locations stop browsers from reading JSON content or executing PHP from the core directory.
Create /etc/nginx/conf.d/bludit.conf, replacing YOUR_DOMAIN with the hostname in DNS:
server {
listen 80;
listen [::]:80;
server_name YOUR_DOMAIN;
root /var/www/bludit;
index index.php;
client_max_body_size 16m;
location ^~ /bl-content/databases/ { deny all; }
location ^~ /bl-content/pages/ { deny all; }
location ^~ /bl-content/workspaces/ { deny all; }
location ^~ /bl-content/tmp/ { deny all; }
location ~* ^/bl-kernel/.*\.php$ { deny all; }
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_pass unix:/run/php-fpm/www.sock;
}
}
Write the file with your editor, then test the complete Nginx configuration before reloading it:
sudo vi /etc/nginx/conf.d/bludit.conf
sudo nginx -t
sudo systemctl reload nginx
The test should finish with:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
This server block deliberately starts with HTTP. Certbot will add the TLS listener after the domain resolves, so you do not have to reference certificate files that do not exist yet. Bludit’s official Nginx configuration documents the front-controller rule and protected directories.
Step 4: Open the firewall and enable HTTPS
Allow SSH for administration, HTTP for Let’s Encrypt validation, and HTTPS for the finished website; repeat these ports in any firewall provided by your VPS host.
sudo firewall-cmd --permanent --zone=public --add-service=ssh
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-services
dig +short YOUR_DOMAIN
The dig result must contain the VPS public IP before you request a certificate. Replace YOUR_EMAIL with an address that receives renewal notices, then run Certbot:
sudo certbot --nginx --redirect --agree-tos --no-eff-email -m YOUR_EMAIL -d YOUR_DOMAIN
Certbot should report that the certificate was successfully deployed. It will create the HTTPS server block and redirect normal HTTP requests to HTTPS.
Step 5: Complete the Bludit browser installer
The web installer writes the site configuration and administrator account into bl-content, so it does not ask for database host, user, or password values.
Open https://YOUR_DOMAIN in a browser. Select the language, enter a site name, choose an administrator username, and create a long unique password. Submit the form, sign in at the administrator URL shown by Bludit, and publish a small test page with an image.
If the installer reports that content is not writable, stop and repair ownership and the SELinux label before submitting the form again:
sudo chown -R nginx:nginx /var/www/bludit/bl-content
sudo restorecon -Rv /var/www/bludit/bl-content
sudo systemctl restart php-fpm
Verify the Bludit installation
Run these checks from SSH and then load the site in a private browser window. The private window confirms the certificate and administrator session without a cached HTTP redirect.
sudo systemctl is-active nginx php-fpm firewalld
sudo nginx -t
php -m | grep -E 'dom|gd|json|mbstring'
curl -fsSI https://YOUR_DOMAIN | head -n 1
curl -fsS -o /dev/null -w '%{http_code}\n' https://YOUR_DOMAIN/bl-content/databases/
Expected results are active for all three services, a successful Nginx test, the four PHP modules, an HTTPS status such as HTTP/2 200, and 403 for the protected database path. A 302 redirect or an installer page is normal if you have not finished the browser setup.
Troubleshooting
502 Bad Gateway
Nginx cannot reach PHP-FPM, commonly because the service is stopped or the socket path does not match the server block. Check sudo systemctl status php-fpm, then compare listen = in /etc/php-fpm.d/www.conf with /run/php-fpm/www.sock and restart PHP-FPM after correcting it.
Permission denied in the Nginx error log
The Unix socket or its SELinux context is preventing Nginx from contacting PHP-FPM. Confirm the socket with sudo ls -lZ /run/php-fpm/www.sock, verify the pool uses the nginx user and group, and run sudo systemctl restart php-fpm.
The home page works but a new page returns 404
The request is probably using a different server block or the front-controller fallback was edited. Run sudo nginx -T | grep -A8 -B2 'server_name YOUR_DOMAIN', confirm try_files $uri $uri/ /index.php?$args;, and reload Nginx after fixing the file.
Certbot reports a timeout or failed validation
The DNS record may still point elsewhere, or port 80 may be blocked by firewalld or an upstream VPS firewall. Compare dig +short YOUR_DOMAIN with the server’s public IP, allow HTTP in both firewalls, and run Certbot again after DNS updates.
Hardening and maintenance
- Back up
/var/www/bludit, especiallybl-content, before upgrades; it contains the site’s pages, users, settings, and uploads. - Keep Rocky Linux, PHP, Nginx, and Bludit updated, and take a backup before replacing files within the Bludit 3.x series.
- Test renewal with
sudo certbot renew --dry-runafter HTTPS is working. - Keep SELinux enforcing and give write access only to directories that Bludit or a trusted plugin actually needs.
FAQ
Why does this guide enable PHP 8.2 instead of Rocky’s default stream?
Rocky Linux 8’s default PHP stream is older, while its AppStream includes PHP 8.2. Bludit’s requirements call for PHP 8.0 or newer, so PHP 8.2 provides a compatible supported stream without adding a third-party repository.
Does Bludit need MariaDB or MySQL?
No. Bludit is a flat-file CMS and keeps content and configuration beneath bl-content. Your backup plan should therefore include the complete application directory rather than only a database dump.
Can I use an IP address instead of a domain?
You can test the HTTP server by IP, but a domain is the practical choice for a public installation. Let’s Encrypt cannot issue the normal certificate used here for an arbitrary server IP, and the installer’s HTTPS URL should use the hostname you configured.
Which Bludit directory needs the most protection?
Protect bl-content/databases, bl-content/pages, bl-content/workspaces, and bl-content/tmp from direct web requests because they contain site data. The Nginx rules also deny PHP execution beneath bl-kernel, reducing the impact of an accidental upload or misconfiguration.