Persist Redis (AOF+vol), read config from mounted secrets.js, add backup/restore docs (#34)

Lossless upgrades + config story for the all-in-one image.

Redis persistence (Part A):
- Replace in-memory `--save "" --appendonly no` with AOF + RDB persisted to /data
  (--appendonly yes, periodic saves, --dbfilename dump.rdb). OAuth clients,
  tokens, and other model-redis state now survive container recreation.
- Add the `sso-data` named volume -> /data in docker-compose.yml.

Config from ./config/sso-secrets.js (Part B):
- docker-entrypoint.sh: when /config/sso-secrets.js is mounted, symlink it to
  /app/conf/secrets.js and read the server-side LDAP vars (base DN, admin pass,
  org, domain, cert CN, JWT) from the file via one `node` call (base64-decoded,
  no eval/quoting hazards). No app_* env is exported in this mode, so the file
  is authoritative (@simpleworkjs/conf precedence: base < env < secrets.js <
  app_* env). Falls back to the existing LDAP_* env-var mode when the file is
  absent (standalone/bare-metal still works).
- docker-compose.yml: trim `environment:` to NODE_ENV/NODE_PORT only and add
  `./config:/config:ro`. Removing the app_* env is required — any leftover
  app_* would silently override secrets.js.
- secrets.js.example: add orchestrator-only `stack`, `bootstrap`, and
  `serviceAccountPass` keys (ignored by the app; read by the entrypoint, the
  theta-env bootstrap, and setup.sh).

Backup/restore docs:
- Full "Backups and restore" runbook in DEPLOYMENT.md (what lives where,
  manual backup, full / Redis-only / LDAP-only restore, AOF-vs-RDB note,
  upgrades). Restore uses slapadd -f (static slapd.conf), and RDB restore
  requires deleting the AOF first (AOF wins on startup).
- Pointers in docs/deployment.md and docs/ldap.md; update the Docker Setup
  section for the new ./config/ approach (env vars now advanced/optional).

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-12 12:55:22 -04:00
committed by GitHub
parent d5e951fa9a
commit 6920a9f9f0
6 changed files with 283 additions and 131 deletions
+9 -5
View File
@@ -105,17 +105,21 @@ The bundled slapd generates a **self-signed cert** on first start (CN =
> Port 389 (plain LDAP) is **not** mapped to the host by default — direct-LDAP
> clients should use LDAPS (636) or StartTLS.
### Backups (~100 users)
### Backups and restore
LDAP, Redis (OAuth clients + tokens), and the `./config/` secrets are all
persisted and restorable. Redis is now AOF+RDB persisted to the `sso-data`
volume (not in-memory) so OAuth clients survive rebuilds.
See the **Backups and restore** section of `DEPLOYMENT.md` for the full runbook
(what lives where, manual backup, full / Redis-only / LDAP-only restore, and
the AOF-vs-RDB note). Quick LDAP backup:
```bash
docker compose exec sso-manager slapcat -f /etc/openldap/slapd.conf \
-b "dc=yourdomain,dc=com" > ldap-backup-$(date +%F).ldif
```
Restorable with `ldapadd`/`ldapmodify` against a fresh instance. Redis is
in-memory (session/cache only — safe to lose). Persist `JWT_SECRET` +
`LDAP_ADMIN_PASS` outside the container (your `.env`, a password manager).
## Method 2: Bare metal (Debian/Ubuntu)
`install.sh` is an idempotent installer: Node.js 20.x, OpenLDAP (modules +
+21 -2
View File
@@ -123,14 +123,33 @@ idempotently against a running slapd (auto-detects the database holding your
base DN, and verifies `pwdAccountLockedTime` is live — the attribute the app's
active/inactive toggle depends on).
## Backups
## Backups and restore
**Backup** (while slapd is running):
```bash
docker compose exec sso-manager slapcat -f /etc/openldap/slapd.conf \
-b "dc=yourdomain,dc=com" > ldap-backup-$(date +%F).ldif
```
Restorable with `ldapadd`/`ldapmodify` against a fresh instance.
Store the `.ldif` off the host — it contains every user's password hash.
**Restore** into a stopped directory. The SSO image uses a static `slapd.conf`
(slapd starts with `-f`, not cn=config `-F`), so restore uses `slapadd -f`:
```bash
docker compose stop sso-manager
docker compose run --rm --no-deps --entrypoint sh sso-manager -c \
'rm -f /var/lib/ldap/* && slapadd -f /etc/openldap/slapd.conf -l /dev/stdin' \
< ldap-backup-<date>.ldif
docker compose start sso-manager
```
Verify: `docker compose exec sso-manager ldapsearch -x -b "dc=yourdomain,dc=com"`.
Redis state (OAuth clients, tokens) and `./config/` secrets are backed up
separately — see the *Backups and restore* section of `DEPLOYMENT.md` for the
full (LDAP + Redis + secrets) runbook.
## Troubleshooting