WIUNIX ACADEMY
Install WordPress on Nginx with a privacy-safe FastCGI cache
Page 7 of 8. Review the earlier steps and prerequisites before continuing.
YOUR SYSTEM. YOUR STEPS.
Where are you working?
Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.
USE YOUR OWN VALUES
Configure this tutorial
Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.
Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.
Set values for my environment4 editable values
Invalidate without deleting active cache files
No purge API/module is assumed. For urgent changes disable cache or remove the public URL BEFORE changing its privacy, then select a never-used generation in the next panel and validate/reload. This invalidates the whole small site, not one URL. Old files are unreachable by new keys and expire by inactive/size controls. Never revert to an old generation. Normal WordPress publication does not trigger this cache invalidation; content can remain until its actual upstream/fallback TTL. In staging, change the marker to PUBLIC_CACHE_MARKER_V2, rotate generation, then repeat the anonymous test using the new marker and require the old content absent.
WordPress server, Bash, existing sudo administrator.
sudo nano /etc/nginx/sites-available/wordpress
Check succeeds; stop on an error before continuing.
Rotate the cache generation
Replace the existing key line, never add a duplicate. Use a never-used generation, then the earlier guarded validation/reload panel.
File contents; save in the named file, not the shell.
# Replace the previous key directive with this NEW generation:
fastcgi_cache_key "$scheme|$request_method|$host|$request_uri|wp-v2";
Check succeeds; stop on an error before continuing.
Retain the site while disabling caching
If a user sees another user’s content, disable caching immediately with the next line and the earlier guarded reload. Also invalidate existing outer CDN/distributed copies through their owning workflow and investigate the exposure. Keep WordPress files, database, uploads, accounts and certificates. Do not delete active cache directories.
WordPress server, Bash, existing sudo administrator.
sudo nano /etc/nginx/sites-available/wordpress
Check succeeds; stop on an error before continuing.
LET’S BUILD
Return to direct PHP without deleting data
Replace the cache-selection line only; keep the zone while references remain. After validation/reload, body/session tests must still pass, with X-WP-Cache absent rather than HIT/BYPASS. Correct the policy and use a fresh generation before re-enabling. Existing cache files can expire normally.
File contents; save in the named file, not the shell.
# In the PHP location, replace WORDPRESS with off:
fastcgi_cache off;
WordPress works through PHP; cache off, all site data retained.
LET’S BUILD
Back up before controlled maintenance
Optional maintenance: first suspend editorial/plugin/schema changes and uploads through your existing maintenance access process. The dump is transaction-consistent for InnoDB, but does not synchronize uploaded files or non-transactional plugin tables. File comparison fails safely if the tree changes. This is not an atomic online whole-site backup; use a maintenance window or your established consistent backup workflow. Original files/data stay in place. Local checksums/read-back/comparison do NOT prove SQL restorability. Before destructive retirement/migration, restore into an ISOLATED recovery environment, verify login/content/uploads, and keep an encrypted off-host copy using your existing backup system. Never restore-test over the live database. Plan administrator-controlled core/theme/plugin updates from official sources, then repeat privacy tests.
WordPress server, Bash, existing sudo administrator.
sudo sh -eu <<'BACKUP'
umask 077
install -d -m 0700 /root/academy-backups
backup=$(mktemp -d /root/academy-backups/wordpress-XXXXXXXX)
mariadb-dump --single-transaction --quick --databases wordpress > "$backup/wordpress.sql"
test -s "$backup/wordpress.sql"
tar -C / -cpf "$backup/wordpress-files.tar" var/www/wordpress etc/nginx/sites-available/wordpress etc/nginx/conf.d/wordpress-cache.conf etc/php/8.5/fpm/pool.d/wordpress.conf
cd "$backup"
sha256sum wordpress.sql wordpress-files.tar > SHA256SUMS
sha256sum -c SHA256SUMS
tar -tf wordpress-files.tar >/dev/null
tar -C / -df wordpress-files.tar
printf 'Verified local files and dump: %s\n' "$backup"
BACKUP
Root-only archive/dump pass local checks; original data retained. SQL restore remains a separate required recovery test.
Diagnose the failing boundary
Keep private logs and cookies local. Each disclosure has separate executable diagnostics.
Check succeeds; stop on an error before continuing.
PHP returns 502
Compare actual socket, selected service and permissions; restart does not fix a wrong path.
sudo nginx -t
sudo systemctl status php8.5-fpm --no-pager
sudo journalctl -u php8.5-fpm -n 50 --no-pager
sudo stat /run/php/wordpress.sock
sudo -u www-data test -w /run/php/wordpress.sockDatabase connection fails
Check local authentication, schema grants and file readability without printing secrets.
sudo systemctl status mariadb --no-pager
sudo journalctl -u mariadb -n 50 --no-pager
mariadb -u wp_site -p wordpress -e 'SELECT 1;'
sudo -u wp-php test -r /var/www/wordpress/wp-config.phpNo HIT or wrong body
Disable cache first for wrong content. Cookies/queries/Set-Cookie/private/no-store can correctly prevent storage. Check disk/inodes, never suppress headers to force HIT. This request may warm the public URL.
sudo nginx -t
sudo df -h /var/cache/nginx/wordpress
sudo df -i /var/cache/nginx/wordpress
sudo du -sh /var/cache/nginx/wordpress
curl -sS --connect-timeout 5 --max-time 20 -D - -o /dev/null https://blog.example.com/sample-page/TLS or renewal fails
Compare DNS, challenge reachability and matching certificate. Repair the cause, do not bypass certificate checks.
getent ahosts blog.example.com
sudo nginx -t
sudo certbot certificates
sudo journalctl -u nginx -n 50 --no-pager