Skip to content

Commit a7221e3

Browse files
gididafclaude
andcommitted
fix(installer,docs): actually honor SPANNORA_ALLOWED_ORIGINS
The installer documented `SPANNORA_ALLOWED_ORIGINS` as a supported env var but never read it — the systemd unit hard-codes its own `Environment=` lines, so re-running `install.sh` with the var set did nothing. Now we write `/etc/systemd/system/spannora.service.d/origins.conf` when the var is set and remove it when unset, so the env var is the single source of truth across re-runs. Docs: drop the broken `VAR=... systemctl restart spannora` recipe (env in front of systemctl never reaches the unit) and the `VAR=... curl ... | bash` recipe (env stays in curl's process, never reaches bash). Add a `Passing env vars correctly` subsection covering the two shapes that actually work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d8ab26b commit a7221e3

3 files changed

Lines changed: 67 additions & 16 deletions

File tree

install.sh

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@
77
# curl -fsSL https://spannora.dev/install.sh | sudo bash
88
#
99
# Environment overrides:
10-
# SPANNORA_DOMAIN Use this hostname instead of <public-ip>.sslip.io
11-
# SPANNORA_NO_PROXY Skip all reverse-proxy install/config
12-
# SPANNORA_NO_HTTPS On nginx hosts, skip the certbot/HTTPS step
13-
# SPANNORA_ACME_EMAIL Email used when registering with Let's Encrypt
14-
# (default: anonymous registration, no expiry notices)
10+
# SPANNORA_DOMAIN Use this hostname instead of <public-ip>.sslip.io
11+
# SPANNORA_NO_PROXY Skip all reverse-proxy install/config
12+
# SPANNORA_NO_HTTPS On nginx hosts, skip the certbot/HTTPS step
13+
# SPANNORA_ACME_EMAIL Email used when registering with Let's Encrypt
14+
# (default: anonymous registration, no expiry notices)
15+
# SPANNORA_ALLOWED_ORIGINS Comma-separated origins permitted to talk
16+
# cross-origin (needed for the hub PWA at
17+
# spannora.dev/app/). Re-run unset to clear.
1518

1619
set -euo pipefail
1720

@@ -277,6 +280,25 @@ ok "Dependencies installed"
277280
# --- systemd unit ---
278281
say "Installing systemd unit"
279282
install -m 644 "$INSTALL_DIR/deploy/spannora.service" "/etc/systemd/system/${SERVICE_NAME}.service"
283+
284+
# Optional CORS allowlist via a drop-in. The drop-in lives outside the
285+
# main unit so future installer runs don't clobber it; the env var is
286+
# the source of truth — re-run with it unset to clear the allowlist.
287+
DROPIN_DIR="/etc/systemd/system/${SERVICE_NAME}.service.d"
288+
ORIGINS_DROPIN="${DROPIN_DIR}/origins.conf"
289+
if [[ -n "${SPANNORA_ALLOWED_ORIGINS:-}" ]]; then
290+
say "Configuring CORS allowlist: ${SPANNORA_ALLOWED_ORIGINS}"
291+
mkdir -p "$DROPIN_DIR"
292+
cat > "$ORIGINS_DROPIN" <<EOF
293+
[Service]
294+
Environment=SPANNORA_ALLOWED_ORIGINS=${SPANNORA_ALLOWED_ORIGINS}
295+
EOF
296+
elif [[ -f "$ORIGINS_DROPIN" ]]; then
297+
say "Clearing previous CORS allowlist drop-in"
298+
rm -f "$ORIGINS_DROPIN"
299+
rmdir "$DROPIN_DIR" 2>/dev/null || true
300+
fi
301+
280302
systemctl daemon-reload
281303
systemctl enable "$SERVICE_NAME" >/dev/null 2>&1 || true
282304
systemctl restart "$SERVICE_NAME"

packages/site/src/pages/docs/hub.mdx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,34 @@ If you only have one spannora, the per-server PWA at `https://<your-vm>/` works
2121

2222
## Per-install setup (CORS opt-in)
2323

24-
The hub talks to your spannora across origins, so each install you want to manage needs to allow the hub's origin. On the VM:
24+
The hub talks to your spannora across origins, so each install you want to manage needs to allow the hub's origin. The cleanest way is to re-run the installer with the var set — it'll write a systemd drop-in that survives future upgrades:
2525

2626
```bash
27-
SPANNORA_ALLOWED_ORIGINS=https://spannora.dev systemctl restart spannora
27+
curl -fsSL https://spannora.dev/install.sh | sudo SPANNORA_ALLOWED_ORIGINS=https://spannora.dev bash
2828
```
2929

30-
Or edit `/etc/systemd/system/spannora.service` to add:
30+
The variable must be on the **bash** at the tail of the pipe, not the `curl`. `SPANNORA_ALLOWED_ORIGINS=... curl ... | bash` does nothing — the var lives in curl's environment and never reaches bash. See [install docs](/docs/install/#passing-env-vars-correctly) for the full explanation.
3131

32-
```
33-
Environment="SPANNORA_ALLOWED_ORIGINS=https://spannora.dev"
32+
To clear the allowlist later, re-run the installer with the variable **unset** — the drop-in is removed.
33+
34+
If you'd rather skip the installer round-trip, write the drop-in directly on the VM:
35+
36+
```bash
37+
sudo mkdir -p /etc/systemd/system/spannora.service.d
38+
sudo tee /etc/systemd/system/spannora.service.d/origins.conf >/dev/null <<'EOF'
39+
[Service]
40+
Environment=SPANNORA_ALLOWED_ORIGINS=https://spannora.dev
41+
EOF
42+
sudo systemctl daemon-reload && sudo systemctl restart spannora
3443
```
3544

36-
Then `systemctl daemon-reload && systemctl restart spannora`.
45+
Without this, the browser will refuse cross-origin requests and the hub will show a CORS error. Verify it took with:
46+
47+
```bash
48+
curl -i -X OPTIONS https://<your-spannora-host>/api/auth/status -H 'Origin: https://spannora.dev'
49+
```
3750

38-
Without this, the browser will refuse cross-origin requests and the hub will show a CORS error.
51+
A `204` with an `Access-Control-Allow-Origin: https://spannora.dev` header means you're good.
3952

4053
## Adding an instance to the hub
4154

packages/site/src/pages/docs/install.mdx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,39 @@ Visit `https://<your-vm-ip>.sslip.io/setup`, paste the setup token, create your
4141
Point an A record at your VM, then run:
4242

4343
```bash
44-
SPANNORA_DOMAIN=chat.example.com curl -fsSL https://spannora.dev/install.sh | bash
44+
curl -fsSL https://spannora.dev/install.sh | sudo SPANNORA_DOMAIN=chat.example.com bash
4545
```
4646

4747
The installer will configure the proxy and request a certificate for that hostname instead of `sslip.io`.
4848

4949
## Other install options
5050

51-
The installer respects a handful of environment variables. Set them before piping into bash:
51+
The installer respects a handful of environment variables:
5252

5353
| Variable | Purpose |
5454
|---|---|
5555
| `SPANNORA_DOMAIN` | Custom hostname (otherwise auto-derived from public IP via sslip.io). |
56-
| `SPANNORA_PORT` | Local port to bind the Node process (default `7878`). |
5756
| `SPANNORA_NO_PROXY=1` | Skip reverse-proxy setup entirely. You handle TLS yourself. |
5857
| `SPANNORA_NO_HTTPS=1` | nginx path only — skip certbot. |
5958
| `SPANNORA_ACME_EMAIL` | Email registered with Let's Encrypt. |
60-
| `SPANNORA_ALLOWED_ORIGINS` | Comma-separated origins permitted to talk to this install (needed for cross-origin hub access). |
59+
| `SPANNORA_ALLOWED_ORIGINS` | Comma-separated origins permitted to talk to this install (needed for cross-origin [hub](/docs/hub/) access). Re-run unset to clear. |
60+
61+
### Passing env vars correctly
62+
63+
The variable must be set in the **bash** process at the end of the pipe, not the `curl` in front. Two shapes that work:
64+
65+
```bash
66+
# inline on bash (one-shot)
67+
curl -fsSL https://spannora.dev/install.sh | sudo SPANNORA_ALLOWED_ORIGINS=https://spannora.dev bash
68+
69+
# or export + sudo -E to preserve env
70+
export SPANNORA_ALLOWED_ORIGINS=https://spannora.dev
71+
curl -fsSL https://spannora.dev/install.sh | sudo -E bash
72+
```
73+
74+
`SPANNORA_ALLOWED_ORIGINS=... curl ... | bash` does **not** work — the variable lives in curl's environment and never reaches bash. Same trap applies to all the variables above.
75+
76+
The installer is idempotent: re-running with `SPANNORA_ALLOWED_ORIGINS` set writes a systemd drop-in at `/etc/systemd/system/spannora.service.d/origins.conf`; re-running with it unset removes that drop-in.
6177

6278
## Reverse-proxy detection
6379

0 commit comments

Comments
 (0)