The cron has been silently failing every day since 2026-03-28. Four
independent bugs were stacked:
1. cron/entrypoint.sh: env dump used `sed` to wrap each line in
`export `, but values with spaces (e.g. GIT_SSH_COMMAND, OIDC_SCOPES)
produced lines like `export GIT_SSH_COMMAND=ssh -o UserKnownHosts...`
which `export` parses as a flag and aborts. busybox ash treats the
builtin error as fatal, so `. /etc/environment.sh; script.sh` never
reaches the script. Now single-quote each value with proper escaping.
2. cron/Dockerfile: NODE_PATH only works for CommonJS `require()`, not
ESM `import`. The export script is `"type": "module"` and failed with
"Cannot find package 'gray-matter'". Install deps at /app/node_modules
instead — Node ESM walks up from /app/scripts and finds it there.
3. docker-compose.yml: `~/.ssh:/root/.ssh:ro` — DokPloy does NOT expand
`~`, so it created a literal `~` directory inside the deployment dir
and mounted that empty dir. The container had no SSH key. Use the
absolute host path `/root/.ssh` instead.
4. cron/entrypoint.sh: even with the SSH key, `git push` would fail
because the git remote is HTTPS and the host's git server runs on
port 2222 (set in /root/.ssh/config). Add a `pushInsteadOf` rewrite
so push uses SSH while DokPloy can keep fetching via HTTPS, and stop
re-running ssh-keyscan against the wrong port — copy the host's
known_hosts (which already has the :2222 entry) instead.
- nginx: deny all requests to hidden files (/.git/config was publicly readable)
- nginx: remove CSS injection and /custom/ static file serving
- cron: install script deps at build time into /opt to avoid ro mount conflict
- docker-compose: widen cron build context for package.json COPY
- Delete unused theme/ghost-guild.css
Alpine crond doesn't inherit the container environment, so
OUTLINE_API_TOKEN and other vars were missing. Dump env at
startup and source it in each cron entry.
- Add cron service to docker-compose with backup (3 AM) and export (4 AM) schedules
- Remove redundant content/articles/ and content/curriculum/ (now in Outline, exported to content/wiki/)
- Fix env var mismatch: support both OUTLINE_API_KEY and OUTLINE_API_TOKEN
- Drop updatedAt from export frontmatter to reduce noisy commits
- Add backups/ to gitignore
9 session pages and 10 PS Guide markdown files for the Baby Ghosts
cooperative foundations curriculum. Import script creates documents in
Outline wiki with cross-links between paired session/PS Guide pages.
Export script pulls all Outline documents via API and writes them as
flat markdown files to content/wiki/ with frontmatter metadata.
Cron wrapper auto-commits changes daily.
Traefik was routing directly to Outline, so the nginx.conf
was unused. Add nginx as an intermediary service to enable
sub_filter injection of OG tags on the homepage and custom
CSS on all pages.
Strip the Nuxt 4 static site and replace with Docker Compose config
for self-hosted Outline wiki (Outline + PostgreSQL 16 + Redis 7).
Adds nginx reverse proxy with WebSocket support and CSS injection,
migration script for existing markdown articles, backup script,
and starter theme CSS.