m038 8c93dfd7c9 Sync local state with remote after untracked local evolution
Local site-ai/ had diverged significantly from the last commit pushed
to Gitea (new remote-env-setup/remove targets, SITE_CONFIG_DIR/MAIN_REPO
split, credential cleanup in server-install.sh, migration docs) without
ever being committed. This catches the repo up to what's actually on disk.

Also untracks the legacy user/ subtree left over from before content was
split into its own standalone repo (natascha-rieter.nl-user) — user/ is
gitignored here and stays a separate git repo, unaffected by this commit.
2026-08-30 14:48:54 +02:00

natascha-rieter.nl — Grav CMS

Grav CMS site for natascha-rieter.nl. Local dev via Docker; production on a VPS managed entirely through make.


Repository structure

Two git repos:

Repo Contents Location
natascha-rieter-nl (this repo) Docker setup, Makefile, scripts, plugins.txt site-ai/
natascha-rieter.nl-user Site config, pages, theme user/ (standalone git repo)

The user/ directory is a standalone git repo — its changes are pushed/pulled independently to Gitea. The Grav Sync plugin on the server automatically pulls from Gitea when content is pushed.


Prerequisites

  • Docker (for local dev)
  • SSH access to the production server
  • Both Gitea repos created and accessible
  • A Gitea personal access token with repo read/write access

Local development setup

cp .env.example .env   # fill in your values — never commit this file
make setup             # start Docker container and install plugins

Site runs at http://localhost:8080.

Clone the user content repo into user/ if not already present:

git clone $USER_REPO user/

First-time server setup

1. Fill in .env — copy .env.example and set all values including REMOTE_USER, REMOTE_HOST, USER_REPO, MAIN_REPO, and Gitea credentials.

2. Run the install:

make remote-install

This SSHes into the server, downloads Grav, clones both repos (user content + this config repo), installs plugins, and prints the server's SSH public key.

3. Add the SSH key to Gitea — copy the printed public key and add it as a read-only deploy key to both Gitea repos. After this, make remote-fetch works without credentials.


Content sync workflow

Editors push content via the Grav Admin panel or by editing files in user/. The Grav Sync plugin on the server syncs changes automatically to Gitea.

To pull those editor changes locally:

make content-pull   # pull latest user/ content from Gitea → local

To push local changes to Gitea (triggers server sync):

git -C user add -A && git -C user commit -m "content: describe change"
make content-push   # push local user/ commits → Gitea

All commands

Local

Command Description
make start Start the local Docker container
make stop Stop the local Docker container
make setup Start container and install all plugins from plugins.txt
make install-plugins (Re)install plugins from plugins.txt in the local container
make content-push Push local user/ commits to Gitea
make content-pull Pull latest user/ content from Gitea

Remote credentials

Command Description
make remote-env-setup Write Gitea credentials to ~/.env-natascha on the server
make remote-env-remove Delete ~/.env-natascha from the server

Always run make remote-env-remove when done. Credentials must not persist on the server.

Remote server management

Command Description
make remote-install First-time install: download Grav, clone both repos, install plugins
make remote-fetch Pull latest config repo (Makefile, scripts, plugins.txt) on the server
make remote-install-plugins Install/update plugins from local plugins.txt on the server
make remote-upgrade-grav Upgrade Grav core on the server
make remote-clean Clear Grav cache on the server
make remote-maintenance-on Enable maintenance mode (visitors see offline page)
make remote-maintenance-off Disable maintenance mode

Typical upgrade workflow

make remote-maintenance-on
make remote-upgrade-grav
make remote-install-plugins
make remote-clean
make remote-maintenance-off

Plugins

Plugins are not committed to git. The full list is in plugins.txt — one plugin name per line.

  • Locally: make install-plugins
  • On server: make remote-install-plugins

Security

  • .env is gitignored. Never commit it — it contains your server credentials and Gitea token.
  • GITEA_TOKEN exists only in .env locally, and in ~/.env-natascha on the server only during active sessions. Always run make remote-env-remove after use.
  • ~/.env-natascha has chmod 600 — readable only by the SSH user.
  • The server pulls from Gitea using its SSH deploy key (read-only). No long-lived token is stored on the server after initial install.
  • scripts/server-install.sh writes ~/.netrc for the initial clone only, and deletes it immediately after via a trap handler — even if the script fails.
  • Credentials are never passed as command-line arguments (they would appear in server process listings). They are passed as environment variables within the SSH session.
S
Description
No description provided
Readme
20 MiB
Languages
HTML 78.9%
Makefile 8.7%
CSS 6.5%
Shell 5.4%
JavaScript 0.5%