Anton Bakulin

Deployment

Contents

The recommended production setup: your Obsidian vault lives in its own private GitHub repo. Pushing to it triggers an instant content update — no container rebuild required.


How it works

The vault is cloned at container startup (not build time). A /webhook endpoint accepts GitHub push events, runs git pull, and triggers a hot-reload — the site updates in seconds.

flowchart LR A([Edit note]) --> B([git push vault]) B --> C([GitHub webhook]) C --> D([POST /webhook]) D --> E([git pull]) E --> F([Live instantly])

Coolify setup

1. Deploy OnyxFolio

Deploy the OnyxFolio repo to Coolify. Set these environment variables in your app's settings:

Variable Purpose
VAULT_REPO Full clone URL of your vault repo, including a read-only token: https://<token>@github.com/you/your-vault
WEBHOOK_SECRET A secret string you choose — GitHub will sign webhook payloads with it

Use a fine-grained personal access token scoped to read-only on the vault repo.

Generating a webhook secret
Run `openssl rand -hex 32` in your terminal to generate a strong secret.

2. Wire up the GitHub webhook

In your vault's GitHub repo go to Settings → Webhooks → Add webhook:

Result

Every git push to the vault repo triggers the webhook, which pulls the latest notes and hot-reloads the site. No container rebuild. No downtime.


Docker (local development)

Mount a local vault

docker build -t onyxfolio .
docker run -p 8000:8000 -v /path/to/vault:/vault onyxfolio

If /vault is not mounted, the server falls back to the bundled BlogPages/ demo vault.

Use a private vault repo with docker-compose

The repo ships with a docker-compose.yml. Put your vault URL and webhook secret in a .env file (gitignored):

# .env
VAULT_REPO=https://<token>@github.com/you/your-vault
WEBHOOK_SECRET=your-secret-here
docker compose up --build

The container clones the vault on first start. On subsequent starts it pulls the latest. If .env is absent or VAULT_REPO is unset, the build falls back to BlogPages/.


Environment variables

Variable Default Purpose
VAULT_PATH ./BlogPages Path to the vault directory inside the container
VAULT_REPO Git URL of the vault repo to clone/pull at startup
WEBHOOK_SECRET HMAC secret for verifying GitHub webhook payloads
ATTACHMENTS_PATH Optional fallback path for media files

Production server (gunicorn)

gunicorn -w 5 -b 0.0.0.0:8000 app:app