← Start of tutorial

WIUNIX ACADEMY

Install WordPress on Nginx with a privacy-safe FastCGI cache

Page 5 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.

Rhel 10.2Reviewed against official documentation ·

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

Require installer HTTP 200 from the permitted client

Run from the permitted workstation. TLS verification remains enabled. From a separate unpermitted network, repeat the same check expecting 403 instead; do not use that negative result to continue installation there.

Bash

Allowed workstation, Bash with curl.

(
set -euo pipefail
work=$(mktemp -d)
code=$(curl -sS --connect-timeout 5 --max-time 20 -D "$work/installer.h" -o "$work/installer.html" -w '%{http_code}' https://blog.example.com/wp-admin/install.php)
[ "$code" = 200 ]
grep -F 'name="weblog_title"' "$work/installer.html"
grep -F 'name="user_name"' "$work/installer.html"
grep -F 'id="setup"' "$work/installer.html"
)
How do I know it worked?

Trusted HTTPS, exact 200 and an actual WordPress installer body.

19

LET’S BUILD

Finish installation behind the IP gate

From the allowed workstation open the HTTPS installer URL below. Choose a site title, unique non-default administrator name, strong password and real email; complete Install WordPress, sign in and confirm the dashboard. Keep credentials out of evidence. On STAGING, edit the existing Sample Page (do not create a conflicting slug) so its slug is sample-page and body includes PUBLIC_CACHE_MARKER. Create a separate Home page with PUBLIC_HOME_MARKER; choose it in Settings → Reading as static homepage. Choose Post name permalinks and save. Keep sample-page public; create a DIFFERENT password-protected page at locked-test with body LOCKED_CONTENT_MARKER. Use two staging accounts whose display names are CACHE_USER_A and CACHE_USER_B, with front-end toolbar enabled in both profiles. Each signed-in browser must show its own toolbar name; private browsing must show neither. These real markers drive the following body tests.

URL

Allowed workstation browser address bar, not the server shell.

https://blog.example.com/wp-admin/install.php
How do I know it worked?

Dashboard works, tables exist, public home/sample and separate locked page render with cache still off.

20

LET’S BUILD

Verify the installed database and public body

Run on the permitted administrator workstation. Replace YOUR_PUBLIC_SITE_TITLE with the actual title and require exact200 plus the intended site body. A redirect back to the installer is failure. Check tables separately on the server in the next panel.

Bash

Permitted administrator workstation with Bash and curl.

(
set -euo pipefail
work=$(mktemp -d)
code=$(curl -sS --connect-timeout 5 --max-time 20 -o "$work/public.html" -w '%{http_code}' https://blog.example.com/)
[ "$code" = 200 ]
grep -F 'YOUR_PUBLIC_SITE_TITLE' "$work/public.html"
)
How do I know it worked?

The public homepage returns200 and contains the actual site title.

21

LET’S BUILD

Verify the installed tables locally

Run this separately on the server with the existing local database administrator. The preceding HTTPS body request belongs on the permitted workstation; do not broaden the installation gate to let the server curl itself.

Bash

WordPress server, existing sudo administrator.

sudo mariadb wordpress -e "SHOW TABLES LIKE 'wp_options';"
How do I know it worked?

wp_options exists.

Keep a verified configuration checkpoint

The root-only checkpoint preserves paths and compares both files before opening the editor. Keep its printed location. This is a configuration backup, not a database/uploads backup.

Bash

WordPress server, Bash, existing sudo administrator.

(
set -euo pipefail
sudo sh -eu <<'SAVE'
umask 077
test ! -L /root/academy-backups
if test -e /root/academy-backups; then
  test -d /root/academy-backups
  test "$(stat -c '%u:%a' /root/academy-backups)" = 0:700
fi
install -d -m 0700 /root/academy-backups
backup=$(mktemp -d /root/academy-backups/wp-nginx-XXXXXXXX)
cp -a --parents /etc/nginx/conf.d/wordpress-site.conf /etc/nginx/conf.d/wordpress-cache.conf "$backup/"
cmp /etc/nginx/conf.d/wordpress-site.conf "$backup/etc/nginx/conf.d/wordpress-site.conf"
cmp /etc/nginx/conf.d/wordpress-cache.conf "$backup/etc/nginx/conf.d/wordpress-cache.conf"
printf 'Verified pre-cache configuration: %s\n' "$backup"
SAVE
sudo nano /etc/nginx/conf.d/wordpress-site.conf
)
How do I know it worked?

Check succeeds; stop on an error before continuing.

22

LET’S BUILD

Enable the reviewed public cache

In the existing PHP location replace only the cache-off line below. Keep both bypass and no-cache and the staging IP gate. Default Nginx handling of Set-Cookie, Cache-Control private/no-cache/no-store, Vary and X-Accel-Expires must remain intact. Never add fastcgi_ignore_headers or hide cookies to force HIT. A public successful 200 gets a fallback 60-second TTL; upstream expiration controls can take precedence. Personalized plugins without correct cookies/headers cannot be made safe by a cache header alone; keep such URLs outside the allowlist.

Nginx · /etc/nginx/conf.d/wordpress-site.conf (existing PHP location)

File contents; save in the named file, not the shell.

# In the PHP location, replace ONLY the existing cache-off line:
fastcgi_cache WORDPRESS;
How do I know it worked?

Check succeeds; stop on an error before continuing.

Explore all tutorials ↗