2026-06-18 23:00:02 +02:00

into the east — Grav CMS

Grav CMS travel blog. Local dev via Docker; production on a VPS managed entirely through make.


Repository structure

Two git repos:

Repo Contents Location
intotheeast.com (this repo) Docker setup, Makefile, scripts, plugins.txt ./
intotheeast.com-content 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:8081.

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

To pull 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-intotheeast on the server
make remote-env-remove Delete ~/.env-intotheeast 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-intotheeast on the server only during active sessions. Always run make remote-env-remove after use.
  • ~/.env-intotheeast 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 556 KiB
Languages
JavaScript 56.1%
Python 20.7%
Shell 11%
Makefile 5.9%
HTML 5%
Other 1.3%