diff --git a/Makefile b/Makefile index 5154ef1..370ed30 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ WEB_HOST ?= $(REMOTE_HOST) REMOTE_TARGETS := remote-env-setup remote-env-remove remote-wipe remote-install \ remote-fetch remote-fetch-content remote-install-plugins remote-update-plugins \ remote-upgrade-grav remote-git-sync-disable remote-git-sync-enable \ - remote-content-status remote-clean remote-diag remote-apply-env \ + remote-content-status remote-clean remote-warmup remote-diag remote-apply-env \ remote-seed-api-salt remote-secrets-audit \ remote-gpm-install remote-maintenance-on remote-maintenance-off \ remote-apply-plugin-patches @@ -284,6 +284,27 @@ remote-content-status: guard-env remote-clean: guard-env $(SSH) "cd $(WEBROOT) && php bin/grav clearcache" +# Post-deploy cache refresh: clear, then WARM. A `reset --hard` content deploy +# leaves Grav's compiled-Twig/page cache stale, and the first real visitor pays +# the recompile cost — so clear it and pre-render the public pages ourselves. +# Grav has no native warmup command, so this is an HTTP crawl of the live site: +# homepage + trips listing + every trip page linked from it (no sitemap plugin +# installed, so we scrape the listing instead of /sitemap.xml). The crawl runs +# from here over public HTTPS, so it also doubles as a smoke test — a non-200 on +# `/` is surfaced loudly. Run after every content deploy: `make remote-warmup-prod`. +remote-warmup: guard-env + $(SSH) "cd $(WEBROOT) && php bin/grav clearcache" >/dev/null + @base="https://$${WEB_HOST:-$(REMOTE_HOST)}"; \ + echo "warming $$base (clear done) ..."; \ + trip_urls=$$(curl -s "$$base/trips" | grep -oE '/trips/[a-z0-9][a-z0-9-]*' | sort -u); \ + fail=0; \ + for u in / /trips $$trip_urls; do \ + code=$$(curl -s -o /dev/null -w '%{http_code}' "$$base$$u"); \ + printf ' %-40s %s\n' "$$u" "$$code"; \ + case "$$code" in 2*|3*) ;; *) fail=1;; esac; \ + done; \ + if [ "$$fail" = 1 ]; then echo "WARNING: one or more pages returned a non-2xx/3xx status"; else echo "warmup OK — all pages 2xx/3xx"; fi + # Install a single GPM package on the server (e.g. git-sync, which is # intentionally NOT in plugins.txt — it is remote-only). # Usage: make remote-gpm-install-prod PKG=git-sync diff --git a/docs/guides/deploy-cycle.md b/docs/guides/deploy-cycle.md index 08e880a..08da316 100644 --- a/docs/guides/deploy-cycle.md +++ b/docs/guides/deploy-cycle.md @@ -73,8 +73,17 @@ make remote-upgrade-grav-test # 2. gpm self-upgrade (rewrites sche make remote-update-plugins-test # 3. gpm update the plugins.txt set (auto-applies deploy/patches/) make remote-gpm-install-test PKG=git-sync # 4. EXPLICITLY (re)install each remote-only plugin make remote-apply-env-test # 5. re-deploy the env override (not synced; gone after install) +make remote-warmup-test # 6. clear + warm cache — a reset deploy leaves it stale ``` +> **Always finish a deploy with `remote-warmup-`** — even a content-only +> deploy. A `reset --hard` (step 1) changes files under Grav without going +> through it, so the compiled-Twig/page cache is stale and the first visitor +> eats the recompile. `remote-warmup` clears the cache, then crawls the public +> pages (homepage + trips listing + every trip page linked from it) to +> pre-render them. Grav has no native warmup command — this is an HTTP crawl, so +> it also doubles as a smoke test (a non-2xx on any page is flagged loudly). + Why each matters: - **Step 3** re-applies `deploy/patches/*.patch` automatically (it chains `remote-apply-plugin-patches`). GPM install/update lays down **pristine** third-party plugins, wiping local fixes to git-ignored `user/plugins/` — the patch step restores them. Content pulls (step 1) do **not** touch `plugins/`, so the patch only needs re-applying after a GPM op, not after every sync. Run `make remote-apply-plugin-patches-test` standalone if you ever GPM-install outside this sequence. Requires the `patch` tool on the server. See `deploy/patches/README.md`. - **Step 4** is non-optional even if git-sync "was already there" — remote-only plugins are not in `plugins.txt`, so nothing in steps 1–3 restores them. If the code is missing, the plugin is inert despite valid config. @@ -111,6 +120,7 @@ make remote-upgrade-grav-prod make remote-update-plugins-prod make remote-gpm-install-prod PKG=git-sync make remote-apply-env-prod +make remote-warmup-prod # clear + warm cache; also HTTP-smokes public pages # ── smoke checklist (same as test) ── make remote-git-sync-enable-prod ```