spacesops b308d0ceaa
Build Service / BuildPackage (push) Has been cancelled
v0.0.9:2
2026-05-23 02:37:38 -04:00
2026-05-14 00:22:24 -04:00
2026-05-14 05:39:56 -04:00
2026-05-23 02:37:38 -04:00
2026-05-14 00:22:24 -04:00
2026-05-14 00:22:24 -04:00
2026-05-14 18:27:20 -04:00
2026-05-14 05:39:56 -04:00
2026-05-14 05:39:56 -04:00
2026-05-14 05:39:56 -04:00
2026-05-14 05:39:56 -04:00
2026-05-23 02:37:38 -04:00
2026-05-14 05:39:56 -04:00
2026-05-14 05:39:56 -04:00

Spaces

Spaces on StartOS

Upstream docs: https://docs.spacesprotocol.org/

Everything not listed in this document should behave the same as upstream spaced / space-cli. If a feature, setting, or behavior is not mentioned here, the upstream documentation is accurate and fully applicable.

Spaces is a permissionless protocol for sovereign Bitcoin-anchored identities. This package runs the spaced daemon against Bitcoin mainnet and exposes space-cli through a browser-based terminal.


Table of Contents


Image and Container Runtime

Field Value
Spaces image docker.io/horologger/spaces
PostgreSQL image docker.io/postgres:16.3
Subspaces image docker.io/horologger/subs:v0.1.0
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
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.

Volume and Data Layout

Path Volume Purpose
/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/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.

Installation and First-Run Flow

On the first install, StartOS:

  1. Seeds store.json.password with a random 32-char alphanumeric admin password and creates a critical task that points the user at Show Space-CLI Web UI Credentials so the password can be copied before login.
  2. Seeds store.json.btcAuth with a random spaces:<random> RPC credential 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 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 = 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) and the gotty web terminal once the bashrc oneshot completes.
  9. 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.

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:

  1. Postgres-chown oneshot creates /data/postgres with correct ownership.
  2. 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-fetchindexer-buildindexer-migrateindexer, and explorer-fetchexplorer-installexplorer-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
Chain selection (locked to mainnet)
Spaced data directory and RPC bind

Network Access and Interfaces

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 UI. No built-in auth. 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 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.
Spaced RPC 7225 HTTP JSON-RPC Loopback only Internal use, static-cred-authenticated via SPACED_RPC_USER / SPACED_RPC_PASSWORD from store.json.spacedAuth
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

Actions

ID Name Visibility Availability Purpose
reset-password Reset Space-CLI Web UI Password Enabled Any Regenerates the Space-CLI Web UI password and restarts the terminal daemon
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.
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.
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.

Backups and Restore

sdk.Backups.ofVolumes('main') -- the entire /data volume is backed up, including spaced state, wallets, the block index, and store.json. On restore, the same idempotent init logic runs and reuses the existing credentials in store.json.

Health Checks

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 127.0.0.1:7225
subs-prover (daemon ready) Subspaces Prover 60 s TCP listen on 0.0.0.0:8888. Only present when Subspaces is enabled.
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.
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

  1. Mainnet only. Testnet, testnet4, signet, and regtest are not exposed.
  2. The Spaces image's docker_entrypoint.sh is not used. Its auto-start of spaced inside screen would conflict with the StartOS-managed daemon.
  3. Space-CLI Web UI is a terminal, not a graphical app. All Spaces operations happen 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), 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: spaced RPC (7225) and PostgreSQL (5432). 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), subs-prover (8888, no GPU), registry-server (8081). 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 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 /data/bin/fabric so it's runnable from the Space-CLI Web UI. You must set CERTRELAY_SELF_URL (via Configure Certrelay) to the publicly visible URL StartOS exposes for the Certrelay interface, or peers/clients won't be able to reach this relay at the advertised address.
  • space-cli subcommands and flags work exactly as documented upstream.
  • spaced honours all SPACED_* environment variables not otherwise set by StartOS.
  • Wallet files, the spaces database, and the block index are managed by spaced itself; StartOS only provides the volume.
  • bitcoind connectivity follows the standard StartOS dependency-service model (bitcoind.startos:8332).

Using the Web Terminal

After install:

  1. Run the Show Space-CLI Web UI Credentials action (the install task surfaces it).
  2. Open the Space-CLI Web UI from the StartOS dashboard.
  3. Log in with admin and the displayed password.
  4. Use spaces <subcommand> -- it expands to space-cli --chain mainnet --rpc-user "$SPACED_RPC_USER" --rpc-password "$SPACED_RPC_PASSWORD" <subcommand>.

Examples:

spaces getserverinfo
spaces createwallet           # creates the `default` wallet (--wallet defaults to "default")
spaces balance

Quick Reference for AI Consumers

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
  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)
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
  spaced_rpc: 7225      # loopback only
  postgres: 5432        # loopback only
dependencies:
  - bitcoind
spaced_env_vars:
  - SPACED_CHAIN
  - SPACED_DATA_DIR
  - SPACED_RPC_BIND
  - SPACED_RPC_PORT
  - SPACED_RPC_URL
  - SPACED_RPC_USER
  - SPACED_RPC_PASSWORD
  - SPACED_BLOCK_INDEX
  - SPACED_BITCOIN_RPC_URL
  - SPACED_BITCOIN_RPC_USER
  - SPACED_BITCOIN_RPC_PASSWORD
  - BTC_RPC_HOST
  - BTC_RPC_PORT
  - BTC_RPC_USER
  - 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
  image: horologger/subs:v0.1.0   # 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
certrelay:
  always_on: true
  image: horologger/certrelay:v0.2.3   # prebuilt; static musl binaries
  server_bin: /usr/local/bin/certrelay
  fabric_bin: /usr/local/bin/fabric    # copied to /data/bin/fabric for the CLI
  data_dir: /data/certrelay/data
  port: 7778
  spaced_rpc_creds: from store.spacedAuth (local spaced)
  configurable_via_action: configure-certrelay
  env:
    CERTRELAY_CHAIN: mainnet
    CERTRELAY_BIND: 0.0.0.0
    CERTRELAY_PORT: '7778'
    CERTRELAY_REMOTE_IP_HEADER: x-forwarded-for
    CERTRELAY_ANCHOR_REFRESH: '300'
    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'
actions:
  - reset-password
  - show-credentials
  - show-password
  - set-bitcoin-rpc
  - 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
  - reset-subspaces-state
  - configure-certrelay
S
Description
No description provided
Readme MIT
341 KiB
Languages
TypeScript 99.9%
Makefile 0.1%