archy/apps/bitcoin-ui/manifest.yml

57 lines
1.8 KiB
YAML
Raw Normal View History

feat(container): bitcoin-ui pre-start hook renders nginx.conf from embedded template Replaces the first-boot-containers.sh sed/envsubst approach with a Rust-native render step bound into the ContainerOrchestrator lifecycle. - New container::bitcoin_ui module: embeds the nginx.conf template via include_str!, reads the plaintext RPC password from /var/lib/archipelago/secrets/bitcoin-rpc-password, substitutes {{BITCOIN_RPC_AUTH}} with base64(archipelago:<password>), and atomic- writes (tmp + rename) to /var/lib/archipelago/bitcoin-ui/nginx.conf. Idempotent: byte-compares before writing so unchanged input is a no-op (no inode churn, no restart cascade). - ProdContainerOrchestrator gains run_pre_start_hooks(app_id) returning HookOutcome::{Rewritten, Unchanged}. Fires in install_fresh before create_container, and in ensure_running: on Running + Rewritten triggers a restart; on Stopped re-renders then starts. - bitcoin-ui Dockerfile no longer COPYs a default.conf; the file now arrives via runtime bind-mount of the rendered config. If the bind- mount is ever missing, nginx starts with no site configured and returns 404 everywhere — safe failure vs. serving upstream RPC with a stale Authorization header. - apps/{bitcoin,electrs,lnd}-ui/manifest.yml land as first-class manifests. bitcoin-ui declares the bind-mount target and a dependency on bitcoin-core; electrs-ui and lnd-ui declare their own deps and health checks. - 8 new unit tests on the render fn (idempotency, rotation, trimming, missing/empty secret, template invariants) plus an integration test asserting install(bitcoin-ui) actually lands a substituted nginx.conf on disk via the hook. 39/39 container:: tests pass (test_parse_image_versions pre-existing failure unchanged, out of scope).
2026-04-23 02:19:52 -04:00
app:
id: bitcoin-ui
name: Bitcoin UI
version: 1.0.0
description: |
Archipelago-native HTTP proxy + static site for interacting with the
Bitcoin Core / Bitcoin Knots JSON-RPC. Runs nginx inside a container
and reverse-proxies /bitcoin-rpc/ to 127.0.0.1:8332 on the host. The
upstream Authorization header is substituted from
/var/lib/archipelago/secrets/bitcoin-rpc-password by the prod
orchestrator's pre-start hook, rendered into an nginx.conf that is
bind-mounted read-only at container start.
container:
build:
context: /opt/archipelago/docker/bitcoin-ui
dockerfile: Dockerfile
tag: localhost/bitcoin-ui:local
dependencies:
- app_id: bitcoin-core
resources:
memory_limit: 128Mi
security:
readonly_root: false
network_policy: host
# Host networking: nginx listens on 8334 directly on the host IP, and
# proxies to 127.0.0.1:8332 which is where the bitcoin backend binds
# its RPC. `ports:` is intentionally empty because host networking
# bypasses port mapping.
ports: []
volumes:
# Bind-mount the rendered nginx.conf read-only. The prod orchestrator
# renders /var/lib/archipelago/bitcoin-ui/nginx.conf on every install
# and every reconcile pass, substituting the base64 RPC auth from
# the plaintext password secret. If the rendered bytes change (the
# password rotated, or the template was updated by OTA), the
# reconciler restarts this container so nginx re-reads the config.
- type: bind
source: /var/lib/archipelago/bitcoin-ui/nginx.conf
target: /etc/nginx/conf.d/default.conf
options: [ro]
environment: []
health_check:
type: http
endpoint: http://127.0.0.1:8334
path: /
interval: 30s
timeout: 5s
retries: 3