Configs and scripts to provision the VPS that runs HomeDir. All secrets are stripped; fill them from your secure store before applying. This folder is meant to be copied to a fresh host to get the same behavior we have now (GitHub Actions SSH deploy + timer fallback + rollback + maintenance page).
scripts/homedir-update.sh– pulls a tagged image, restarts the container, and rolls back on failure.scripts/homedir-env-lib.sh– shared env loader with*_FILEsecret resolution.scripts/homedir-webhook.py– optional listener for Quay webhooks that triggershomedir-update.shwith the tag from the payload (ignoreslatest-only webhooks), validates webhook signatures, and exposes a token-protected status endpoint.scripts/homedir-auto-deploy.sh– fallback poller that checks Quay tags and deploys the newest semver tag when webhook delivery is missing.scripts/homedir-discord-alert.sh– sends deploy and webhook alerts to Discord with severity icons/colors (WARN,FAIL,RECOVERY).scripts/homedir-ir-first-level.sh– first-level incident response (status,snapshot,shield-on,recover,shield-off) for attacks/DoS.scripts/homedir-security-hardening.sh– hardening baseline automation (audit,apply) for VPS + runtime controls.scripts/homedir-cfp-traffic-guard.sh– monitors CFP/community critical routes for 429/5xx/timeouts and triggers alerts on threshold breaches.scripts/homedir-dr-backup.sh– creates an encrypted DR backup artifact (tar.gz.age) + sha256 + metadata, with retention-based rotation.scripts/homedir-dr-recover.sh– one-command disaster recovery orchestrator for a pre-provisioned VM.scripts/homedir-dr-restore.py– safe archive extractor used by DR recovery (blocks path traversal/symlinks).scripts/homedir-secrets-rotate.sh– rotates internal runtime secrets with backup + optional service restart.systemd/homedir-webhook.service– runs the optional webhook listener.systemd/homedir-auto-deploy.service/systemd/homedir-auto-deploy.timer– periodic fallback auto-deploy from Quay.systemd/homedir-cfp-traffic-guard.service/systemd/homedir-cfp-traffic-guard.timer– periodic CFP route resilience monitoring.systemd/homedir-update.service/systemd/homedir-update.timer– optional manual/timer runner; keep disabled unless you set a tag.nginx/homedir.conf,nginx/int.conf– HTTPS reverse proxies with a maintenance page for 502/503/504.nginx/snippets/homedir-incident-guard.conf– lock-file based emergency shield to force maintenance mode during incidents.nginx/snippets/homedir-security-hardening.conf– baseline edge hardening (timeouts, headers, method filtering, body-size cap).assets/maintenance.html– friendly maintenance page served by nginx.env.example– sample/etc/homedir.envwith required variables (no secrets).
- Install dependencies:
podman,python3,nginx,certbot(or provide your own TLS certs). - Copy scripts to
/usr/local/bin/and make them executable. - Create
/etc/homedir.envfromplatform/env.example. Prefer*_FILEvariables for sensitive values.- Store secret files under
/etc/homedir-secretswithroot:rootand mode600. - To enable Discord alerts, set
ALERTS_DISCORD_WEBHOOK_URL_FILEand keepDISCORD_ALERTS_ENABLED=true. - For webhook security, define
WEBHOOK_SHARED_SECRET_FILEandWEBHOOK_STATUS_TOKEN_FILE, keepWEBHOOK_REQUIRE_SIGNATURE=true, and bind webhook to localhost (WEBHOOK_BIND_ADDRESS=127.0.0.1). - Keep OAuth callback baseline values in env:
APP_PUBLIC_URL=https://homedir.opensourcesantiago.ioQUARKUS_HTTP_PROXY_ALLOW_X_FORWARDED=trueQUARKUS_HTTP_PROXY_ALLOW_FORWARDED=falseQUARKUS_OIDC_AUTHENTICATION_FORCE_REDIRECT_HTTPS_SCHEME=true
- Store secret files under
- Install systemd units from
platform/systemd/into/etc/systemd/system/, runsystemctl daemon-reload, then enable:homedir-auto-deploy.timer(fallback every 1 min)homedir-cfp-traffic-guard.timer(CFP route guard every 5 min)homedir-webhook.serviceonly if you want Quay webhook support
- Place nginx configs into
/etc/nginx/sites-available/, symlink tosites-enabled, and reload nginx. - Configure GitHub Actions deploy secrets/vars (for immediate deploy on release):
- Secret:
DEPLOY_SSH_PRIVATE_KEY - Optional secret:
DEPLOY_SSH_KNOWN_HOSTS - Vars:
DEPLOY_SSH_HOST,DEPLOY_SSH_USER, optionalDEPLOY_SSH_PORT, optionalDEPLOY_SSH_COMMAND, optionalDEPLOY_HEALTHCHECK_URL
- Secret:
- Validate fallback poller with
systemctl start homedir-auto-deploy.serviceand inspect/var/log/homedir-auto-deploy.log. - Optional webhook verification: send a POST with
updated_tags/docker_tagsand check/var/log/homedir-webhook.logpluspodman ps. homedir-update.shlogs to/var/log/homedir-update.logand performs rollback using the previous container image if a run fails.
Emergency shield on:
/usr/local/bin/homedir-ir-first-level.sh shield-onCapture diagnostics:
/usr/local/bin/homedir-ir-first-level.sh snapshotRecover to known good tag and reopen traffic:
/usr/local/bin/homedir-ir-first-level.sh recover vX.Y.ZManual reopen:
/usr/local/bin/homedir-ir-first-level.sh shield-offManual check:
/usr/local/bin/homedir-cfp-traffic-guard.sh statusEnforced check (exit non-zero on breach):
/usr/local/bin/homedir-cfp-traffic-guard.sh checkGenerate encrypted backups regularly and store them in your secure backup location:
/usr/local/bin/homedir-dr-backup.sh \
--age-recipient <AGE_PUBLIC_RECIPIENT> \
--retain-count 28 \
--output-dir /var/backups/homedir-drOutputs:
*.tar.gz.ageencrypted backup artifact*.sha256integrity file*.metadata.jsonnon-sensitive metadata- keeps only the newest
--retain-countbackup sets after a successful run (28by default, suitable for a 6-hour schedule with 7 days of history)
Minimal example:
/usr/local/bin/homedir-dr-recover.sh \
--env-file /secure/homedir.env.age \
--age-identity /root/.config/age/keys.txt \
--backup-file /secure/homedir-data-YYYYMMDDTHHMMSSZ.tar.gz.age \
--backup-sha256-file /secure/homedir-data-YYYYMMDDTHHMMSSZ.tar.gz.age.sha256 \
--apply-hardeningWhat it automates:
- Pull repo from GitHub (
--repo-refselectable). - Install platform scripts + systemd units.
- Install secure env file into
/etc/homedir.envwith strict permissions. - Restore application data safely to host data directory.
- Deploy from Quay (
--deploy-tagor latest semver fallback). - Verify local healthcheck (
/q/healthby default).
- The update script expects a specific tag; no
latestis used. homedir-update.shnormalizes tags likev3.361.0to3.361.0to avoid pull failures.- Release workflow now deploys by SSH immediately after pushing the image; timer remains active as a safety net.
- Discord alerts are non-blocking: if webhook delivery fails, deploy flow continues and logs the warning in
/var/log/homedir-alerts.log. - Secrets must never land in git—always inject via
/etc/homedir.env+*_FILEsecure files or your secret manager. - Nginx returns the maintenance page when the backend is down, avoiding default 502/Cloudflare responses.
- First-level shield uses
/etc/homedir.incident.lock; when present, public traffic receives maintenance (503) while local/q/healthremains available. homedir-webhook.pynow requires signed requests by default (X-Quay-Signature) and does not log raw webhook payloads.GET /on webhook is disabled unlessWEBHOOK_STATUS_TOKENis configured and sent by caller.- Persistence path must be consistent across deploys: set
HOMEDIR_DATA_DIRand keepJAVA_TOOL_OPTIONS=-Dhomedir.data.dir=<same-path>in/etc/homedir.env. - The default volume mapping (
/work/data:/work/data:Z) and data-dir env vars must point to the same in-container path. - For concurrency hardening, set explicit container limits in
/etc/homedir.env:CONTAINER_MEMORY_LIMIT(recommended2g)CONTAINER_CPU_LIMIT(recommended3)CONTAINER_PIDS_LIMIT(recommended2048)
- Never store plaintext secrets or unencrypted backups in git. Keep
/etc/homedir.env, age identity keys, and backup artifacts in secure storage with restricted access. - Run
/usr/local/bin/homedir-security-hardening.sh auditperiodically and after each DR recovery. - Rotate internal runtime secrets periodically (monthly or after incident):
/usr/local/bin/homedir-secrets-rotate.sh --restart-services