Demo images / Build & push demo images (push) Failing after 2m22s
Replaces the registry host across 86 files: 309 references, covering all 40 app manifests, the orchestrator and container crates, the release and catalog scripts, both demo-images workflows, the ISO builder, demo-deploy, and the frontend marketplace data. Verified the domain actually serves the registry before rewriting anything, rather than assuming the web host implies the registry: - TLS verifies clean, HTTP/2 on the web root - an anonymous token grants a manifest fetch (HTTP 200) with no credentials - skopeo inspect --no-creds resolves an image and lists its tags That last check is the one that matters: an outside developer with no account can now pull, which was the functional blocker for publishing at all. Plain-HTTP references become HTTPS in the same pass, so OTA downloads stop crossing the network in the clear. Deliberately NOT rewritten: - The public FIPS anchor on port 8444. It is a functional network endpoint every node dials to bootstrap the mesh — closer to Bitcoin Core's hardcoded seeds than to leaked infrastructure. The domain does resolve to the same host, so it could become a hostname, but that adds a DNS dependency to the path used precisely when things are broken. Worth a deliberate decision, not a side effect of this change. - The companion APK on port 2100. The domain returns 404 for that path, so rewriting it would swap a working URL for a broken one. The Releases page does serve (200), which is where the plan already wants those binaries. - releases/app-catalog.json, releases/manifest.json and release-manifest.json. These carry `signature` and `signed_by`; editing their contents invalidates the signature and the fleet refuses artifacts that fail verification. They were rewritten in a first pass and reverted — they must be regenerated and re-signed through the signing ceremony instead, which needs the mnemonic. So the catalog still advertises the old host until that ceremony runs. Nodes resolve images through the signed catalog, not the on-disk manifests, so this commit alone does not change what a node pulls. Verified: archipelago-container 75/75; every manifest still parses with a top-level app block; no signed artifact modified. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
103 lines
4.9 KiB
YAML
103 lines
4.9 KiB
YAML
app:
|
|
id: fedimint-clientd
|
|
name: Fedimint Client
|
|
version: 0.8.0
|
|
description: Fedimint ecash client daemon (fmcd). Lets the node hold Fedimint ecash and join federations; the wallet talks to it over a local REST API.
|
|
|
|
container:
|
|
# fmcd built from source (github.com/minmoto/fmcd v0.8.0, fedimint-client
|
|
# 0.8.2 — iroh-capable). No usable upstream image exists, so we build + push
|
|
# this to the node registry. Pin the tag to match the REST shapes coded in
|
|
# core/archipelago/src/wallet/fedimint_client.rs (validated against 0.8.2).
|
|
image: source.archipelago-foundation.org/lfg2025/fmcd:0.8.1
|
|
pull_policy: if-not-present
|
|
network: archy-net
|
|
# No entrypoint override: the image's resilient `fmcd-run` launcher loops
|
|
# fmcd and retries on join failure (fmcd needs >=1 federation to boot), so an
|
|
# unreachable default never crash-loops. All config comes from FMCD_* env
|
|
# below. Nodes can join more federations via wallet.fedimint-join.
|
|
# Auto-generated on first install (random hex, 0600, rootless-owned) so the
|
|
# app needs no host provisioning. The wallet bridge reads the same file.
|
|
generated_secrets:
|
|
- name: fmcd-password
|
|
kind: hex16
|
|
secret_env:
|
|
- key: FMCD_PASSWORD
|
|
secret_file: fmcd-password
|
|
data_uid: "1000:1000"
|
|
|
|
# NOTE: this is a CLIENT, not the guardian — it does not require the local
|
|
# `fedimint` app. It joins external federations (default below), so it can be
|
|
# bundled standalone on every node.
|
|
dependencies:
|
|
- storage: 2Gi
|
|
|
|
resources:
|
|
# fmcd's embedded iroh networking can hot-loop on relay/hole-punch retries
|
|
# on NAT'd nodes that reach the federation neither directly nor via iroh's
|
|
# public relays, pegging its whole allotment. Cap it low so a stuck instance
|
|
# can't starve the node (steady-state is <3% of a core; joins are brief);
|
|
# the fmcd-run watchdog additionally restarts a sustained-hot process.
|
|
cpu_limit: 1
|
|
memory_limit: 1Gi
|
|
disk_limit: 2Gi
|
|
|
|
security:
|
|
# fmcd's `fmcd-run` launcher chowns its /data (existing federation DB) on
|
|
# every start. With the default `cap_drop: ALL` and no caps added back, that
|
|
# chown fails and fmcd dies "Operation not permitted (os error 1)" — but ONLY
|
|
# once /data holds a joined federation (a fresh/empty dir needs no chown, so
|
|
# it appeared to work). Restore the standard container capability set so the
|
|
# startup chown succeeds (#7). Verified by bisection on .116: these caps make
|
|
# fmcd boot + serve /v2/*; DAC_OVERRIDE or SETUID/SETGID alone do NOT.
|
|
capabilities: ["CHOWN", "DAC_OVERRIDE", "FOWNER", "SETUID", "SETGID"]
|
|
readonly_root: true
|
|
# NOT isolated: fmcd needs outbound UDP + Mainline DHT (port 6881) + iroh
|
|
# relays to reach iroh-transport federations. `bridge` gives NAT'd outbound
|
|
# (UDP/DHT/iroh hole-punch all work) plus the published 8178→8080 port the
|
|
# wallet bridge targets. ("open" is not a valid policy — it made the loader
|
|
# skip this whole manifest, so fmcd never ran and federations never joined.)
|
|
# Lock down once the default federation's reachability model is finalized.
|
|
network_policy: bridge
|
|
|
|
ports:
|
|
# fmcd REST bound to 8080 in-container; 8080 collides with LND REST on the
|
|
# host, so map to 8178. The Rust bridge targets http://127.0.0.1:8178.
|
|
- host: 8178
|
|
container: 8080
|
|
protocol: tcp
|
|
bind: 127.0.0.1
|
|
auth: local
|
|
|
|
volumes:
|
|
# Same dir the first-boot bundled path uses + where the wallet bridge reads
|
|
# the password (/var/lib/archipelago/fmcd/password) — keep install paths aligned.
|
|
- type: bind
|
|
source: /var/lib/archipelago/fmcd
|
|
target: /data
|
|
options: [rw]
|
|
|
|
environment:
|
|
- FMCD_ADDR=0.0.0.0:8080
|
|
- FMCD_MODE=rest
|
|
- FMCD_DATA_DIR=/data
|
|
# Default federation joined out-of-the-box (guardian on .116, iroh
|
|
# transport; validated to join with fmcd 0.8.2). iroh does NAT traversal so
|
|
# it's reachable fleet-wide. Keep in sync with DEFAULT_FEDERATION_INVITE in
|
|
# core/.../wallet/fedimint_client.rs. CAVEAT: iroh is experimental — validate
|
|
# join reliability from a real second node before relying on auto-bundle.
|
|
- FMCD_INVITE_CODE=fed11qgqyj3mfwfhksw309uuxywtxxfjrjc35xuexverpxdsnxcnrxucxvenzveskgc3kvvun2c34xp3k2ep38yunzdpexcekxe3hvd3rvvmx8pnrvdenx5mnzvtzqqqjqt0t6pc3s5z0ynqjw9s4njf6svwgu59kweawc0vvrddcjeemw6yyn4pcdp
|
|
|
|
# fmcd serves only authenticated /v2/* routes — there is no unauthenticated
|
|
# /health endpoint, so an http probe to /health 404s forever and pins the
|
|
# container in "(starting)". fmcd's own image also ships neither curl nor wget.
|
|
# Use a TCP probe: the Quadlet renderer skips it (no HealthCmd emitted) and the
|
|
# host-side lifecycle layer verifies reachability, so the container reports
|
|
# "running" instead of a perpetual false-negative "(starting)".
|
|
health_check:
|
|
type: tcp
|
|
endpoint: localhost:8080
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|