Files
intotheeast-com/docs/guides/local-setup.md
m038andClaude Opus 4.8 0f6b1e69cd docs: capture local Grav core upgrade + refresh version-authority docs
New learning: docs/solutions/tooling-decisions/upgrade-local-grav-core-rebuild-docker-image.md
— the local Grav core is baked into the Docker image (only ./user is bind-mounted),
so it upgrades by a Dockerfile URL bump + image rebuild + `docker rm -f` recreate,
not the `gpm self-upgrade` the servers use (non-durable in-container).

Refreshed three docs this exposed as stale/incomplete:
- local-setup.md: rewrote the stale "newer Grav RC" section with the durable
  rebuild procedure (recreate gotcha, verify, plugin refresh, non-durability note).
- deploy-cycle.md: Phase 0 now upgrades the local core; state-model notes the
  image as a fourth surface beyond the three server layers.
- stale-grav-version-blocks-api-plugin-install.md: version-authority surfaces
  3 -> 4 (hardcoded Dockerfile URL); clarified .env* GRAV_VERSION governs fresh
  remote installs only, never the local Docker core.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
2026-07-05 12:05:51 +02:00

135 lines
3.8 KiB
Markdown

# Local Development Setup
This guide covers setting up the dev environment from scratch after cloning the repo.
---
## First-time setup
`user/plugins/` and `user/data/` are excluded from git but Grav requires them to exist. Create them once:
```bash
mkdir -p user/plugins user/data
```
Then run:
```bash
make setup
```
`make setup` = `build → start → install-plugins → fix-perms`. This builds the Docker image (Grav 2.0 baked in), starts the container, installs all plugins from `plugins.txt`, and fixes file ownership.
The dev server runs at **http://localhost:8081**.
---
## After any docker compose down
Always run `make setup` — not just `make start` — to ensure permissions are correct.
`docker compose restart` (soft restart) preserves the image and is fine for quick restarts. Only `make setup` is needed after `docker compose down`.
---
## Fix 500 errors after plugin install
If the site returns a 500 error after plugin installation or after recreating the container:
```bash
make fix-perms
```
This creates uid 1000 in the container, chowns `/var/www/html` to 1000:1000, and reloads Apache.
---
## Upgrading the Grav core
The Grav core is baked into the custom Docker image via `Dockerfile`. The base
`getgrav/grav` image ships 1.7 — the `Dockerfile` downloads the pinned stable bundle
(`grav-admin-v<version>.zip`) from GitHub and overwrites the core files at build time.
`docker-compose.yml` volume-mounts only `./user`, so the core lives in the **image
layer**. That means you upgrade the core by rebuilding the image, **not** by running
`gpm self-upgrade` inside the container — an in-container self-upgrade is lost on the
next rebuild. (The servers are the opposite: no image, so they self-upgrade in place.)
To upgrade:
1. Bump **both** occurrences of the version in the `Dockerfile` release URL (the
`/download/<ver>/` path and the `grav-admin-v<ver>.zip` filename). Note: the
`GRAV_VERSION` in `.env*` does **not** drive this build — it only pins fresh
*remote* installs.
2. Rebuild: `docker compose build grav`.
3. Recreate the container. `docker compose up -d` won't replace an already-running
container with a fixed `container_name` (it errors `Conflict … name … already in
use`), so remove it first — safe because `./user` is a bind mount:
```bash
docker rm -f intotheeast_grav && docker compose up -d grav
```
4. Verify: `docker exec -w /var/www/html intotheeast_grav php bin/grav --version`.
5. Refresh plugins and clear cache: `make install-plugins` then
`docker exec -w /var/www/html intotheeast_grav php bin/grav cache`.
Full rationale and the server-vs-local contrast:
`docs/solutions/tooling-decisions/upgrade-local-grav-core-rebuild-docker-image.md`.
---
## Required system.yaml settings (Grav 2.0)
After upgrading, verify these are set in `user/config/system.yaml`:
```yaml
accounts:
type: flex # required for Admin2 API
pages:
type: flex # required for Admin2 pages API
```
---
## Admin user API permissions
The admin user account needs `api.*` permissions for Admin2. In `user/accounts/<username>.yaml`:
```yaml
access:
admin:
login: true
super: true
api:
super: true
access: true
```
---
## Disable the old admin plugin
Both `admin` and `admin2` route to `/admin` and conflict. After installing `admin2`, disable the old one:
In `user/plugins/admin/admin.yaml`:
```yaml
enabled: false
```
---
## JWT secret
Leave `jwt_secret: ''` in `user/plugins/api/api.yaml`. It works for local dev; production installs generate a secure secret automatically during `make remote-install`.
---
## Language URL prefix
If Grav redirects to `/en/...` URLs, ensure `user/config/system.yaml` contains:
```yaml
languages:
supported: [en]
include_default_lang: false
```
Without `include_default_lang: false`, Grav adds a language prefix to all URLs even for single-language sites.