Release v0.1.1:2 with certrelay, nacho, and prebuilt subspaces.
Build Service / BuildPackage (push) Has been cancelled

Remove the embedded explorer/indexer stack, switch subspaces to prebuilt images, add certrelay and nacho as always-on services, expose Spaces and Subs APIs, and wire optional HTTP basic auth for subs and subs-prover with the correct SUBS_BASIC_AUTH_PASSWORD env var.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-23 12:06:16 -04:00
co-authored by Cursor
parent 931becd274
commit ad64a47d42
30 changed files with 1364 additions and 831 deletions
+111 -155
View File
@@ -38,27 +38,15 @@ through a browser-based terminal.
| Field | Value |
| --- | --- |
| Spaces image | `docker.io/horologger/spaces` |
| PostgreSQL image | `docker.io/postgres:16.3` |
| Subspaces image | `docker.io/horologger/subs:v0.1.0` |
| Subspaces image | `docker.io/horologger/subs:v0.1.2` |
| Certrelay image | `docker.io/horologger/certrelay:v0.2.3` |
| Indexer image | _**TODO** — prebuilt explorer-indexer image, not yet produced_ |
| Explorer image | _**TODO** — prebuilt explorer (SvelteKit) image_ |
| Nacho image | `docker.io/horologger/nacho:v1.0.0` |
| Architectures | `linux/amd64`, `linux/arm64` |
| Entrypoint | StartOS-managed (image entrypoints are **not** used directly) |
The Spaces image bundles `spaced`, `space-cli`, `bitcoin-cli`, `gotty`, `node`,
`npm`, `screen`, and a small shell environment. StartOS ignores the Spaces
image's `docker_entrypoint.sh`; daemons are defined in `startos/main.ts`. The
PostgreSQL image is the upstream `postgres:16.3`, launched via its official
`docker-entrypoint.sh`.
> **Note (build-from-source removed):** earlier builds compiled the Go indexer
> and the SvelteKit explorer from source inside `golang:1.23-alpine` and
> `node:20-alpine` builder images. Those images and their build chains were
> removed to shrink the `.s9pk` and eliminate the multi-minute first-enable
> compile. They will be replaced with prebuilt images (see the **TODO** rows
> above). Until then, enabling the embedded explorer starts **PostgreSQL only**
> — the indexer and explorer-UI daemons are stubbed out in `startos/main.ts`.
image's `docker_entrypoint.sh`; daemons are defined in `startos/main.ts`.
## Volume and Data Layout
@@ -66,15 +54,14 @@ PostgreSQL image is the upstream `postgres:16.3`, launched via its official
| --- | --- | --- |
| `/data` | `main` | Spaces data directory (`SPACED_DATA_DIR`), wallets, indexes, and `store.json` |
| `/data/mainnet/.cookie` | `main` | Spaced RPC cookie (auto-generated by `spaced` at startup) |
| `/data/store.json` | `main` | StartOS-managed credentials (web-UI password, bitcoind RPC user/password, PostgreSQL user/password/database) |
| `/data/postgres` | `main` | PostgreSQL data directory (`PGDATA`). Owned by uid 999 (`postgres`). The whole `main` volume is backed up, so the database is included. |
| `/data/explorer-indexer` | `main` | **TODO** — reserved for the prebuilt indexer's runtime data. The build-from-source layout (source, `bin/sync`, `bin/goose`, marker) is gone; `reset-indexer-state` still wipes this path. |
| `/data/explorer-ui` | `main` | **TODO** — reserved for the prebuilt explorer's runtime data. The build-from-source layout (source, `build/`, `node_modules`, marker) is gone; `reset-explorer-state` still wipes this path. |
| `/data/store.json` | `main` | StartOS-managed credentials (Space-CLI Web UI password, bitcoind RPC user/password, spaced RPC user/password) and feature config (Subspaces toggles, Certrelay + Nacho settings). |
| `/data/subspaces/data` | `main` | `subs` runtime data (`SUBS_DATA_DIR`) — handles, proofs, config.db. Persists across restarts and enable/disable toggles. |
| `/data/subspaces/prover` | `main` | Working directory for the `subs-prover` daemon. |
| `/data/subspaces/registry` | `main` | Working directory for the `registry-server` daemon. |
| `/data/certrelay/data` | `main` | Certrelay data directory (`CERTRELAY_DATA_DIR`) — anchors, peer state, sqlite. |
| `/data/bin/fabric` | `main` | The `fabric` CLI, copied from the certrelay image on each start so the gotty terminal (which has `/data/bin` on PATH) can resolve handles. |
| `/data/support.pdf` | `main` | Workshop PDF served by nacho. Uploaded/replaced via the **Upload Support PDF** action. Missing until an upload has been performed. |
| `/data/nacho/ignore_names.txt` | `main` | Comma-separated names hidden from the nacho UI (read at runtime). Created by the `nacho-setup` oneshot with the default (`fold,swifty`) on first start; managed by the **Configure Nacho** action. |
## Installation and First-Run Flow
@@ -87,60 +74,41 @@ On the first install, StartOS:
pair and creates a critical cross-service task on **Bitcoin** that runs
bitcoind's `generate-rpc-dependent` action to register the credentials in
`bitcoin.conf`.
3. Seeds `store.json.dbAuth` with a random PostgreSQL password (username
`postgres`, database `spacesprotocol_explorer`). No task is created — the
credentials are only used internally by the embedded daemon.
4. Runs the `postgres-chown` oneshot to create `/data/postgres` with the right
ownership, then launches the PostgreSQL daemon on loopback 5432.
5. Seeds `store.json.spacedAuth` with a random `spaces:<random>` credential
3. Seeds `store.json.spacedAuth` with a random `spaces:<random>` credential
pair. Spaced is configured to require these via `SPACED_RPC_USER` /
`SPACED_RPC_PASSWORD` (cookie auth is **not** used in this package), so the
gotty terminal's `spaces` alias and the indexer share a single auth path.
6. Seeds `store.json.enableExplorer = false`. The embedded explorer
(PostgreSQL + Go indexer) is **opt-in**.
7. Seeds `store.json` certrelay defaults: `certrelaySelfUrl =
gotty terminal's `spaces` alias and other clients share a single auth path.
4. Seeds `store.json` certrelay defaults: `certrelaySelfUrl =
https://certrelay.spacesops.com`, `certrelayBootstrap = false`,
`certrelayHealthcheckHandle = account-digital-useful.genesis@key`.
8. Launches `spaced` as a managed daemon (no `screen`, no shell auto-start)
5. Seeds `store.json` nacho defaults (`nachoWorkshopPdfLinkText = ''`) and
`store.json.enableSubspaces = false`, `store.json.enableSubsProver = false`.
The nacho ignore-names list lives in `/data/nacho/ignore_names.txt` (not
in the store); the `nacho-setup` oneshot creates that file with the
default (`fold,swifty`) on first daemon start if it doesn't exist.
6. Launches `spaced` as a managed daemon (no `screen`, no shell auto-start)
and the `gotty` web terminal once the bashrc oneshot completes.
9. Runs `certrelay-setup` (creates `/data/certrelay/data`, copies the `fabric`
7. Runs `certrelay-setup` (creates `/data/certrelay/data`, copies the `fabric`
CLI to `/data/bin/fabric`) and launches the **certrelay** daemon on 7778.
Certrelay is **always on**; its `CERTRELAY_SPACED_RPC_URL` uses the local
spaced credentials from `store.spacedAuth`. Configure its self URL etc. via
the **Configure Certrelay** action.
8. Runs `nacho-setup` (mkdir `/data/nacho`; seeds `ignore_names.txt` with the
default `fold,swifty` if missing) and launches the **nacho** Expo daemon
on 8082. Always on.
The user is **not** prompted to choose a chain or RPC mode — this package is
mainnet-only.
### Enabling the embedded explorer
Run the **Enable Embedded Explorer** action. That flips
`store.json.enableExplorer = true` and the service auto-restarts:
8. Postgres-chown oneshot creates `/data/postgres` with correct ownership.
9. PostgreSQL daemon starts on loopback `127.0.0.1:5432`.
> **TODO (prebuilt images pending):** the indexer and explorer-UI daemons are
> currently **stubbed out** in `startos/main.ts`. The build-from-source chain
> (`indexer-fetch` → `indexer-build` → `indexer-migrate` → `indexer`, and
> `explorer-fetch` → `explorer-install` → `explorer-ui`) was removed to shrink
> the `.s9pk` and cut startup time. Until prebuilt images are wired in,
> enabling the explorer starts **PostgreSQL only**; nothing populates the DB
> and the Explorer Web UI (port 3000) will not resolve. The `show-db-credentials`,
> `reset-db-state`, `reset-indexer-state`, and `reset-explorer-state` actions
> remain available.
Run **Disable Embedded Explorer** to turn it back off; on-disk data at
`/data/postgres`, `/data/explorer-indexer`, and `/data/explorer-ui` is
preserved.
## Configuration Management
| StartOS-Managed | Upstream-Managed |
| --- | --- |
| Web-UI username / password (`admin` + generated password) | `spaced` runtime tuning via `SPACED_*` env vars in the image |
| Bitcoin RPC username / password (registered on bitcoind) | Wallet creation, bidding, and registration -- all driven via `space-cli` inside the terminal |
| PostgreSQL username / password / database (loopback only) | `space-cli` flags and subcommands |
| Spaced RPC username / password (`SPACED_RPC_USER`/`SPACED_RPC_PASSWORD`) | `space-cli` flags and subcommands |
| Subspaces auth toggle + credentials (`SUBS_BASIC_AUTH_USER`/`SUBS_BASIC_AUTH_PASSWORD`, off by default) | |
| Subspaces Prover auth toggle + credentials (`SUBS_PROVER_BASIC_AUTH_USER`/`SUBS_PROVER_BASIC_AUTH_PASSWORD`, off by default) | |
| Chain selection (locked to `mainnet`) | |
| Spaced data directory and RPC bind | |
@@ -149,14 +117,13 @@ preserved.
| Interface | Port | Protocol | Exposure | Notes |
| --- | --- | --- | --- | --- |
| Space-CLI Web UI (gotty terminal) | 8080 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | Basic auth: `admin:<store.password>` |
| Explorer Web UI | 3000 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | SvelteKit explorer. **TODO** — daemon stubbed pending the prebuilt explorer image; the interface is still registered but nothing listens yet. |
| Subspaces Web UI | 7777 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | `subs` daemon (subsd). No built-in auth. Only useful while Subspaces is enabled. |
| Subs API | 7777 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | The subsd REST API (same daemon/port as above), exposed as a distinct `api` interface separate from the prover and registry. Only useful while Subspaces is enabled. |
| Subspaces Prover | 8888 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | `subs-prover` RISC Zero prover server (no GPU). Its own StartOS interface. Only useful while Subspaces is enabled. |
| Subspaces Web UI | 7777 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | `subs` daemon (subsd). Optional HTTP basic auth — off by default, gated by **Enable Subspaces Auth**. When on, both this UI and the Subs API are walled behind `SUBS_BASIC_AUTH_USER` / `SUBS_BASIC_AUTH_PASSWORD`. Only useful while Subspaces is enabled. |
| Subs API | 7777 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | The subsd REST API (same daemon/port as above), exposed as a distinct `api` interface separate from the prover and registry. Shares the optional Subspaces Auth wall with the Web UI (same port, same process). Only useful while Subspaces is enabled. |
| Subspaces Prover | 8888 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | `subs-prover` RISC Zero prover server (no GPU). Its own StartOS interface. Optional HTTP basic auth — off by default, gated by **Enable Subspaces Prover Auth**. When on, `SUBS_PROVER_BASIC_AUTH_USER`/`SUBS_PROVER_BASIC_AUTH_PASSWORD` are enforced. Only useful while Subspaces (and the prover toggle) is enabled. |
| Subspaces Registry | 8081 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | `registry-server` for publishing/resolving handles (remapped from its upstream default 8080 to avoid colliding with the gotty terminal on 8080). Its own StartOS interface. Only useful while Subspaces is enabled. |
| Certrelay | 7778 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | `certrelay` server (always on). Serves cryptographic proofs binding handles to owner keys. **Setup:** run **Configure Certrelay** and set `CERTRELAY_SELF_URL` to the publicly visible URL StartOS exposes for this interface. |
| Spaces API (spaced RPC) | 7225 | HTTP JSON-RPC | LAN / `.local` / Tor / clearnet (via StartOS) | spaced JSON-RPC, now bound to `0.0.0.0` and exposed as the **Spaces API** interface. Static-cred-authenticated via `SPACED_RPC_USER` / `SPACED_RPC_PASSWORD` from `store.json.spacedAuth`. Internal clients still connect over loopback. |
| PostgreSQL | 5432 | Postgres wire protocol | **Loopback only** (`listen_addresses=127.0.0.1`) | Username/password from `store.json.dbAuth`; full `DB_URL` exported into the web terminal |
| Nacho | 8082 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | nacho Expo dev server (always on). The ignore list is read at runtime from `/data/nacho/ignore_names.txt` (managed by **Configure Nacho**). `EXPO_PUBLIC_API_BASE_URL` is derived dynamically from the Subs API StartOS interface (`sdk.serviceInterface.getOwn('subs-api').const()`), preferring the `.local` URL. Falls back to `http://127.0.0.1:7777` only if no address info is available. |
| Spaces API (spaced RPC) | 7225 | HTTP JSON-RPC | LAN / `.local` / Tor / clearnet (via StartOS) | spaced JSON-RPC, bound to `0.0.0.0` and exposed as the **Spaces API** interface. Static-cred-authenticated via `SPACED_RPC_USER` / `SPACED_RPC_PASSWORD` from `store.json.spacedAuth`. Internal clients still connect over loopback. |
## Actions
@@ -166,21 +133,26 @@ preserved.
| `show-credentials` | Show Space-CLI Web UI Credentials | Hidden | Any | Surfaces the current `admin` username + masked password (launched by the first-install task) |
| `show-password` | Show Space-CLI Web UI Password | Enabled | Any | Same as `show-credentials` but visible in the actions list, for routine re-display of the current admin credentials |
| `set-bitcoin-rpc` | Set up Bitcoin RPC | Enabled | Any | Re-invokes bitcoind's `generate-rpc-dependent` with the stored credentials. Safe to call repeatedly. |
| `show-spaced-credentials` | Show Spaces API Credentials | Enabled | Any | Surfaces the spaced RPC `SPACED_RPC_USER` / `SPACED_RPC_PASSWORD` (from `store.spacedAuth`) plus a loopback connection URL (password masked, all copyable). |
| `sync-status` | Sync Status | Enabled | Only running | Runs `space-cli getserverinfo` inside the daemon container and returns the JSON output |
| `reset-spaced-state` | Reset Spaced State | Enabled | Any | Deletes `/data/mainnet/` so spaced resyncs its index from spaces' anchor. Preserves `store.json` (passwords + RPC credentials). Use when spaced crash-loops on a stale or corrupt index. |
| `export-wallet` | Export Wallet | Enabled | Only running | Runs `space-cli exportwallet /data/mainnet/wallets_backup/default.json` and surfaces the resulting JSON as a masked/copyable result. The file is also persisted inside the volume at that path. |
| `import-wallet` | Import Wallet | Enabled | Only running | Accepts a pasted JSON payload (textarea), writes it to `/data/mainnet/wallets_backup/default.json` (rotating the existing file to `.bakNNN`), rotates `/data/mainnet/wallets/default` to `.bakNNN`, then runs `space-cli importwallet` + `loadwallet`. |
| `enable-explorer` | Enable Embedded Explorer | Enabled (hidden when already on) | Any | Sets `store.enableExplorer = true` and triggers a service restart so the full daemon graph (postgres + indexer + indexer-sync HC) takes effect. |
| `disable-explorer` | Disable Embedded Explorer | Enabled (hidden when already off) | Any | Sets `store.enableExplorer = false` and triggers a service restart so the indexer and postgres daemons stop. On-disk data at `/data/postgres` and `/data/explorer-indexer` is preserved. |
| `show-db-credentials` | Show Database Credentials | Enabled | Any | Surfaces the PostgreSQL username, password, database, and full `DB_URL` (all copyable; secrets masked). Credentials exist regardless of whether the explorer is currently enabled. |
| `reset-db-state` | Reset Database State | Enabled | Any | Deletes `/data/postgres` so the next start re-initializes an empty database. Warning-gated. `store.json` is preserved. |
| `reset-indexer-state` | Reset Indexer State | Enabled | Any | Deletes `/data/explorer-indexer` so the next start re-fetches the indexer source and rebuilds the sync + goose binaries. Useful when bumping the pinned commit. PostgreSQL data is preserved. Warning-gated. |
| `reset-explorer-state` | Reset Explorer UI State | Enabled | Any | Deletes `/data/explorer-ui` so the next start re-fetches the SvelteKit source and rebuilds the bundle. PostgreSQL data is preserved. Warning-gated. |
| `enable-subspaces` | Enable Subspaces | Enabled (hidden when already on) | Any | Sets `store.enableSubspaces = true` and triggers a service restart so the Subspaces chain (build → wallet → subs-prover → subs) takes effect. |
| `disable-subspaces` | Disable Subspaces | Enabled (hidden when already off) | Any | Sets `store.enableSubspaces = false` and triggers a service restart so the subs and subs-prover daemons stop. On-disk data at `/data/subspaces` is preserved. |
| `reset-subspaces-state` | Reset Subspaces State | Enabled | Any | Deletes `/data/subspaces` (runtime data only — binaries ship in the image). Use to wipe local handles/proofs. The spaces wallet on spaced is preserved. Warning-gated. |
| `set-subs-prover` | Enable / Disable Subspaces Prover | Enabled | Any | Toggle (`store.enableSubsProver`, default **off**) that starts/stops only the `subs-prover` daemon, independent of the overall Subspaces toggle. When off, the daemon doesn't start but its interface (8888) stays registered. Saving restarts the service. |
| `enable-subs-auth` | Enable Subspaces Auth | Enabled (hidden when already on) | Any | Sets `store.subsAuthEnabled = true`. If no credentials exist yet, generates `{ username: 'spaces', password: random32 }` and stores them in `store.subsAuth`. Restart re-launches `subs` with `SUBS_BASIC_AUTH_USER`/`SUBS_BASIC_AUTH_PASSWORD` env vars set. |
| `disable-subs-auth` | Disable Subspaces Auth | Enabled (hidden when already off) | Any | Sets `store.subsAuthEnabled = false`. Stored credentials are preserved so a later re-enable does not regenerate them. Restart re-launches `subs` without the auth env vars. |
| `show-subs-credentials` | Show Subspaces Auth Credentials | Enabled | Any | Surfaces the current `SUBS_BASIC_AUTH_USER`/`SUBS_BASIC_AUTH_PASSWORD` (from `store.subsAuth`) plus a loopback connection URL. Reports whether auth is currently enforced. |
| `set-subs-credentials` | Set Subspaces Auth Credentials | Enabled | Any | Set or rotate `store.subsAuth` and enable auth (`store.subsAuthEnabled = true`). Username is prefilled with the current value; password field is blank — leave it blank to auto-generate a random 32-char password, or paste your own. Restarts the service so subs picks up `SUBS_BASIC_AUTH_USER`/`SUBS_BASIC_AUTH_PASSWORD`. |
| `enable-subs-prover-auth` | Enable Subspaces Prover Auth | Enabled (hidden when already on) | Any | Sets `store.subsProverAuthEnabled = true`. If no credentials exist yet, generates `{ username: 'spaces', password: random32 }` and stores them in `store.subsProverAuth`. Restart re-launches `subs-prover` with `SUBS_PROVER_BASIC_AUTH_USER`/`SUBS_PROVER_BASIC_AUTH_PASSWORD` env vars set. |
| `disable-subs-prover-auth` | Disable Subspaces Prover Auth | Enabled (hidden when already off) | Any | Sets `store.subsProverAuthEnabled = false`. Stored credentials are preserved. Restart re-launches `subs-prover` without the auth env vars. |
| `show-subs-prover-credentials` | Show Subspaces Prover Auth Credentials | Enabled | Any | Surfaces the current `SUBS_PROVER_BASIC_AUTH_USER`/`SUBS_PROVER_BASIC_AUTH_PASSWORD` (from `store.subsProverAuth`) plus a loopback connection URL. Reports whether auth is currently enforced. |
| `set-subs-prover-credentials` | Set Subspaces Prover Auth Credentials | Enabled | Any | Set or rotate `store.subsProverAuth`. Same UX as `set-subs-credentials` (blank password → auto-generated). Restarts the service only if prover auth is currently enabled. |
| `configure-certrelay` | Configure Certrelay | Enabled | Any | Sets `CERTRELAY_SELF_URL` (text), `CERTRELAY_BOOTSTRAP` (toggle), and `CERTRELAY_HEALTHCHECK_HANDLE` (text) in `store.json`; prefilled with current values. Saving restarts the service so certrelay picks up the new config. |
| `configure-nacho` | Configure Nacho | Enabled | Any | Writes the Ignore Names list to `/data/nacho/ignore_names.txt` (read at runtime by nacho — survives daemon restarts independent of the store) and sets `EXPO_PUBLIC_WORKSHOP_PDF_LINK_TEXT` in `store.json`. Prefill reads the file (with the package default as fallback) plus the current store value. Saving restarts the service. |
| `upload-support-pdf` | Upload Support PDF | Enabled | Any | Required `.pdf` file upload that overwrites `/data/support.pdf` on the main volume (read with `fs/promises`, piped via stdin into a temp `spaces` subcontainer's `cat > /data/support.pdf`). Split out from Configure Nacho because StartOS's form serializes an unselected `Value.file` as `{}` rather than `null`, which `Value.file(..., required: false).nullable()` rejects; a `required: true` dedicated action avoids the empty-form path entirely. |
## Backups and Restore
@@ -193,15 +165,14 @@ the same idempotent init logic runs and reuses the existing credentials in
| ID | Display | Grace period | Behaviour |
| --- | --- | --- | --- |
| `postgres` (daemon `ready`) | Database | 60 s | TCP listen on `127.0.0.1:5432` |
| `spaced` (daemon `ready`) | Spaced RPC | 120 s | TCP listen on `0.0.0.0:7225` (exposed as the Spaces API interface) |
| `subs-prover` (daemon `ready`) | Subspaces Prover | 60 s | TCP listen on `0.0.0.0:8888`. Only present when Subspaces **and** the `set-subs-prover` toggle are enabled (toggle defaults off). Polled every 30 s; nothing depends on it. |
| `subs-registry` (daemon `ready`) | Subspaces Registry | 60 s | TCP listen on `0.0.0.0:8081`. Only present when Subspaces is enabled. |
| `subs` (daemon `ready`) | Subspaces Web UI | 60 s | TCP listen on `0.0.0.0:7777`. Only present when Subspaces is enabled. |
| `certrelay` (daemon `ready`) | Certrelay | 120 s | TCP listen on `0.0.0.0:7778`. Always on. Polled every 30 s. |
| `nacho` (daemon `ready`) | Nacho | 120 s | TCP listen on `0.0.0.0:8082`. Always on. Polled every 30 s. |
| `web-terminal` (daemon `ready`) | Web Interface | default | TCP listen on `0.0.0.0:8080` |
| `sync` (standalone) | Spaced Sync | 30 s | Exec `space-cli --output-format json getserverinfo`; reports `success` when `ready=true && progress=100%`, otherwise `loading` with progress percentage |
| `indexer` / `explorer-ui` / `indexer-sync` | — | — | **TODO** — removed with the build-from-source chain. Will return when the prebuilt indexer + explorer images are wired in. |
## Limitations and Differences
@@ -212,47 +183,28 @@ the same idempotent init logic runs and reuses the existing credentials in
via `space-cli` (aliased as `spaces` inside the shell).
4. **Externally exposed ports** (each a StartOS interface): 8080 (gotty
Space-CLI Web UI, always on), 7225 (Spaces API / spaced RPC, always on),
7778 (Certrelay, always on), and — only while their feature is enabled —
3000 (Explorer Web UI, currently stubbed), 7777 (Subspaces Web UI), 8888
(Subspaces Prover), 8081 (Subspaces Registry). **Loopback-only:** PostgreSQL
(5432). The spaced RPC is authenticated (static creds) even though it's now
externally exposed. The Subspaces registry is remapped from its upstream
default 8080 to 8081 to avoid colliding with the gotty terminal.
7778 (Certrelay, always on), 8082 (Nacho, always on), and — only while
Subspaces is enabled — 7777 (Subspaces Web UI + Subs API), 8888 (Subspaces
Prover, only if its sub-toggle is on), 8081 (Subspaces Registry). The
spaced RPC is authenticated (static creds). The Subspaces registry is
remapped from its upstream default 8080 to 8081 to avoid colliding with the
gotty terminal.
5. **Bitcoin Core 31.x is the only supported dependency.** Earlier majors are
not allowed by the manifest version range.
6. **The web terminal is independent of spaced.** Gotty stays reachable even
when `spaced` is crash-looping, so you can always shell in to diagnose.
7. **The embedded explorer is opt-in — and currently PostgreSQL-only.** Fresh
installs run in spaces-only mode (spaced + gotty). Run **Enable Embedded
Explorer** to start PostgreSQL; **Disable Embedded Explorer** stops it. The
indexer and explorer-UI daemons are **stubbed out** pending prebuilt images
(the build-from-source chain was removed to shrink the `.s9pk` and cut
startup time). So enabling the explorer today brings up an empty database
and nothing else. PostgreSQL data is preserved across toggles.
8. **PostgreSQL is embedded, not a separate service.** There is no
cross-service dependency on a postgres .s9pk; the database is local to this
package, lives at `/data/postgres`, and is intended for the (pending)
prebuilt indexer + explorer UI. Connect to it from inside the gotty
terminal with `psql $DB_URL`.
9. **Subspaces pointers data note.** When the prebuilt indexer is wired back
in, be aware our spaced binary predates the spaces pointers feature; the
prior build-from-source indexer was patched to treat `ptrs_root` as optional
and to skip the `getptrblockmeta` RPC. A future rebuild of
`horologger/spaces` with a newer spaced will let us drop those patches.
10. **Subspaces is opt-in.** Fresh installs do not run Subspaces. Run **Enable
Subspaces** to start it. It ships as the prebuilt `horologger/subs:v0.1.0`
image (no compile step), so enabling is fast — the three daemons start as
soon as the image is on the box. Enabling runs three daemons, each with its
own StartOS interface: **subs** (Web UI, 7777), **registry-server** (8081),
and — only if the separate **Enable / Disable Subspaces Prover** toggle is
on (default **off**) — **subs-prover** (8888, no GPU). The prover's
interface is always registered even when its daemon is off. subs loads the
existing `default` spaces
wallet at startup and does **not** create it — create it first from the
Space-CLI Web UI with `spaces createwallet` if you haven't. Subspaces is
independent of the Embedded Explorer toggle — you can run any combination
of {explorer, subspaces}.
11. **Certrelay is always on.** It ships as the prebuilt
7. **Subspaces is opt-in.** Fresh installs do not run Subspaces. Run **Enable
Subspaces** to start it. It ships as the prebuilt `horologger/subs:v0.1.2`
image (no compile step), so enabling is fast — the daemons start as soon
as the image is on the box. Enabling runs three daemons, each with its own
StartOS interface: **subs** (Web UI + Subs API, 7777), **registry-server**
(8081), and — only if the separate **Enable / Disable Subspaces Prover**
toggle is on (default **off**) — **subs-prover** (8888, no GPU). The
prover's interface is always registered even when its daemon is off. subs
loads the existing `default` spaces wallet at startup and does **not**
create it — create it first from the Space-CLI Web UI with `spaces
createwallet` if you haven't.
8. **Certrelay is always on.** It ships as the prebuilt
`horologger/certrelay:v0.2.3` image (static musl binaries) and runs on
7778 from service start. It talks to the local spaced over loopback using
the `store.spacedAuth` credentials. The bundled `fabric` CLI is copied to
@@ -294,23 +246,20 @@ package_id: spaces
upstream_version: subspacesplus
images:
spaces: docker.io/horologger/spaces:v0.0.9s
postgres: docker.io/postgres:16.3
subspaces: docker.io/horologger/subs:v0.1.0
subspaces: docker.io/horologger/subs:v0.1.2
certrelay: docker.io/horologger/certrelay:v0.2.3
# TODO: prebuilt indexer image (was golang:1.23-alpine builder, removed)
# TODO: prebuilt explorer image (was node:20-alpine builder, removed)
nacho: docker.io/horologger/nacho:v1.0.0
architectures: [x86_64, aarch64]
volumes:
main: /data
ports:
ui: 8080
explorer_ui: 3000 # interface registered; daemon stubbed (TODO prebuilt image)
subspaces_ui: 7777 # external, only useful while subspaces enabled
subspaces_prover: 8888 # external (its own interface), subspaces only
subspaces_registry: 8081 # external (its own interface), subspaces only; remapped from upstream 8080
certrelay: 7778 # external (its own interface), always on
nacho: 8082 # external (its own interface), always on
spaced_rpc: 7225 # external (Spaces API interface); spaced binds 0.0.0.0, auth-gated
postgres: 5432 # loopback only
dependencies:
- bitcoind
spaced_env_vars:
@@ -331,37 +280,43 @@ spaced_env_vars:
- BTC_RPC_PASSWORD
- APP_USER
- APP_PASSWORD
- DB_URL
postgres_env_vars:
- POSTGRES_USER
- POSTGRES_PASSWORD
- POSTGRES_DB
- PGDATA
explorer:
default_enabled: false # opt-in via Enable Embedded Explorer action
store_field: enableExplorer
status: postgres_only # indexer + explorer-ui daemons stubbed; see TODOs
reset_actions: [reset-db-state, reset-indexer-state, reset-explorer-state]
indexer:
status: TODO # build-from-source (Go) removed; prebuilt image pending
prior_source_repo: spacesprotocol/explorer-indexer
data_dir: /data/explorer-indexer # reset-indexer-state still wipes this
explorer_ui:
status: TODO # build-from-source (SvelteKit) removed; prebuilt image pending
prior_source_repo: randomlogin/explorer
data_dir: /data/explorer-ui # reset-explorer-state still wipes this
port: 3000 # interface registered; daemon stubbed
subspaces:
default_enabled: false # opt-in via Enable Subspaces action
store_field: enableSubspaces
subs_prover_default_enabled: false # separate toggle: set-subs-prover (store.enableSubsProver)
image: horologger/subs:v0.1.0 # prebuilt; no compile step
image: horologger/subs:v0.1.2 # prebuilt; no compile step
data_dir: /data/subspaces/data
wallet: default # loaded by subs, NOT created (create via space-cli first)
daemons: # three separate daemons, each its own interface
subs: { bin: /usr/local/bin/subs, port: 7777 }
subs-prover: { bin: /usr/local/bin/subs-prover, port: 8888, gpu: none }
registry-server: { bin: /usr/local/bin/registry-server, port: 8081 } # remapped from upstream 8080
auth: # optional HTTP basic auth in front of subs (Web UI + Subs API on 7777)
default_enabled: false
store_enabled_field: subsAuthEnabled
store_creds_field: subsAuth # { username, password }; persists across enable/disable
default_username: spaces
env_vars: # injected only when subsAuthEnabled=true AND subsAuth!=null
- SUBS_BASIC_AUTH_USER
- SUBS_BASIC_AUTH_PASSWORD
actions:
- enable-subs-auth
- disable-subs-auth
- show-subs-credentials
- set-subs-credentials
prover_auth: # optional HTTP basic auth in front of subs-prover (8888)
default_enabled: false
store_enabled_field: subsProverAuthEnabled
store_creds_field: subsProverAuth
default_username: spaces
env_vars: # injected only when subsProverAuthEnabled=true AND subsProverAuth!=null
- SUBS_PROVER_BASIC_AUTH_USER
- SUBS_PROVER_BASIC_AUTH_PASSWORD
actions:
- enable-subs-prover-auth
- disable-subs-prover-auth
- show-subs-prover-credentials
- set-subs-prover-credentials
certrelay:
always_on: true
image: horologger/certrelay:v0.2.3 # prebuilt; static musl binaries
@@ -380,41 +335,42 @@ certrelay:
CERTRELAY_SELF_URL: https://certrelay.spacesops.com # default; set to your public URL
CERTRELAY_BOOTSTRAP: 'false' # toggle via action
CERTRELAY_HEALTHCHECK_HANDLE: account-digital-useful.genesis@key # via action
managed_env_vars:
- POSTGRES_URI
- BITCOIN_NODE_URI
- BITCOIN_NODE_USER
- BITCOIN_NODE_PASSWORD
- SPACES_NODE_URI
- RPC_USER
- RPC_PASSWORD
- ACTIVATION_BLOCK_HEIGHT
- FAST_SYNC_BLOCK_HEIGHT
- UPDATE_DB_INTERVAL
- MEMPOOL_CHUNK_SIZE
defaults:
ACTIVATION_BLOCK_HEIGHT: '871222' # spaces mainnet activation
FAST_SYNC_BLOCK_HEIGHT: '864000'
UPDATE_DB_INTERVAL: '5'
MEMPOOL_CHUNK_SIZE: '200'
nacho:
always_on: true
image: horologger/nacho:v1.0.0 # Expo dev server
port: 8082
data_dir: /data/nacho
ignore_names_file: /data/nacho/ignore_names.txt # read at runtime; default 'fold,swifty' seeded by nacho-setup
configurable_via_actions:
- configure-nacho # ignore_names.txt + EXPO_PUBLIC_WORKSHOP_PDF_LINK_TEXT
- upload-support-pdf # writes /data/support.pdf
env:
EXPO_PUBLIC_API_BASE_URL: <derived from subs-api StartOS interface>
EXPO_PUBLIC_WORKSHOP_PDF_LINK_TEXT: '' # set via configure-nacho
EXPO_DEV_PORT: '8082'
actions:
- reset-password
- show-credentials
- show-password
- set-bitcoin-rpc
- show-spaced-credentials
- sync-status
- reset-spaced-state
- export-wallet
- import-wallet
- enable-explorer
- disable-explorer
- show-db-credentials
- reset-db-state
- reset-indexer-state
- reset-explorer-state
- enable-subspaces
- disable-subspaces
- set-subs-prover
- enable-subs-auth
- disable-subs-auth
- show-subs-credentials
- set-subs-credentials
- enable-subs-prover-auth
- disable-subs-prover-auth
- show-subs-prover-credentials
- set-subs-prover-credentials
- reset-subspaces-state
- configure-certrelay
- configure-nacho
- upload-support-pdf
```