Files
intotheeast-com/docs/superpowers/specs/2026-06-18-grav2-upgrade-design.md
T
2026-06-18 23:00:02 +02:00

6.3 KiB

Grav 2.0 Upgrade — Design Spec

Goal: Upgrade the intotheeast travel blog from Grav 1.7.x to Grav 2.0 RC on a feature branch, validate full Milestone 1 functionality, and prepare a clean production fresh-install path.

Context: Departure date is 2026-07-15. The production server has never been deployed, so production gets a fresh Grav 2.0 install — no in-place migration required. Local dev uses Docker; production uses PHP 8.4 directly.


Scope

Two tracks:

  1. Local dev track — swap Docker image to Grav 2.0, validate all functionality
  2. Production track — update server-install.sh and .env so make remote-install deploys Grav 2.0 fresh

All work on branch update-to-2.0.


Compatibility Assessment

Component Status Action required
form, login, email, error, problems, flex-objects First-party Auto-updated to 2.0 versions via GPM
shortcode-core First-party Same
cache-on-save (custom) Should work Add Grav 2.0 compat flag to blueprints.yaml; uses onFormProcessed which is unchanged
shortcode-gallery-plusplus Likely works Plugin arch unchanged; test and confirm
add-page-by-form ⚠️ Archived Aug 2024 Try as-is (plugin arch unchanged, may work); if broken, write a custom replacement
Custom intotheeast theme Should work Twig 3 compat mode covers existing templates; test rendering
linuxserver/grav Docker image Not supported Replace with getgrav/grav + GRAV_CHANNEL=beta

Track 1 — Local Dev

Changes

docker-compose.yml

Replace:

image: lscr.io/linuxserver/grav:latest
environment:
  - PUID=1000
  - PGID=1000
volumes:
  - ./user:/config/www/user

With:

image: getgrav/grav
environment:
  - GRAV_CHANNEL=beta
volumes:
  - ./user:/var/www/html/user

Makefile — three targets reference the linuxserver internal path /app/www/public; replace with /var/www/html:

  • install-plugins: docker exec -w /app/www/publicdocker exec -w /var/www/html
  • demo-load clear cache: /app/www/public/var/www/html
  • demo-reset clear cache: same

user/plugins/cache-on-save/blueprints.yaml (create — does not exist yet) — minimal blueprint with Grav 2.0 compat flag:

name: Cache On Save
version: 1.0.0
description: Clears Grav cache on new-entry form submission
author:
  name: Mischa
license: MIT

dependencies:
  - { name: grav, version: '>=1.6.0' }

grav:
  version: ['1.7', '2.0']

user/config/system.yaml — switch GPM to testing channel so make setup resolves 2.0-compatible plugin versions:

gpm:
  releases: testing

Validation Checklist (smoke test after make setup)

Run in order — stop and investigate if any step fails:

  1. Site loadshttp://localhost:8081 returns the tracker page (200, no PHP errors)
  2. Admin2 loads/admin renders the new SPA admin (not the old Twig admin)
  3. Login works — log in via Admin2 with existing credentials
  4. Posting form — submit /post form with title + text; entry appears immediately in /tracker
  5. Photo upload — submit /post form with a photo; image renders in the entry
  6. Gallery — visit an entry with multiple photos; shortcode-gallery-plusplus renders gallery with lightbox
  7. Cache invalidation — submit a second post; it appears without a manual cache clear (validates cache-on-save)
  8. Theme rendering — check tracker, entry, map, post-form, and stats templates for layout/CSS regressions
  9. Playwright suitemake test-ui passes all 25 tests. If any tests fail, investigate whether the failure is a genuine regression (blocker) or a test that needs updating for Admin2's new DOM structure (acceptable — update the test)

If add-page-by-form fails

If step 4 fails due to add-page-by-form incompatibility, the fallback is to write a custom replacement plugin. The existing cache-on-save plugin is a good template — it hooks onFormProcessed and that API is unchanged. The replacement would use the same hook to:

  1. Build the page path and slug from form fields
  2. Create the page file on disk (same logic add-page-by-form does in PHP)
  3. Clear cache (merging cache-on-save functionality)

This is ~1 day of work and should be planned as a follow-up task if needed.


Track 2 — Production (Fresh Install)

Production has PHP 8.4 (compatible with Grav 2.0's PHP 8.3+ requirement) and has never been deployed.

Changes

server-install.sh — the download URL for Grav 2.0 RC requires a ?testing query parameter:

Current:

wget --no-verbose "https://getgrav.org/download/core/grav-admin/$GRAV_VERSION" -O grav-admin.zip

Updated (conditionally append ?testing for pre-release versions, or accept a full URL suffix via env var):

wget --no-verbose "https://getgrav.org/download/core/grav-admin/${GRAV_VERSION}${GRAV_CHANNEL_SUFFIX}" -O grav-admin.zip

Where GRAV_CHANNEL_SUFFIX is ?testing for RC versions and empty for stable.

.env (not committed — edit on the server directly or locally before make remote-install) — update:

GRAV_VERSION=2.0.0-rc.9
GRAV_CHANNEL_SUFFIX=?testing

When Grav 2.0 goes stable, remove GRAV_CHANNEL_SUFFIX and update GRAV_VERSION to the stable version number.

user/config/system.yaml — keep gpm.releases: testing (already set in Track 1) so production also installs 2.0-compatible plugin versions.

Production deploy

When local validation passes:

make remote-install

That's it — fresh Grav 2.0 install from scratch with all plugins, content from Gitea, and the existing user/ config.


Out of Scope

  • MCP server setup (grav-mcp Node.js binary) — a separate task after Grav 2.0 is stable on production
  • Admin2 theming or customization
  • Grav 2.0 REST API integration
  • Switching add-page-by-form to the API-based approach (only if the plugin breaks)

Go/No-Go Criteria

Ship to production before departure (2026-07-15) only if:

  • All 9 smoke test steps pass
  • Playwright suite passes
  • add-page-by-form posting workflow works end-to-end (or a custom replacement is in place and tested)

If any of these fail and cannot be resolved with time to spare before departure, stay on Grav 1.7 for the trip and revisit post-trip.