pre
This commit is contained in:
@@ -39,7 +39,7 @@ auto-connects to it — see [Installation and First-Run Flow](#installation-and-
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Image | `docker.io/spacesops/spacesops:v1.0.1` |
|
||||
| Image | `docker.io/spacesops/spacesops:v1.0.3` |
|
||||
| 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. |
|
||||
@@ -86,7 +86,7 @@ credentials. Instead, at startup it:
|
||||
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`.
|
||||
`SPACED_WALLETLOAD_NAME=default`.
|
||||
|
||||
If Spaces is not installed yet, or its credentials have not been seeded, the
|
||||
service **restarts until they appear** — this is expected. (Dependency
|
||||
@@ -101,6 +101,7 @@ declarations do not gate startup; SpacesOps handles readiness itself.)
|
||||
| `OPERATOR_SECRET_HEX` / `OPERATOR_PUBLIC_HEX` (generated or imported) | |
|
||||
| `PLATFORM_SESSION_SECRET` (generated) | |
|
||||
| `SPACED_RPC_*` (auto-wired from Spaces) | |
|
||||
| `PLATFORM_CALLBACK_HOST` (defaults to `spacesops.startos`; override via **Configure Platform**) | |
|
||||
| Optional: `OPERATOR_RELAY`, `PLATFORM_MODE`, `COINGECKO_*`, `SUBS_*` (via **Configure Platform**) | |
|
||||
|
||||
## Network Access and Interfaces
|
||||
@@ -116,7 +117,7 @@ declarations do not gate startup; SpacesOps handles readiness itself.)
|
||||
| `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, SUBS (all optional) | Sets the Nostr relay, theme mode, pricing, and SUBS backend. Saving restarts the service. |
|
||||
| `configure-platform` | Configure Platform | Enabled | Any | relay, mode, CoinGecko, SUBS, callback host | Sets the Nostr relay, theme mode, pricing, SUBS backend, and `PLATFORM_CALLBACK_HOST`. Saving restarts the service. |
|
||||
|
||||
## Backups and Restore
|
||||
|
||||
@@ -139,7 +140,7 @@ volume is **not** part of this package's backup.
|
||||
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.1 image as `admin` / `Whatever!` with **no environment override**.
|
||||
in the v1.0.3 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**.
|
||||
@@ -147,14 +148,16 @@ volume is **not** part of this package's backup.
|
||||
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, `SUBS_*` for subname purchase + cert-callback flows).
|
||||
pricing, `SUBS_*` for subname purchase + cert-callback flows). Payment
|
||||
callback URLs use `PLATFORM_CALLBACK_HOST`, which defaults to `spacesops.startos`
|
||||
and can be overridden in **Configure Platform**.
|
||||
5. **The SUBS backend is not auto-wired to the Spaces subs daemon in v1.** The
|
||||
Spaces service's subs daemon listens on 7777 with a different API/auth than
|
||||
the SUBS endpoint (port 7244) SpacesOps expects, so SUBS must be configured
|
||||
manually if used. StartOS always sets `NODE_EXTRA_CA_CERTS` to the StartOS
|
||||
root CA (fetched via `sdk.getSslCertificate` for the SUBS `*.startos`
|
||||
hostname when configured, otherwise `spaces.startos`) so outbound HTTPS to
|
||||
same-host StartOS services succeeds and the v1.0.1 image entrypoint does not
|
||||
same-host StartOS services succeeds and the v1.0.3 image entrypoint does not
|
||||
crash on its broken `_SCRIPT_DIR` default.
|
||||
|
||||
## What Is Unchanged from Upstream
|
||||
@@ -170,8 +173,8 @@ volume is **not** part of this package's backup.
|
||||
|
||||
```yaml
|
||||
package_id: spacesops
|
||||
upstream_version: 1.0.1
|
||||
image: docker.io/spacesops/spacesops:v1.0.1
|
||||
upstream_version: 1.0.3
|
||||
image: docker.io/spacesops/spacesops:v1.0.3
|
||||
architectures: [x86_64, aarch64]
|
||||
volumes:
|
||||
main: /data
|
||||
@@ -193,7 +196,8 @@ startos_managed_env_vars:
|
||||
- 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
|
||||
- SPACED_WALLETLOAD_NAME # default
|
||||
- PLATFORM_CALLBACK_HOST # store.platformCallbackHost ?? spacesops.startos
|
||||
optional_env_vars: # only set when configured via configure-platform
|
||||
- COINGECKO_API_KEY
|
||||
- COINGECKO_TOKEN_COINS
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -4,6 +4,7 @@ import { sdk } from '../sdk'
|
||||
import {
|
||||
DEFAULT_COINGECKO_TOKEN_COINS,
|
||||
DEFAULT_OPERATOR_RELAY,
|
||||
DEFAULT_PLATFORM_CALLBACK_HOST,
|
||||
DEFAULT_PLATFORM_MODE,
|
||||
} from '../utils'
|
||||
|
||||
@@ -103,6 +104,20 @@ const inputSpec = InputSpec.of({
|
||||
minLength: null,
|
||||
maxLength: null,
|
||||
}),
|
||||
platformCallbackHost: Value.text({
|
||||
name: i18n('CALLBACK HOST'),
|
||||
description: i18n(
|
||||
'Callback hostname SpacesOps uses for cert-callback flows (PLATFORM_CALLBACK_HOST). Leave blank to use spacesops.startos.',
|
||||
),
|
||||
warning: null,
|
||||
footnote: null,
|
||||
default: DEFAULT_PLATFORM_CALLBACK_HOST,
|
||||
required: false,
|
||||
masked: false,
|
||||
placeholder: 'spacesops.startos',
|
||||
minLength: null,
|
||||
maxLength: null,
|
||||
}),
|
||||
})
|
||||
|
||||
export const configurePlatform = sdk.Action.withInput(
|
||||
@@ -113,7 +128,7 @@ export const configurePlatform = sdk.Action.withInput(
|
||||
async ({ effects }) => ({
|
||||
name: i18n('Configure Platform'),
|
||||
description: i18n(
|
||||
'Set optional SpacesOps settings: Nostr relay, theme mode, CoinGecko pricing, and SUBS backend. Saving restarts the service so the new settings take effect.',
|
||||
'Set optional SpacesOps settings: Nostr relay, theme mode, CoinGecko pricing, SUBS backend, and callback host. Saving restarts the service so the new settings take effect.',
|
||||
),
|
||||
warning: null,
|
||||
allowedStatuses: 'any',
|
||||
@@ -136,6 +151,8 @@ export const configurePlatform = sdk.Action.withInput(
|
||||
subsUrl: store?.subsUrl ?? null,
|
||||
subsUser: store?.subsUser ?? null,
|
||||
subsPassword: store?.subsPassword ?? null,
|
||||
platformCallbackHost:
|
||||
store?.platformCallbackHost ?? DEFAULT_PLATFORM_CALLBACK_HOST,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -149,6 +166,7 @@ export const configurePlatform = sdk.Action.withInput(
|
||||
subsUrl: input.subsUrl || null,
|
||||
subsUser: input.subsUser || null,
|
||||
subsPassword: input.subsPassword || null,
|
||||
platformCallbackHost: input.platformCallbackHost?.trim() || null,
|
||||
})
|
||||
|
||||
return {
|
||||
|
||||
@@ -16,6 +16,7 @@ const shape = z.object({
|
||||
subsUrl: z.string().nullable().catch(null),
|
||||
subsUser: z.string().nullable().catch(null),
|
||||
subsPassword: z.string().nullable().catch(null),
|
||||
platformCallbackHost: z.string().nullable().catch(null),
|
||||
})
|
||||
|
||||
export const storeJson = FileHelper.json(
|
||||
|
||||
@@ -16,7 +16,7 @@ const dict = {
|
||||
'SUBS RPC Password': 12,
|
||||
'Optional SUBS RPC password (SUBS_RPC_PASSWORD).': 13,
|
||||
'Configure Platform': 14,
|
||||
'Set optional SpacesOps settings: Nostr relay, theme mode, CoinGecko pricing, and SUBS backend. Saving restarts the service so the new settings take effect.': 15,
|
||||
'Set optional SpacesOps settings: Nostr relay, theme mode, CoinGecko pricing, SUBS backend, and callback host. Saving restarts the service so the new settings take effect.': 15,
|
||||
Success: 16,
|
||||
'Platform configuration saved. The service is restarting to apply the new settings.': 17,
|
||||
'Operator Secret Key (hex)': 18,
|
||||
@@ -50,6 +50,8 @@ const dict = {
|
||||
'Web Interface': 46,
|
||||
'The web interface is ready': 47,
|
||||
'The web interface is not ready': 48,
|
||||
'CALLBACK HOST': 49,
|
||||
'Callback hostname SpacesOps uses for cert-callback flows (PLATFORM_CALLBACK_HOST). Leave blank to use spacesops.startos.': 50,
|
||||
} as const
|
||||
|
||||
/**
|
||||
|
||||
+4
-1
@@ -5,6 +5,7 @@ import { sdk } from './sdk'
|
||||
import {
|
||||
dataDir,
|
||||
DEFAULT_OPERATOR_RELAY,
|
||||
DEFAULT_PLATFORM_CALLBACK_HOST,
|
||||
DEFAULT_PLATFORM_MODE,
|
||||
SPACED_RPC_URL,
|
||||
SPACED_WALLETLOAD_NAME,
|
||||
@@ -110,8 +111,10 @@ export const main = sdk.setupMain(async ({ effects }) => {
|
||||
if (store.subsUrl) env.SUBS_URI_VALUE = store.subsUrl
|
||||
if (store.subsUser) env.SUBS_RPC_USER = store.subsUser
|
||||
if (store.subsPassword) env.SUBS_RPC_PASSWORD = store.subsPassword
|
||||
env.PLATFORM_CALLBACK_HOST =
|
||||
store.platformCallbackHost ?? DEFAULT_PLATFORM_CALLBACK_HOST
|
||||
|
||||
// v1.0.1's entrypoint sources setup-spacesops-env.sh with set -u. That file
|
||||
// v1.0.3's entrypoint sources setup-spacesops-env.sh with set -u. That file
|
||||
// exports NODE_EXTRA_CA_CERTS using ${_SCRIPT_DIR}, but _SCRIPT_DIR is set on
|
||||
// a separate non-export line the entrypoint never evals — startup crashes
|
||||
// unless NODE_EXTRA_CA_CERTS is already set. Fetch the StartOS root CA for
|
||||
|
||||
@@ -14,7 +14,7 @@ export const manifest = setupManifest({
|
||||
volumes: ['main'],
|
||||
images: {
|
||||
spacesops: {
|
||||
source: { dockerTag: 'spacesops/spacesops:v1.0.1' },
|
||||
source: { dockerTag: 'spacesops/spacesops:v1.0.3' },
|
||||
arch: ['x86_64', 'aarch64'],
|
||||
},
|
||||
},
|
||||
|
||||
+6
-3
@@ -18,16 +18,16 @@ export const SPACES_PACKAGE_ID = 'spaces'
|
||||
// Spaces exposes its spaced JSON-RPC as the `spaces-api` interface on 7225,
|
||||
// reachable from a dependent package at this address.
|
||||
export const SPACED_RPC_URL = 'http://spaces.startos:7225'
|
||||
export const SPACED_WALLETLOAD_NAME = 'main'
|
||||
export const SPACED_WALLETLOAD_NAME = 'default'
|
||||
|
||||
// Admin Basic Auth is baked into the v1.0.1 image with NO env override. It
|
||||
// Admin Basic Auth is baked into the v1.0.3 image with NO env override. It
|
||||
// cannot be changed without rebuilding the image. Surfaced (with a warning)
|
||||
// via the "Show Admin Credentials" action.
|
||||
export const ADMIN_USER = 'admin'
|
||||
export const ADMIN_PASSWORD = 'Whatever!'
|
||||
|
||||
// Where StartOS writes the StartOS root CA for outbound *.startos HTTPS (see
|
||||
// main.ts). Always injected as NODE_EXTRA_CA_CERTS — required on v1.0.1+ where
|
||||
// main.ts). Always injected as NODE_EXTRA_CA_CERTS — required on v1.0.3+ where
|
||||
// the image entrypoint's setup-spacesops-env.sh references _SCRIPT_DIR without
|
||||
// defining it under set -u.
|
||||
export const nodeExtraCaCertVolumeSubpath = '.startos/startos-root-ca.crt'
|
||||
@@ -51,6 +51,9 @@ export function startOsHostnameFromUrl(url: string): string | null {
|
||||
export const DEFAULT_OPERATOR_RELAY = 'wss://relay.primal.net'
|
||||
export const DEFAULT_PLATFORM_MODE = 'prod'
|
||||
export const DEFAULT_COINGECKO_TOKEN_COINS = 'bitcoin'
|
||||
// Hostname SpacesOps uses when building payment callback URLs
|
||||
// (http://${PLATFORM_CALLBACK_HOST}:${PORT}/...).
|
||||
export const DEFAULT_PLATFORM_CALLBACK_HOST = 'spacesops.startos'
|
||||
|
||||
// 32 random bytes as a 64-char hex string — a secp256k1/Nostr secret key. The
|
||||
// odds of an out-of-range key are ~1 in 2^128; if getPublicKey rejects it,
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { VersionGraph } from '@start9labs/start-sdk'
|
||||
import { v_1_0_1_0 } from './v1.0.1.0'
|
||||
import { v_1_0_1_1 } from './v1.0.1.1'
|
||||
import { v_1_0_2_0 } from './v1.0.2.0'
|
||||
import { v_1_0_2_1 } from './v1.0.2.1'
|
||||
import { v_1_0_3_0 } from './v1.0.3.0'
|
||||
|
||||
export const versionGraph = VersionGraph.of({
|
||||
current: v_1_0_1_1,
|
||||
other: [v_1_0_1_0],
|
||||
current: v_1_0_3_0,
|
||||
other: [v_1_0_2_1, v_1_0_2_0, v_1_0_1_1, v_1_0_1_0],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
export const v_1_0_2_0 = VersionInfo.of({
|
||||
version: '1.0.2:0',
|
||||
releaseNotes: {
|
||||
en_US: `Upstream upgrade to SpacesOps v1.0.2.
|
||||
- Bumps the image to spacesops/spacesops:v1.0.2 on x86_64 and aarch64.
|
||||
- No StartOS-side configuration, action, or migration changes; existing operator keypair, session secret, and Configure-Platform settings are preserved.`,
|
||||
},
|
||||
migrations: {
|
||||
up: async ({ effects }) => {},
|
||||
down: IMPOSSIBLE,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
export const v_1_0_2_1 = VersionInfo.of({
|
||||
version: '1.0.2:1',
|
||||
releaseNotes: {
|
||||
en_US: `- Adds PLATFORM_CALLBACK_HOST to Configure Platform (defaults to spacesops.startos) for cert-callback and payment callback URLs.
|
||||
- Sets SPACED_WALLETLOAD_NAME to default (was main).`,
|
||||
},
|
||||
migrations: {
|
||||
up: async ({ effects }) => {},
|
||||
down: IMPOSSIBLE,
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,14 @@
|
||||
import { IMPOSSIBLE, VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
export const v_1_0_3_0 = VersionInfo.of({
|
||||
version: '1.0.3:0',
|
||||
releaseNotes: {
|
||||
en_US: `Upstream upgrade to SpacesOps v1.0.3.
|
||||
- Bumps the image to spacesops/spacesops:v1.0.3 on x86_64 and aarch64.
|
||||
- No StartOS-side configuration, action, or migration changes; existing operator keypair, session secret, and Configure-Platform settings are preserved.`,
|
||||
},
|
||||
migrations: {
|
||||
up: async ({ effects }) => {},
|
||||
down: IMPOSSIBLE,
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user