Build SpacesOps StartOS package (v1.0.0:0)
Initial .s9pk for SpacesOps, targeting StartOS 0.4.0.x with SDK 1.5.1. - Single managed daemon from spacesops/spacesops:v1.0.0 (x86_64 + aarch64), keeping the image entrypoint (/app/docker-entrypoint.sh node server.js). Forces PLATFORM_HOST=0.0.0.0 / PLATFORM_PORT=7264 so the StartOS proxy can reach the app. Single `ui` interface on 7264. - Depends on the Spaces service (>=0.0.9:3) and auto-wires the spaced RPC creds: main.ts mounts the Spaces `main` volume read-only at /spaces-data, execs a read of its store.json inside the subcontainer, and injects SPACED_RPC_USER/ PASSWORD + SPACED_RPC_URL=http://spaces.startos:7225. Throws to retry until Spaces is installed and seeded. - Generates a Nostr operator keypair (nostr-tools, bundled by ncc) and a strong session secret in idempotent init tasks (.once() reads, allowWriteAfterConst merges). Actions: show-operator-credentials, import-operator-key, show-admin-credentials (surfaces the fixed admin/Whatever! login with a warning), configure-platform (optional relay/mode/CoinGecko/SUBSD). - Install alert warns to install Spaces first and about the fixed admin credential. Backs up the `main` volume. - Icon: icon.svg (source spacesops.svg). The `spaces` dependency uses assets/spaces-icon.png for its Marketplace metadata. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
<p align="center">
|
||||
<img src="icon.svg" alt="SpacesOps" width="180" />
|
||||
</p>
|
||||
|
||||
# SpacesOps on StartOS
|
||||
|
||||
> **Upstream repo:** <https://git.spacesops.com/spacesops/spacesops>
|
||||
>
|
||||
> Everything not listed in this document should behave the same as upstream
|
||||
> SpacesOps. If a feature, setting, or behavior is not mentioned here, the
|
||||
> upstream documentation is accurate and fully applicable.
|
||||
|
||||
SpacesOps is a web platform for confirming [Spaces](https://spacesprotocol.org)
|
||||
ownership and selling subspace names. It talks to the Spaces `spaced` daemon
|
||||
over JSON-RPC, signs operator events on Nostr, and optionally integrates pricing
|
||||
and subname-purchase backends. On StartOS it **requires the Spaces service** and
|
||||
auto-connects to it — see [Installation and First-Run Flow](#installation-and-first-run-flow).
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Image and Container Runtime](#image-and-container-runtime)
|
||||
- [Volume and Data Layout](#volume-and-data-layout)
|
||||
- [Installation and First-Run Flow](#installation-and-first-run-flow)
|
||||
- [The Spaces Dependency (auto-wiring)](#the-spaces-dependency-auto-wiring)
|
||||
- [Configuration Management](#configuration-management)
|
||||
- [Network Access and Interfaces](#network-access-and-interfaces)
|
||||
- [Actions](#actions)
|
||||
- [Backups and Restore](#backups-and-restore)
|
||||
- [Health Checks](#health-checks)
|
||||
- [Limitations and Differences](#limitations-and-differences)
|
||||
- [What Is Unchanged from Upstream](#what-is-unchanged-from-upstream)
|
||||
- [Quick Reference for AI Consumers](#quick-reference-for-ai-consumers)
|
||||
|
||||
---
|
||||
|
||||
## Image and Container Runtime
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Image | `docker.io/spacesops/spacesops:v1.0.0` |
|
||||
| Base | `node:20-alpine` |
|
||||
| Architectures | `x86_64` (linux/amd64), `aarch64` (linux/arm64) |
|
||||
| Entrypoint | The image's `/app/docker-entrypoint.sh` is **kept**. StartOS runs `/app/docker-entrypoint.sh node server.js` as the daemon. |
|
||||
| Runs as | `root`, working directory `/app` |
|
||||
|
||||
The image bundles Node 20 and the app's `node_modules` (including `nostr-tools`
|
||||
and `bitcoinjs-lib`). The entrypoint creates `/data{,/spaces,/signed}`, symlinks
|
||||
`/app/data` → `/data`, and loads defaults from `/app/setup-spacesops-env.sh` for
|
||||
any environment variable StartOS leaves unset, then exec's `node server.js`.
|
||||
|
||||
## Volume and Data Layout
|
||||
|
||||
| Path | Volume | Purpose |
|
||||
| --- | --- | --- |
|
||||
| `/data` | `main` | SpacesOps data directory. SQLite databases (`local.db`, `sessions.db`, `prices.db`, per-tenant DBs), signed artifacts, and StartOS `store.json`. |
|
||||
| `/data/local.db` | `main` | Primary SQLite database (`PLATFORM_DB_PATH`). DB migrations auto-run on startup. |
|
||||
| `/data/store.json` | `main` | StartOS-managed settings: the generated Nostr operator keypair, the generated session secret, and optional Configure-Platform values. |
|
||||
| `/spaces-data` | _Spaces `main`_ | The **Spaces** service's volume, mounted **read-only**. Used only at startup to read the spaced RPC credentials — see below. |
|
||||
|
||||
## Installation and First-Run Flow
|
||||
|
||||
On first install, StartOS:
|
||||
|
||||
1. Generates a **Nostr operator keypair** (`operatorSecretHex` /
|
||||
`operatorPublicHex` in `store.json`). SpacesOps requires this keypair at
|
||||
startup; the **Show Operator Credentials** action surfaces it (npub / nsec /
|
||||
hex), and **Import Operator Key** replaces it with one you supply.
|
||||
2. Generates a strong **session secret** (`sessionSecret`), replacing the weak
|
||||
hardcoded default the upstream image ships with.
|
||||
3. Reads the **spaced RPC credentials from the Spaces service** and connects to
|
||||
it (see next section). The service will not finish starting until those
|
||||
credentials are available.
|
||||
|
||||
There is no upstream setup wizard to complete — the operator keypair and session
|
||||
secret are provisioned automatically.
|
||||
|
||||
## The Spaces Dependency (auto-wiring)
|
||||
|
||||
SpacesOps **requires the Spaces service** (`spaces`, version `>=0.0.9:3`).
|
||||
**Install and sync Spaces first.** SpacesOps does not ask you for spaced RPC
|
||||
credentials. Instead, at startup it:
|
||||
|
||||
1. Mounts the Spaces `main` volume read-only at `/spaces-data`.
|
||||
2. Reads `spacedAuth.{username,password}` from the Spaces `store.json`.
|
||||
3. Connects to spaced at `http://spaces.startos:7225` with those credentials,
|
||||
exporting `SPACED_RPC_URL`, `SPACED_RPC_USER`, `SPACED_RPC_PASSWORD`, and
|
||||
`SPACED_WALLETLOAD_NAME=main`.
|
||||
|
||||
If Spaces is not installed yet, or its credentials have not been seeded, the
|
||||
service **restarts until they appear** — this is expected. (Dependency
|
||||
declarations do not gate startup; SpacesOps handles readiness itself.)
|
||||
|
||||
## Configuration Management
|
||||
|
||||
| StartOS-Managed | Upstream-Managed |
|
||||
| --- | --- |
|
||||
| `PLATFORM_HOST` / `PLATFORM_PORT` (forced to `0.0.0.0:7264` so the proxy can reach the app) | Everything inside the SpacesOps web UI / admin area |
|
||||
| `PLATFORM_DB_PATH` (`/data/local.db`) | Tenant management, space-ownership flows |
|
||||
| `OPERATOR_SECRET_HEX` / `OPERATOR_PUBLIC_HEX` (generated or imported) | |
|
||||
| `PLATFORM_SESSION_SECRET` (generated) | |
|
||||
| `SPACED_RPC_*` (auto-wired from Spaces) | |
|
||||
| Optional: `OPERATOR_RELAY`, `PLATFORM_MODE`, `COINGECKO_*`, `SUBSD_*` (via **Configure Platform**) | |
|
||||
|
||||
## Network Access and Interfaces
|
||||
|
||||
| Interface | Port | Protocol | Exposure | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Web UI | 7264 | HTTP | LAN / `.local` / Tor / clearnet (via StartOS) | The SpacesOps web platform + admin area. The app provides its own auth; the admin area uses a **fixed built-in credential** (see warning below). |
|
||||
|
||||
## Actions
|
||||
|
||||
| ID | Name | Visibility | Availability | Inputs | Purpose |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `show-operator-credentials` | Show Operator Credentials | Enabled | Any | — | Displays the Nostr operator keypair: npub (QR), hex public key, and the masked nsec / hex secret. |
|
||||
| `import-operator-key` | Import Operator Key | Enabled | Any | 64-char hex secret key | Replaces the operator keypair. Derives the public key automatically. **Warns** that it changes the operator identity; the service restarts to apply it. |
|
||||
| `show-admin-credentials` | Show Admin Credentials | Enabled | Any | — | Displays the **fixed** built-in admin login (`admin` / `Whatever!`) with a security warning. |
|
||||
| `configure-platform` | Configure Platform | Enabled | Any | relay, mode, CoinGecko, SUBSD (all optional) | Sets the Nostr relay, theme mode, pricing, and SUBSD backend. Saving restarts the service. |
|
||||
|
||||
## Backups and Restore
|
||||
|
||||
`sdk.Backups.ofVolumes('main')` — the entire `/data` volume is backed up,
|
||||
including all SQLite databases, signed artifacts, and `store.json` (operator
|
||||
keypair, session secret, and Configure-Platform settings). On restore, the same
|
||||
idempotent init runs and reuses the existing keypair and secret. The Spaces
|
||||
volume is **not** part of this package's backup.
|
||||
|
||||
## Health Checks
|
||||
|
||||
| ID | Display | Grace period | Behaviour |
|
||||
| --- | --- | --- | --- |
|
||||
| `spacesops` (daemon `ready`) | Web Interface | 60 s | TCP listen on `0.0.0.0:7264` |
|
||||
|
||||
## Limitations and Differences
|
||||
|
||||
1. **Requires the Spaces service.** SpacesOps auto-connects to `spaces.startos:7225`
|
||||
by reading the Spaces RPC credentials from the mounted Spaces volume. Install
|
||||
and sync Spaces before (or alongside) SpacesOps; the service restarts until
|
||||
those credentials are available.
|
||||
2. **The admin password is fixed and well-known.** Admin Basic Auth is hardcoded
|
||||
in the v1.0.0 image as `admin` / `Whatever!` with **no environment override**.
|
||||
It cannot be changed without rebuilding the image. **Keep this service private
|
||||
(Tor-only) and never expose its admin routes to the public internet** — the
|
||||
admin area can run SQL and manage tenants. See **Show Admin Credentials**.
|
||||
3. **`PLATFORM_HOST` is forced to `0.0.0.0` and `PLATFORM_PORT` to `7264`** so the
|
||||
StartOS reverse proxy can reach the app (it otherwise binds `127.0.0.1:3000`).
|
||||
4. **Subname-purchase and pricing are off by default.** They activate only when
|
||||
you fill in the relevant fields in **Configure Platform** (`COINGECKO_*` for
|
||||
pricing, `SUBSD_*` for subname purchase + cert-callback flows).
|
||||
5. **SUBSD is not auto-wired to the Spaces subs daemon in v1.** The Spaces subs
|
||||
daemon listens on 7777 with a different API/auth than the SUBSD-on-7244 this
|
||||
app expects, so SUBSD must be configured manually if used.
|
||||
|
||||
## What Is Unchanged from Upstream
|
||||
|
||||
- All SpacesOps web UI, admin, and REST API routes behave as upstream documents.
|
||||
- SQLite schema and migrations are managed by the app and run on startup.
|
||||
- `nostr-tools` / `bitcoinjs-lib` cryptography ships in the image and is used
|
||||
exactly as upstream.
|
||||
- Any environment variable not set by StartOS falls back to the image's
|
||||
`setup-spacesops-env.sh` defaults.
|
||||
|
||||
## Quick Reference for AI Consumers
|
||||
|
||||
```yaml
|
||||
package_id: spacesops
|
||||
upstream_version: 1.0.0
|
||||
image: docker.io/spacesops/spacesops:v1.0.0
|
||||
architectures: [x86_64, aarch64]
|
||||
volumes:
|
||||
main: /data
|
||||
mounted_dependencies:
|
||||
spaces: /spaces-data # read-only; used to read spaced RPC creds at startup
|
||||
ports:
|
||||
ui: 7264
|
||||
dependencies:
|
||||
- spaces # kind: running, versionRange '>=0.0.9:3', healthChecks [spaced, sync]
|
||||
startos_managed_env_vars:
|
||||
- PLATFORM_HOST # forced 0.0.0.0
|
||||
- PLATFORM_PORT # forced 7264
|
||||
- PLATFORM_DB_PATH # /data/local.db
|
||||
- PLATFORM_MODE # store.platformMode ?? prod
|
||||
- PLATFORM_SESSION_SECRET # generated
|
||||
- OPERATOR_SECRET_HEX # generated or imported
|
||||
- OPERATOR_PUBLIC_HEX # derived
|
||||
- OPERATOR_RELAY # store.operatorRelay ?? wss://relay.primal.net
|
||||
- SPACED_RPC_URL # http://spaces.startos:7225
|
||||
- SPACED_RPC_USER # from Spaces store.json
|
||||
- SPACED_RPC_PASSWORD # from Spaces store.json
|
||||
- SPACED_WALLETLOAD_NAME # main
|
||||
optional_env_vars: # only set when configured via configure-platform
|
||||
- COINGECKO_API_KEY
|
||||
- COINGECKO_TOKEN_COINS
|
||||
- SUBSD_URI_VALUE
|
||||
- SUBSD_RPC_USER
|
||||
- SUBSD_RPC_PASSWORD
|
||||
admin_credentials:
|
||||
username: admin
|
||||
password: Whatever! # FIXED, baked into image, cannot be changed
|
||||
note: keep service private; admin area can run SQL and manage tenants
|
||||
actions:
|
||||
- show-operator-credentials
|
||||
- import-operator-key
|
||||
- show-admin-credentials
|
||||
- configure-platform
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user