# Local/shared config — always loaded. Keep remote credentials OUT of here; # those live in .env.test / .env.prod. (docker compose also reads .env directly # for ${UID}/${GID} substitution and the travel-memories env_file.) -include .env # Remote config — loaded only when targeting an environment. ENV is set # automatically by the env-suffixed remote targets (e.g. `make remote-install-prod`); # each .env. holds a full, self-contained set of remote vars. ENV ?= -include .env.$(ENV) export REMOTE_PORT ?= 22 SSH := ssh -p $(REMOTE_PORT) $(REMOTE_USER)@$(REMOTE_HOST) WEBROOT ?= $(REMOTE_HOME)/public_html SITE_CONFIG_DIR ?= $(REMOTE_HOME)/site-config # ── Environment guard + generated per-env remote targets ────────────────────── # Every remote-* target below gains `-test` / `-prod` variants, e.g. # make remote-install-prod → runs remote-install with ENV=prod # Calling a bare remote target (no ENV) fails via guard-env. 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-maintenance-on remote-maintenance-off ENVS := test prod guard-env: @test -n "$(ENV)" || { echo "ERROR: no environment. Use an env-suffixed target, e.g. 'make remote-install-prod'."; exit 1; } @test -f ".env.$(ENV)" || { echo "ERROR: missing .env.$(ENV)"; exit 1; } define make-env-target $(1)-$(2): ; @$$(MAKE) --no-print-directory $(1) ENV=$(2) endef $(foreach t,$(REMOTE_TARGETS),$(foreach e,$(ENVS),$(eval $(call make-env-target,$(t),$(e))))) # ── Tests ───────────────────────────────────────────────────────────────────── # Local test account — auto-created, never committed (see user/.gitignore). # Keep the password free of shell/Make/URL-special chars so every consumer agrees. GRAV_TEST_USER ?= testrunner GRAV_TEST_PASS ?= Testpass1234 test-account: @docker exec intotheeast_grav sh -c 'test -f /var/www/html/user/accounts/$(GRAV_TEST_USER).yaml \ || php bin/plugin login new-user -u $(GRAV_TEST_USER) -p "$(GRAV_TEST_PASS)" \ -e $(GRAV_TEST_USER)@example.test -N "Test Runner" -P b --admin-type both -s enabled -n' test-config: @bash scripts/test-form-config.sh test-post: test-account @bash scripts/test-post.sh test-ui: test-account @npx playwright test test: test-config test-post test-ui # ── Local dev ────────────────────────────────────────────────────────────────── build: docker compose build build-assets: docker run --rm \ -v $(PWD)/user/themes/intotheeast:/app \ -w /app node:20-alpine \ sh -c "npm install && npm run build" start: docker compose up -d stop: docker compose down setup: build start install-plugins fix-perms fix-perms: docker exec intotheeast_grav bash -c "getent passwd 1000 > /dev/null || useradd -u 1000 -M hostuser" docker exec intotheeast_grav chown -R 1000:1000 /var/www/html docker exec intotheeast_grav apachectl graceful install-plugins: docker exec -w /var/www/html intotheeast_grav php bin/gpm install $(shell cat plugins.txt | tr '\n' ' ') -y # ── Demo content ────────────────────────────────────────────────────────────── demo-load: # Load italy-2026-demo trip (create pages if absent) docker exec intotheeast_grav bash -c "\ mkdir -p /var/www/html/user/pages/01.trips/italy-2026-demo/01.dailies /var/www/html/user/pages/01.trips/italy-2026-demo/04.stories && \ cp /var/www/html/user/docs/demo/trips/italy-2026-demo/trip.md /var/www/html/user/pages/01.trips/italy-2026-demo/trip.md 2>/dev/null || true && \ cp /var/www/html/user/docs/demo/trips/italy-2026-demo/stories.md /var/www/html/user/pages/01.trips/italy-2026-demo/04.stories/stories.md 2>/dev/null || true && \ cp -r /var/www/html/user/docs/demo/trips/italy-2026-demo/04.stories/. /var/www/html/user/pages/01.trips/italy-2026-demo/04.stories/ 2>/dev/null || true && \ cp -r /var/www/html/user/docs/demo/trips/italy-2026-demo/dailies/. /var/www/html/user/pages/01.trips/italy-2026-demo/01.dailies/ && \ cp /var/www/html/user/docs/demo/trips/italy-2026-demo/*.gpx /var/www/html/user/pages/01.trips/italy-2026-demo/ 2>/dev/null || true && \ chown -R 1000:1000 /var/www/html/user/pages/01.trips/italy-2026-demo && \ cd /var/www/html && php bin/grav clearcache" demo-reset: docker exec intotheeast_grav bash -c "rm -rf /var/www/html/user/pages/01.trips/italy-2026-demo && cd /var/www/html && php bin/grav clearcache" pixelfed-import: docker exec intotheeast_grav bash -c "which python3 || apt-get install -y python3 --no-install-recommends -q" docker cp /home/mischa/Nextcloud/Downloads/pixelfed/pixelfed-statuses.json intotheeast_grav:/tmp/pixelfed-statuses.json docker cp scripts/pixelfed-import.py intotheeast_grav:/tmp/pixelfed-import.py docker exec -w /var/www/html intotheeast_grav python3 /tmp/pixelfed-import.py # ── Content sync (user repo ↔ Gitea) ────────────────────────────────────────── content-push: git -C user push origin main content-pull: git -C user pull origin main # ── Remote credentials ───────────────────────────────────────────────────────── remote-env-setup: guard-env @$(SSH) "printf 'GITEA_HOST=%s\nGITEA_USER=%s\nGITEA_TOKEN=%s\n' \ '$(GITEA_HOST)' '$(GITEA_USER)' '$(GITEA_TOKEN)' > ~/.env-intotheeast && chmod 600 ~/.env-intotheeast" @echo "Credentials written to server. Run 'make remote-env-remove' when done." remote-env-remove: guard-env @$(SSH) "rm -f ~/.env-intotheeast" @echo "Credentials removed from server." # ── Remote: initial install ──────────────────────────────────────────────────── remote-wipe: guard-env $(SSH) "cd $(WEBROOT) && rm -rf assets backup bin cache images logs system tmp vendor webserver-configs index.php .htaccess CHANGELOG.md LICENSE.txt README.md" remote-install: guard-env $(SSH) "WEBROOT=$(WEBROOT) \ SITE_CONFIG_DIR=$(SITE_CONFIG_DIR) \ USER_REPO=$(USER_REPO) \ MAIN_REPO=$(MAIN_REPO) \ GRAV_VERSION=$(GRAV_VERSION) \ PLUGINS='$(shell cat plugins.txt | tr '\n' ' ')' \ GITEA_HOST=$(GITEA_HOST) \ GITEA_USER=$(GITEA_USER) \ GITEA_TOKEN=$(GITEA_TOKEN) \ bash -s" < scripts/server-install.sh # ── Remote: ongoing maintenance ──────────────────────────────────────────────── remote-fetch: guard-env $(SSH) "git -C $(SITE_CONFIG_DIR) checkout main && git -C $(SITE_CONFIG_DIR) pull" remote-fetch-content: guard-env $(SSH) "git -C $(WEBROOT)/user fetch origin main && git -C $(WEBROOT)/user sparse-checkout disable && git -C $(WEBROOT)/user reset --hard origin/main" remote-install-plugins: guard-env $(SSH) "cd $(WEBROOT) && php bin/gpm install $(shell cat plugins.txt | tr '\n' ' ') -y" remote-update-plugins: guard-env $(SSH) "cd $(WEBROOT) && php bin/gpm update -y && php bin/grav cache" remote-upgrade-grav: guard-env $(SSH) "cd $(WEBROOT) && php bin/gpm self-upgrade -y && php bin/grav cache" remote-git-sync-disable: guard-env $(SSH) "bash -s -- '$(WEBROOT)/user/config/plugins/git-sync.yaml' false" < scripts/git-sync-toggle.sh remote-git-sync-enable: guard-env $(SSH) "bash -s -- '$(WEBROOT)/user/config/plugins/git-sync.yaml' true" < scripts/git-sync-toggle.sh remote-content-status: guard-env $(SSH) "cd $(WEBROOT)/user && git status --short && echo '--- config diff ---' && git diff -- config/" remote-clean: guard-env $(SSH) "cd $(WEBROOT) && php bin/grav clearcache" remote-maintenance-on: guard-env $(SSH) "bash -s on $(WEBROOT)" < scripts/server-maintenance.sh remote-maintenance-off: guard-env $(SSH) "bash -s off $(WEBROOT)" < scripts/server-maintenance.sh