fix(fedimint): gateway/guardian follow the running bitcoin container via {{BITCOIN_HOST}}
The gateway crash-looped dialing bitcoind at host.archipelago:8332 (the
host gateway IP, where bitcoind does not listen). Root-cause fix, three
parts:
- fedimint-gateway manifest: --bitcoind-url now comes from
$FM_BITCOIND_URL, filled by a {{BITCOIN_HOST}} derived-env — works on
Knots, Core, or any future Bitcoin distro.
- fedimint manifest: same derived-env replaces the hardcoded
FM_BITCOIND_URL=http://bitcoin-knots:8332 environment entry.
- orchestrator: removed the hardcoded FM_BITCOIND_URL=bitcoin-knots
override that clobbered the derived-env, and bitcoin_host() now
accepts any running bitcoin*/bitcoin container (excluding -ui and
archy-* sidecars), preferring the known names in order.
Catalog regenerated + signed (nodes install from the signed catalog, so
the manifest fixes only reach them via this regen).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
f339358109
commit
fb72e3e159
@@ -9,13 +9,22 @@ app:
|
|||||||
pull_policy: if-not-present
|
pull_policy: if-not-present
|
||||||
network: archy-net
|
network: archy-net
|
||||||
entrypoint: ["sh", "-lc"]
|
entrypoint: ["sh", "-lc"]
|
||||||
|
# The bitcoind host comes from $FM_BITCOIND_URL, filled by the
|
||||||
|
# {{BITCOIN_HOST}} derived-env below — it resolves to whichever bitcoin
|
||||||
|
# container is actually running (Knots, Core, or any future distro archy
|
||||||
|
# ships), so the gateway is never pinned to one node's container name.
|
||||||
|
# (Was hardcoded http://host.archipelago:8332 — the host gateway IP where
|
||||||
|
# bitcoind does not listen — which crash-looped the gateway, 2026-07-22.)
|
||||||
custom_args:
|
custom_args:
|
||||||
- >-
|
- >-
|
||||||
if [ -f /lnd/tls.cert ] && [ -f /lnd/data/chain/bitcoin/mainnet/admin.macaroon ]; then
|
if [ -f /lnd/tls.cert ] && [ -f /lnd/data/chain/bitcoin/mainnet/admin.macaroon ]; then
|
||||||
exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash "$FEDI_HASH" --network bitcoin --bitcoind-url http://host.archipelago:8332 --bitcoind-username "$FM_BITCOIND_USERNAME" --bitcoind-password "$FM_BITCOIND_PASSWORD" lnd --lnd-rpc-host lnd:10009 --lnd-tls-cert /lnd/tls.cert --lnd-macaroon /lnd/data/chain/bitcoin/mainnet/admin.macaroon;
|
exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash "$FEDI_HASH" --network bitcoin --bitcoind-url "$FM_BITCOIND_URL" --bitcoind-username "$FM_BITCOIND_USERNAME" --bitcoind-password "$FM_BITCOIND_PASSWORD" lnd --lnd-rpc-host lnd:10009 --lnd-tls-cert /lnd/tls.cert --lnd-macaroon /lnd/data/chain/bitcoin/mainnet/admin.macaroon;
|
||||||
else
|
else
|
||||||
exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash "$FEDI_HASH" --network bitcoin --bitcoind-url http://host.archipelago:8332 --bitcoind-username "$FM_BITCOIND_USERNAME" --bitcoind-password "$FM_BITCOIND_PASSWORD" ldk --ldk-lightning-port 9737 --ldk-alias archipelago-gateway;
|
exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash "$FEDI_HASH" --network bitcoin --bitcoind-url "$FM_BITCOIND_URL" --bitcoind-username "$FM_BITCOIND_USERNAME" --bitcoind-password "$FM_BITCOIND_PASSWORD" ldk --ldk-lightning-port 9737 --ldk-alias archipelago-gateway;
|
||||||
fi
|
fi
|
||||||
|
derived_env:
|
||||||
|
- key: FM_BITCOIND_URL
|
||||||
|
template: "http://{{BITCOIN_HOST}}:8332"
|
||||||
# The gateway's admin API is gated by a bcrypt password hash. Generate it on
|
# The gateway's admin API is gated by a bcrypt password hash. Generate it on
|
||||||
# first install (random password + its bcrypt hash, both 0600 rootless-owned)
|
# first install (random password + its bcrypt hash, both 0600 rootless-owned)
|
||||||
# so the app installs from its manifest alone — `fedimint-gateway-hash` holds
|
# so the app installs from its manifest alone — `fedimint-gateway-hash` holds
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ app:
|
|||||||
template: fedimint://{{HOST_MDNS}}:8173
|
template: fedimint://{{HOST_MDNS}}:8173
|
||||||
- key: FM_API_URL
|
- key: FM_API_URL
|
||||||
template: ws://{{HOST_MDNS}}:8174
|
template: ws://{{HOST_MDNS}}:8174
|
||||||
|
# Resolves to whichever bitcoin container is running (Knots/Core/future
|
||||||
|
# distro) instead of a hardcoded name — the guardian works on any node
|
||||||
|
# regardless of which Bitcoin software it runs.
|
||||||
|
- key: FM_BITCOIND_URL
|
||||||
|
template: "http://{{BITCOIN_HOST}}:8332"
|
||||||
secret_env:
|
secret_env:
|
||||||
- key: FM_BITCOIND_PASSWORD
|
- key: FM_BITCOIND_PASSWORD
|
||||||
secret_file: bitcoin-rpc-password
|
secret_file: bitcoin-rpc-password
|
||||||
@@ -62,7 +67,8 @@ app:
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
- FM_DATA_DIR=/data
|
- FM_DATA_DIR=/data
|
||||||
- FM_BITCOIND_URL=http://bitcoin-knots:8332
|
# FM_BITCOIND_URL comes from derived_env ({{BITCOIN_HOST}}) above, not a
|
||||||
|
# hardcoded name — do not re-add it here.
|
||||||
- FM_BITCOIND_USERNAME=archipelago
|
- FM_BITCOIND_USERNAME=archipelago
|
||||||
- FM_BITCOIN_NETWORK=bitcoin
|
- FM_BITCOIN_NETWORK=bitcoin
|
||||||
- FM_BIND_P2P=0.0.0.0:8173
|
- FM_BIND_P2P=0.0.0.0:8173
|
||||||
|
|||||||
@@ -3094,8 +3094,9 @@ impl ProdContainerOrchestrator {
|
|||||||
.unwrap_or_else(|| "bitcoin-knots".to_string());
|
.unwrap_or_else(|| "bitcoin-knots".to_string());
|
||||||
}
|
}
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
// Mirrors api::rpc::package::dependencies (the legacy install path);
|
// The known Bitcoin node containers, preferred in order. Any archy
|
||||||
// both Bitcoin node variants are reachable on archy-net by name.
|
// Bitcoin distribution runs as a container named `bitcoin-<distro>`
|
||||||
|
// (or bare `bitcoin`), all reachable on archy-net by name.
|
||||||
const BITCOIN_NAMES: &[&str] = &["bitcoin-knots", "bitcoin-core", "bitcoin"];
|
const BITCOIN_NAMES: &[&str] = &["bitcoin-knots", "bitcoin-core", "bitcoin"];
|
||||||
let names = tokio::process::Command::new("podman")
|
let names = tokio::process::Command::new("podman")
|
||||||
.args(["ps", "--format", "{{.Names}}"])
|
.args(["ps", "--format", "{{.Names}}"])
|
||||||
@@ -3105,12 +3106,23 @@ impl ProdContainerOrchestrator {
|
|||||||
.filter(|o| o.status.success())
|
.filter(|o| o.status.success())
|
||||||
.map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
|
.map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
names
|
let running: Vec<&str> = names.lines().map(|l| l.trim()).collect();
|
||||||
.lines()
|
// Prefer a known name in priority order…
|
||||||
.map(|l| l.trim())
|
if let Some(hit) = BITCOIN_NAMES.iter().find(|n| running.contains(n)) {
|
||||||
.find(|name| BITCOIN_NAMES.contains(name))
|
return hit.to_string();
|
||||||
.map(|name| name.to_string())
|
}
|
||||||
.unwrap_or_else(|| "bitcoin-knots".to_string())
|
// …else accept ANY running `bitcoin-*` / `bitcoin` container, so a
|
||||||
|
// future Bitcoin distribution archy ships works without editing this
|
||||||
|
// list (user req 2026-07-22). Excludes companions/sidecars like
|
||||||
|
// `bitcoin-ui` and `archy-*`.
|
||||||
|
if let Some(other) = running.iter().find(|n| {
|
||||||
|
(**n == "bitcoin" || n.starts_with("bitcoin-"))
|
||||||
|
&& !n.ends_with("-ui")
|
||||||
|
&& !n.starts_with("archy-")
|
||||||
|
}) {
|
||||||
|
return other.to_string();
|
||||||
|
}
|
||||||
|
"bitcoin-knots".to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -3247,10 +3259,10 @@ impl ProdContainerOrchestrator {
|
|||||||
let mut env = manifest.app.environment.clone();
|
let mut env = manifest.app.environment.clone();
|
||||||
env.extend(manifest.app.container.resolve_derived_env(&facts));
|
env.extend(manifest.app.container.resolve_derived_env(&facts));
|
||||||
|
|
||||||
if manifest.app.id == "fedimint" || manifest.app.id == "fedimintd" {
|
// FM_BITCOIND_URL now comes from the manifest's {{BITCOIN_HOST}}
|
||||||
env.retain(|entry| !entry.starts_with("FM_BITCOIND_URL="));
|
// derived_env (works on Knots/Core/any distro). The old hardcoded
|
||||||
env.push("FM_BITCOIND_URL=http://bitcoin-knots:8332".to_string());
|
// `bitcoin-knots` override was removed 2026-07-22 — it defeated the
|
||||||
}
|
// derived-env and broke Core nodes.
|
||||||
|
|
||||||
let provider = FileSecretsProvider {
|
let provider = FileSecretsProvider {
|
||||||
root: self.secrets_dir.clone(),
|
root: self.secrets_dir.clone(),
|
||||||
|
|||||||
@@ -1256,6 +1256,10 @@
|
|||||||
{
|
{
|
||||||
"key": "FM_API_URL",
|
"key": "FM_API_URL",
|
||||||
"template": "ws://{{HOST_MDNS}}:8174"
|
"template": "ws://{{HOST_MDNS}}:8174"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "FM_BITCOIND_URL",
|
||||||
|
"template": "http://{{BITCOIN_HOST}}:8332"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"entrypoint": [
|
"entrypoint": [
|
||||||
@@ -1284,7 +1288,6 @@
|
|||||||
"description": "Federated Bitcoin minting service with built-in Guardian UI. Privacy-preserving Bitcoin custody.",
|
"description": "Federated Bitcoin minting service with built-in Guardian UI. Privacy-preserving Bitcoin custody.",
|
||||||
"environment": [
|
"environment": [
|
||||||
"FM_DATA_DIR=/data",
|
"FM_DATA_DIR=/data",
|
||||||
"FM_BITCOIND_URL=http://bitcoin-knots:8332",
|
|
||||||
"FM_BITCOIND_USERNAME=archipelago",
|
"FM_BITCOIND_USERNAME=archipelago",
|
||||||
"FM_BITCOIN_NETWORK=bitcoin",
|
"FM_BITCOIN_NETWORK=bitcoin",
|
||||||
"FM_BIND_P2P=0.0.0.0:8173",
|
"FM_BIND_P2P=0.0.0.0:8173",
|
||||||
@@ -1443,9 +1446,15 @@
|
|||||||
},
|
},
|
||||||
"container": {
|
"container": {
|
||||||
"custom_args": [
|
"custom_args": [
|
||||||
"if [ -f /lnd/tls.cert ] && [ -f /lnd/data/chain/bitcoin/mainnet/admin.macaroon ]; then\n exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash \"$FEDI_HASH\" --network bitcoin --bitcoind-url http://host.archipelago:8332 --bitcoind-username \"$FM_BITCOIND_USERNAME\" --bitcoind-password \"$FM_BITCOIND_PASSWORD\" lnd --lnd-rpc-host lnd:10009 --lnd-tls-cert /lnd/tls.cert --lnd-macaroon /lnd/data/chain/bitcoin/mainnet/admin.macaroon;\nelse\n exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash \"$FEDI_HASH\" --network bitcoin --bitcoind-url http://host.archipelago:8332 --bitcoind-username \"$FM_BITCOIND_USERNAME\" --bitcoind-password \"$FM_BITCOIND_PASSWORD\" ldk --ldk-lightning-port 9737 --ldk-alias archipelago-gateway;\nfi"
|
"if [ -f /lnd/tls.cert ] && [ -f /lnd/data/chain/bitcoin/mainnet/admin.macaroon ]; then\n exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash \"$FEDI_HASH\" --network bitcoin --bitcoind-url \"$FM_BITCOIND_URL\" --bitcoind-username \"$FM_BITCOIND_USERNAME\" --bitcoind-password \"$FM_BITCOIND_PASSWORD\" lnd --lnd-rpc-host lnd:10009 --lnd-tls-cert /lnd/tls.cert --lnd-macaroon /lnd/data/chain/bitcoin/mainnet/admin.macaroon;\nelse\n exec gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash \"$FEDI_HASH\" --network bitcoin --bitcoind-url \"$FM_BITCOIND_URL\" --bitcoind-username \"$FM_BITCOIND_USERNAME\" --bitcoind-password \"$FM_BITCOIND_PASSWORD\" ldk --ldk-lightning-port 9737 --ldk-alias archipelago-gateway;\nfi"
|
||||||
],
|
],
|
||||||
"data_uid": "1000:1000",
|
"data_uid": "1000:1000",
|
||||||
|
"derived_env": [
|
||||||
|
{
|
||||||
|
"key": "FM_BITCOIND_URL",
|
||||||
|
"template": "http://{{BITCOIN_HOST}}:8332"
|
||||||
|
}
|
||||||
|
],
|
||||||
"entrypoint": [
|
"entrypoint": [
|
||||||
"sh",
|
"sh",
|
||||||
"-lc"
|
"-lc"
|
||||||
@@ -4157,7 +4166,9 @@
|
|||||||
"--model",
|
"--model",
|
||||||
"base-int8",
|
"base-int8",
|
||||||
"--language",
|
"--language",
|
||||||
"en"
|
"en",
|
||||||
|
"--beam-size",
|
||||||
|
"1"
|
||||||
],
|
],
|
||||||
"image": "docker.io/rhasspy/wyoming-whisper:3.4.1",
|
"image": "docker.io/rhasspy/wyoming-whisper:3.4.1",
|
||||||
"network": "archy-net",
|
"network": "archy-net",
|
||||||
@@ -4213,7 +4224,7 @@
|
|||||||
"no_new_privileges": true,
|
"no_new_privileges": true,
|
||||||
"readonly_root": false
|
"readonly_root": false
|
||||||
},
|
},
|
||||||
"version": "3.4.1",
|
"version": "3.4.2",
|
||||||
"volumes": [
|
"volumes": [
|
||||||
{
|
{
|
||||||
"options": [
|
"options": [
|
||||||
@@ -4226,7 +4237,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"version": "3.4.1"
|
"version": "3.4.2"
|
||||||
},
|
},
|
||||||
"portainer": {
|
"portainer": {
|
||||||
"image": "146.59.87.168:3000/lfg2025/portainer:2.19.4",
|
"image": "146.59.87.168:3000/lfg2025/portainer:2.19.4",
|
||||||
@@ -4729,7 +4740,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"schema": 1,
|
"schema": 1,
|
||||||
"signature": "5ca0f41589ba2a905e68d79388ea819ef983689f5c88a718723280d81782d534b8a1c9b0452f062b59dae3261224b98f2f136be564176a20729c55a748025100",
|
"signature": "4054b2a8659b75a3810ed153798c0e8a08db49ce6237b8ae985e87ace8a35163c24a0190074abd2a8296309ebe9dd583f153642d46d4d7f0a6a4db255743380b",
|
||||||
"signed_by": "did:key:z6MkkidEnEpo6qHMCNSZoNKWtvQvxq3whnaME9wGgEFhq7ur",
|
"signed_by": "did:key:z6MkkidEnEpo6qHMCNSZoNKWtvQvxq3whnaME9wGgEFhq7ur",
|
||||||
"updated": "2026-07-22"
|
"updated": "2026-07-23"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user