5abd5296f3
The published docs site had drifted from what actually shipped: - docs/sso/multi-site.md said the no-inbound relay was "designed but not automated" -- it's been automated since earlier this session. Also said "don't combine" multi-site join and LDAP replication -- they're integrated now (join auto-configures LDAP MMR). - docs/sso/replication.md (the actually-published/linked replication page -- distinct from theta-directory's own docs/replication.md, which isn't linked from this site's nav at all) still only described the old fully-manual LDAP_SERVER_ID/LDAP_REPLICATION_HOSTS setup, with zero mention of the new auto-config or CFG_LDAP_MMR_MANUAL. - docs/index.md's feature bullet described multi-site purely as "N-Way Multi-Master LDAP replication" -- the actual master/spoke join feature (the more commonly-used, higher-level mechanism) wasn't mentioned on the homepage at all. - CFG_PUBLIC_DOMAIN (shipped, never documented anywhere an operator would read it) now explained in multi-site.md. - spoke.env now discoverable from quickstart.md, not just multi-site.md. Also documents the real, load-bearing limitation from this session's promotion/LDAP-orphan fix: the master's own replication peer list only updates on its own next setup.sh run, not live the instant a spoke joins or a promotion happens.
199 lines
7.4 KiB
Markdown
199 lines
7.4 KiB
Markdown
---
|
|
layout: default
|
|
title: Quickstart
|
|
description: Step-by-step first run for theta-suite — prerequisites, setup.env, and bringing up the stack with ./setup.sh.
|
|
---
|
|
|
|
# Quickstart Guide
|
|
|
|
[← Back to Home](index.html)
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- A Linux host with **Docker + Docker Compose** (you must use the modern `docker compose` v2 plugin; the older `docker-compose` v1 standalone will fail on BuildKit images).
|
|
- Two hostnames that resolve to the host: one for the SSO UI (your `stack.ssoHost`),
|
|
one for the proxy mgmt UI (your `stack.proxyHost`). On a real network add DNS
|
|
records; for a local try, add them to `/etc/hosts`.
|
|
- Port **80 + 443** reachable from the internet if you want Let's Encrypt
|
|
certs; otherwise the proxy serves a self-signed fallback (browsers warn —
|
|
expected for LAN use).
|
|
|
|
---
|
|
|
|
## 1. Clone
|
|
|
|
```bash
|
|
git clone --recursive https://github.com/theta42/theta-suite.git
|
|
cd theta-suite
|
|
```
|
|
|
|
`--recursive` fetches the two submodules (`sso-manager-node`, `proxy`) in one
|
|
step. If you forgot it:
|
|
|
|
```bash
|
|
git submodule update --init --recursive
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Configure `setup.env` (enter your domain once)
|
|
|
|
```bash
|
|
cp setup.env.example setup.env
|
|
$EDITOR setup.env # set CFG_DOMAIN to your domain
|
|
```
|
|
|
|
Your domain is entered **once**, as a plain DNS domain. The SSO/proxy
|
|
hostnames default to `sso.<domain>` / `proxy.<domain>`, and the LDAP base DN
|
|
is built from it (any number of labels works — a domain like
|
|
`myhost.duckdns.org` becomes `dc=myhost,dc=duckdns,dc=org`), so for most
|
|
setups `CFG_DOMAIN` is the only value you set:
|
|
|
|
| `setup.env` key | Example | Notes |
|
|
|-----|---------|-------|
|
|
| `CFG_DOMAIN` | `lab.local` | your domain — **required** |
|
|
| `CFG_SSO_HOST` | `sso.lab.local` | optional, defaults to `sso.<domain>` |
|
|
| `CFG_PROXY_HOST` | `proxy.lab.local` | optional, defaults to `proxy.<domain>` |
|
|
| `CFG_ADMIN_UID` | `admin` | optional, defaults to `admin` |
|
|
| `CFG_ADMIN_EMAIL` | `admin@<proxyHost>` | optional |
|
|
| `CFG_BASE_DN` | `dc=lab,dc=local` | advanced: override the derived LDAP base DN |
|
|
| `CFG_JUMP_HOST` | `jump.lab.local` | optional, defaults to `jump.<domain>` (the [SSH jump host](https://theta42.github.io/jump-host/) is installed + started by default) |
|
|
| `JUMP_SSH_PORT` | `2222` | optional: host port for the jump host's SSH (never 22 by default) |
|
|
|
|
`setup.env` is used **only on the first run** to generate `./config/`; after
|
|
that `./config/*.js` are operator-owned and `setup.env` is ignored. Secrets
|
|
(LDAP admin password, JWT, admin password, service-account password) are
|
|
**generated** into `./config/*.js` on first run — do **not** put them in
|
|
`setup.env`. See `setup.env.example` for the full annotated shape, and
|
|
`config.example/` + each submodule's `secrets.js.example` for the generated
|
|
file shape.
|
|
|
|
> **Migrating from an older `.env`-based deployment?** If `.env`/`proxy.env`
|
|
> exist, `./setup.sh` migrates them into `./config/` preserving your existing
|
|
> secrets — no need to write a `setup.env`.
|
|
|
|
> **Joining an existing Theta Directory cluster instead of seeding a fresh
|
|
> one?** See [Multi-Site (Master/Spoke Join)](sso/multi-site.html) —
|
|
> `spoke.env.example` has the join-a-cluster vars split out into their own
|
|
> file, or set them directly in `setup.env` (which has every option).
|
|
|
|
---
|
|
|
|
## 3. Run
|
|
|
|
```bash
|
|
./setup.sh
|
|
```
|
|
|
|
The first run reads `setup.env`, generates `./config/sso-secrets.js` +
|
|
`./config/proxy-secrets.js` with your domain filled in everywhere plus random
|
|
secrets, then builds and starts the stack in the same run (no edit-and-re-run).
|
|
What happens:
|
|
|
|
1. Snapshots state to `./backups/<timestamp>/` before rebuilding (a no-op on the
|
|
very first run).
|
|
2. Builds + starts **sso-manager**, waits for `/health`.
|
|
3. Runs the **bootstrap** inside the sso-manager container — creates the LDAP
|
|
service account, your first admin, and the proxy's OAuth client, and writes
|
|
the generated client id + secret into `./config/proxy-secrets.js`.
|
|
4. Builds + starts **proxy**, waits for `/health`.
|
|
5. Registers `<SSO_HOST>` and `<PROXY_HOST>` as Host records in the proxy —
|
|
every hostname the proxy serves, including its own UI and the SSO's,
|
|
needs one of these or it 404s. Idempotent.
|
|
6. Prints your first-admin login + the public URLs.
|
|
|
|
The first run builds two Docker images (a few minutes). Subsequent runs are
|
|
fast.
|
|
|
|
---
|
|
|
|
## 4. Point DNS at the host
|
|
|
|
`stack.ssoHost` and `stack.proxyHost` (from `./config/sso-secrets.js`) must
|
|
resolve to the host running the stack. Add DNS records, or for a local try:
|
|
|
|
```bash
|
|
echo "127.0.0.1 sso.lab.local proxy.lab.local" | sudo tee -a /etc/hosts
|
|
```
|
|
|
|
(The proxy needs port 80 reachable for Let's Encrypt; on a LAN without that it
|
|
serves a self-signed cert — browsers will warn, which is fine for home-lab use.)
|
|
|
|
---
|
|
|
|
## 5. Log in
|
|
|
|
Open `https://<SSO_HOST>` and log in as your bootstrap admin
|
|
(`bootstrap.adminUid` / `bootstrap.adminPass`). From there you can add users,
|
|
groups, and OAuth clients.
|
|
|
|
The proxy mgmt UI is at `https://<PROXY_HOST>` (same admin SSO login protects
|
|
it). Add the Host records you want to protect with OIDC.
|
|
|
|
First-run fallbacks (if DNS/TLS isn't ready yet): SSO UI at
|
|
`http://127.0.0.1:3001`, proxy UI at `http://127.0.0.1:3000`.
|
|
|
|
---
|
|
|
|
## Re-running
|
|
|
|
`./setup.sh` is **idempotent** — safe to re-run after editing `./config/`, after
|
|
a `docker compose down`, or after restoring from backup. It snapshots state,
|
|
then converges the stack to your `./config/` values (LDAP service account + admin
|
|
passwords are reset to the config; the OAuth client is kept if `proxy-secrets.js`
|
|
already holds its creds).
|
|
|
|
> **Troubleshooting: "A newer version is available" after running setup.sh?**
|
|
> If the UI shows this warning immediately after you ran `./setup.sh`, the latest
|
|
> GitHub release tag might not yet be merged into the default tracking branch for
|
|
> the submodules, or Docker may have cached the `COPY` step if the `package.json`
|
|
> didn't change. You can force a clean rebuild by running
|
|
> `docker compose build --no-cache` and then re-running `./setup.sh`.
|
|
|
|
---
|
|
|
|
## Direct LDAP for LDAP-native clients and Linux hosts
|
|
|
|
LDAP-native apps and Linux hosts (PAM/SSSD, sudo, SSH keys) bind LDAP directly
|
|
over LDAPS:
|
|
|
|
```bash
|
|
ldapsearch -x -H ldaps://<host>:636 \
|
|
-D "cn=ldapclient,ou=people,dc=lab,dc=local" -W \
|
|
-b "ou=people,dc=lab,dc=local" '(objectClass=posixAccount)' cn mail
|
|
```
|
|
|
|
Use the `cn=ldapclient` service account (read-only, the bootstrap created it)
|
|
or the admin DN. Use LDAPS (636), not plain LDAP.
|
|
|
|
---
|
|
|
|
## Backups and restore
|
|
|
|
`./setup.sh` auto-snapshots `./config/` + LDAP + both Redis to `./backups/<ts>/`
|
|
before each rebuild (keeps the last `BACKUP_KEEP`, default 5). For manual
|
|
backups and the full restore runbook (full / Redis-only / LDAP-only, with the
|
|
AOF-vs-RDB note), see the *Backups and restore* section of the
|
|
[README](https://github.com/theta42/theta-suite#backups-and-restore). Quick LDAP
|
|
backup:
|
|
|
|
```bash
|
|
docker compose exec sso-manager slapcat -f /etc/openldap/slapd.conf \
|
|
-b "<base>" > backup-$(date +%F).ldif
|
|
```
|
|
|
|
---
|
|
|
|
## Next steps
|
|
|
|
- Add users / groups in the SSO UI.
|
|
- Add Host records in the proxy UI to protect your apps with OIDC.
|
|
- **Mint API tokens** to drive either app's management API from scripts/CI:
|
|
under **API Tokens** in each UI, mint a personal access token and use it as
|
|
`Authorization: Bearer sso_…` (SSO) or `prx_…` (proxy). A token authenticates as
|
|
its creator with their permissions. See each submodule's DEPLOYMENT.
|
|
- See [Architecture](architecture.html) for how it all fits together.
|
|
|
|
[← Back to Home](index.html) |