fix(phoenixd): dot-free datadir + data_uid; docs: iframe rules
phoenixd: the orchestrator treats bind paths containing a dot as file mounts and never creates their source dir, so the image's default /phoenix/.phoenix target crash-looped the unit (statfs: no such file). Datadir moved to /data via PHOENIX_DATADIR; data_uid 1000:1000 matches the image's phoenix user — without it phoenixd dies on phoenix.conf 'Permission denied'. Both verified end-to-end on archi-dev-box: orch install OK, seed.dat + db on the host, authenticated /getinfo answers. alby-hub: launch flips to embedded — pairs with the gate change that neutralizes upstream frame blocking. Dev guide: iframe embedding rules (who blocks framing and why the gate may strip it; when open_in_new_tab is legitimate; test in the embedded session, never a tab). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
b7ba35477c
commit
76e6f06995
@@ -64,7 +64,10 @@ app:
|
||||
repo: https://github.com/getAlby/hub
|
||||
tier: optional
|
||||
launch:
|
||||
open_in_new_tab: true
|
||||
# Embedded: the gate neutralizes Alby Hub's X-Frame-Options: DENY on
|
||||
# proxied responses. Nodes older than the gate fix show a blocked
|
||||
# frame — flip to true only if targeting such nodes.
|
||||
open_in_new_tab: false
|
||||
features:
|
||||
- Self-custodial Lightning node (LDK) with a friendly wallet UI
|
||||
- Connect wallets and apps via Nostr Wallet Connect (NWC)
|
||||
|
||||
@@ -10,6 +10,10 @@ app:
|
||||
# --http-bind-ip 0.0.0.0, as user "phoenix"; no custom args needed.
|
||||
image: source.archipelago-foundation.org/lfg2025/phoenixd:0.9.0
|
||||
pull_policy: if-not-present
|
||||
# The image runs as user phoenix (1000:1000); the datadir bind source
|
||||
# must be chowned to that identity or phoenixd dies on
|
||||
# "Failed to open /data/phoenix.conf with Permission denied".
|
||||
data_uid: "1000:1000"
|
||||
|
||||
dependencies:
|
||||
- storage: 500Mi
|
||||
@@ -41,11 +45,18 @@ app:
|
||||
# The wallet seed (seed.dat) and phoenix.conf live here. This directory
|
||||
# must survive reinstall/migration like any other app data dir —
|
||||
# losing it means losing funds.
|
||||
# Target is /data (via PHOENIX_DATADIR below), NOT the image's default
|
||||
# /phoenix/.phoenix: the orchestrator treats any bind path containing a
|
||||
# dot as a file mount and skips creating its source directory, so a
|
||||
# hidden-dir target never gets its host dir and the unit crash-loops.
|
||||
- type: bind
|
||||
source: /var/lib/archipelago/phoenixd
|
||||
target: /phoenix/.phoenix
|
||||
target: /data
|
||||
options: [rw]
|
||||
|
||||
environment:
|
||||
- PHOENIX_DATADIR=/data
|
||||
|
||||
health_check:
|
||||
type: tcp
|
||||
endpoint: localhost:9740
|
||||
|
||||
@@ -130,7 +130,38 @@ app:
|
||||
|
||||
Additional extension keys may exist for current integrations, for example Bitcoin, Lightning, or app-specific launch/interface metadata. Treat extension keys as transitional unless they are documented as reusable platform primitives.
|
||||
|
||||
Use `metadata.launch.open_in_new_tab: true` when the app UI is known to reject iframe embedding with headers such as `X-Frame-Options` or restrictive CSP. The frontend app-session metadata is generated from this flag during release work.
|
||||
### Iframe embedding — the rules
|
||||
|
||||
The dashboard opens apps in an **embedded frame** (My Apps → app session) by
|
||||
default. Whether that works is decided by HTTP headers, not by wishes, so
|
||||
know the mechanics:
|
||||
|
||||
- Browsers refuse to render a page in an iframe when the response carries
|
||||
`X-Frame-Options: DENY`/`SAMEORIGIN` (the dashboard and the app are
|
||||
different origins — different port at minimum) or a CSP `frame-ancestors`
|
||||
directive that excludes the dashboard's origin.
|
||||
- Many upstream apps ship exactly those headers (Alby Hub sends
|
||||
`X-Frame-Options: DENY`). In a normal deployment that is correct hardening;
|
||||
behind Archipelago's app gate the clickjacking threat those headers address
|
||||
is already handled — every proxied request is authenticated by the gate
|
||||
first.
|
||||
- Therefore **the gate neutralizes frame blocking on proxied responses**: it
|
||||
removes `X-Frame-Options` and strips only the `frame-ancestors` directive
|
||||
from the app's CSP. The rest of the app's CSP (script-src, connect-src, …)
|
||||
passes through untouched — the gate never weakens the app's own content
|
||||
policy, only its framing policy. You do not need a bespoke reverse proxy,
|
||||
header patches, or app config to be embeddable.
|
||||
|
||||
Set `metadata.launch.open_in_new_tab: true` only when embedding is broken by
|
||||
things headers can't fix — the app frame-busts in JavaScript, requires being
|
||||
the top-level origin (OAuth redirect flows, WebAuthn), or sets
|
||||
`SameSite=Strict` session cookies that never accompany framed requests. Test
|
||||
in the real embedded app session, **not** a plain browser tab: tabs don't
|
||||
enforce framing headers, so a tab proves nothing about the iframe.
|
||||
|
||||
(Historical note: before the gate handled this, embeddable-but-blocking apps
|
||||
each carried a hand-built nginx strip proxy — gitea's port-3000 proxy is the
|
||||
surviving example. Do not copy that pattern for new apps.)
|
||||
|
||||
### Launch Interfaces
|
||||
|
||||
|
||||
Reference in New Issue
Block a user