feat(registry): move image and OTA references to the public domain
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>
This commit is contained in:
archipelago
2026-08-07 11:31:20 -04:00
co-authored by Claude Opus 5
parent b2c7592840
commit 8e814ca06a
86 changed files with 210 additions and 210 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ name: Demo images
# code (see demo-deploy/ and docs/demo-deployment-design.md). # code (see demo-deploy/ and docs/demo-deployment-design.md).
# #
# Required repo configuration: # Required repo configuration:
# vars.DEMO_REGISTRY e.g. 146.59.87.168:3000/lfg2025 # vars.DEMO_REGISTRY e.g. source.archipelago-foundation.org/lfg2025
# vars.DEMO_REGISTRY_HOST registry host for docker login (no org suffix) # vars.DEMO_REGISTRY_HOST registry host for docker login (no org suffix)
# secrets.DEMO_REGISTRY_USER # secrets.DEMO_REGISTRY_USER
# secrets.DEMO_REGISTRY_TOKEN # secrets.DEMO_REGISTRY_TOKEN
+1 -1
View File
@@ -5,7 +5,7 @@ name: Demo images
# code (see demo-deploy/ and docs/demo-deployment-design.md). # code (see demo-deploy/ and docs/demo-deployment-design.md).
# #
# Required repo configuration: # Required repo configuration:
# vars.DEMO_REGISTRY e.g. 146.59.87.168:3000/lfg2025 # vars.DEMO_REGISTRY e.g. source.archipelago-foundation.org/lfg2025
# vars.DEMO_REGISTRY_HOST registry host for docker login (no org suffix) # vars.DEMO_REGISTRY_HOST registry host for docker login (no org suffix)
# secrets.DEMO_REGISTRY_USER # secrets.DEMO_REGISTRY_USER
# secrets.DEMO_REGISTRY_TOKEN # secrets.DEMO_REGISTRY_TOKEN
+1 -1
View File
@@ -1,3 +1,3 @@
[submodule "indeedhub"] [submodule "indeedhub"]
path = indeedhub path = indeedhub
url = http://146.59.87.168:3000/lfg2025/indeehub.git url = https://source.archipelago-foundation.org/lfg2025/indeehub.git
+1 -1
View File
@@ -92,7 +92,7 @@ built and signed:
```bash ```bash
SERVED=neode-ui/public/packages/archipelago-companion.apk SERVED=neode-ui/public/packages/archipelago-companion.apk
GITEA_URL=http://146.59.87.168:3000/lfg2025/archy/raw/branch/main/$SERVED GITEA_URL=https://source.archipelago-foundation.org/lfg2025/archy/raw/branch/main/$SERVED
QR_URL=http://146.59.87.168:2100/packages/archipelago-companion.apk QR_URL=http://146.59.87.168:2100/packages/archipelago-companion.apk
curl -sS -o /tmp/live-gitea.apk "$GITEA_URL" curl -sS -o /tmp/live-gitea.apk "$GITEA_URL"
curl -sS -o /tmp/live-qr.apk "$QR_URL" curl -sS -o /tmp/live-qr.apk "$QR_URL"
+1 -1
View File
@@ -21,7 +21,7 @@ Add an entry to `catalog.json`:
"icon": "/assets/img/app-icons/my-app.svg", "icon": "/assets/img/app-icons/my-app.svg",
"author": "Author", "author": "Author",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/my-app:1.0.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/my-app:1.0.0",
"repoUrl": "https://github.com/...", "repoUrl": "https://github.com/...",
"containerConfig": { "containerConfig": {
"ports": ["8080:8080"], "ports": ["8080:8080"],
+23 -23
View File
@@ -1,7 +1,7 @@
{ {
"version": 2, "version": 2,
"updated": "2026-04-22T00:00:00Z", "updated": "2026-04-22T00:00:00Z",
"registry": "146.59.87.168:3000/lfg2025", "registry": "source.archipelago-foundation.org/lfg2025",
"featured": { "featured": {
"id": "indeedhub", "id": "indeedhub",
"banner": "/assets/img/featured/indeedhub-banner.jpg", "banner": "/assets/img/featured/indeedhub-banner.jpg",
@@ -19,7 +19,7 @@
"author": "Bitcoin Knots", "author": "Bitcoin Knots",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/bitcoin-knots:latest", "dockerImage": "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest",
"repoUrl": "https://github.com/bitcoinknots/bitcoin" "repoUrl": "https://github.com/bitcoinknots/bitcoin"
}, },
{ {
@@ -31,7 +31,7 @@
"author": "Bitcoin Core contributors", "author": "Bitcoin Core contributors",
"category": "money", "category": "money",
"tier": "optional", "tier": "optional",
"dockerImage": "146.59.87.168:3000/lfg2025/bitcoin:28.4", "dockerImage": "source.archipelago-foundation.org/lfg2025/bitcoin:28.4",
"repoUrl": "https://github.com/bitcoin/bitcoin" "repoUrl": "https://github.com/bitcoin/bitcoin"
}, },
{ {
@@ -43,7 +43,7 @@
"author": "Lightning Labs", "author": "Lightning Labs",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta", "dockerImage": "source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta",
"repoUrl": "https://github.com/lightningnetwork/lnd", "repoUrl": "https://github.com/lightningnetwork/lnd",
"requires": [ "requires": [
"bitcoin-knots" "bitcoin-knots"
@@ -73,7 +73,7 @@
"author": "Mempool", "author": "Mempool",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/mempool-frontend:v3.0.1", "dockerImage": "source.archipelago-foundation.org/lfg2025/mempool-frontend:v3.0.1",
"repoUrl": "https://github.com/mempool/mempool", "repoUrl": "https://github.com/mempool/mempool",
"requires": [ "requires": [
"bitcoin-knots", "bitcoin-knots",
@@ -89,7 +89,7 @@
"author": "Luke Childs", "author": "Luke Childs",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/electrumx:v1.18.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/electrumx:v1.18.0",
"repoUrl": "https://github.com/spesmilo/electrumx", "repoUrl": "https://github.com/spesmilo/electrumx",
"requires": [ "requires": [
"bitcoin-knots" "bitcoin-knots"
@@ -103,7 +103,7 @@
"icon": "/assets/img/app-icons/indeedhub.png", "icon": "/assets/img/app-icons/indeedhub.png",
"author": "IndeeHub", "author": "IndeeHub",
"category": "community", "category": "community",
"dockerImage": "146.59.87.168:3000/lfg2025/indeedhub:1.0.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/indeedhub:1.0.0",
"repoUrl": "https://github.com/indeedhub/indeedhub" "repoUrl": "https://github.com/indeedhub/indeedhub"
}, },
{ {
@@ -114,7 +114,7 @@
"icon": "/assets/img/app-icons/botfights.svg", "icon": "/assets/img/app-icons/botfights.svg",
"author": "BotFights", "author": "BotFights",
"category": "community", "category": "community",
"dockerImage": "146.59.87.168:3000/lfg2025/botfights:1.2.11", "dockerImage": "source.archipelago-foundation.org/lfg2025/botfights:1.2.11",
"repoUrl": "https://botfights.net", "repoUrl": "https://botfights.net",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -172,7 +172,7 @@
"author": "File Browser", "author": "File Browser",
"category": "data", "category": "data",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/filebrowser:v2.27.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/filebrowser:v2.27.0",
"repoUrl": "https://github.com/filebrowser/filebrowser", "repoUrl": "https://github.com/filebrowser/filebrowser",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -223,7 +223,7 @@
"author": "Vaultwarden", "author": "Vaultwarden",
"category": "data", "category": "data",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/vaultwarden:1.30.0-alpine", "dockerImage": "source.archipelago-foundation.org/lfg2025/vaultwarden:1.30.0-alpine",
"repoUrl": "https://github.com/dani-garcia/vaultwarden", "repoUrl": "https://github.com/dani-garcia/vaultwarden",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -243,7 +243,7 @@
"author": "SearXNG", "author": "SearXNG",
"category": "data", "category": "data",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/searxng:latest", "dockerImage": "source.archipelago-foundation.org/lfg2025/searxng:latest",
"repoUrl": "https://github.com/searxng/searxng", "repoUrl": "https://github.com/searxng/searxng",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -262,7 +262,7 @@
"icon": "/assets/img/app-icons/fedimint.png", "icon": "/assets/img/app-icons/fedimint.png",
"author": "Fedimint", "author": "Fedimint",
"category": "money", "category": "money",
"dockerImage": "146.59.87.168:3000/lfg2025/fedimintd:v0.10.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/fedimintd:v0.10.0",
"repoUrl": "https://github.com/fedimint/fedimint" "repoUrl": "https://github.com/fedimint/fedimint"
}, },
{ {
@@ -274,7 +274,7 @@
"author": "Fedimint", "author": "Fedimint",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/fmcd:0.8.1", "dockerImage": "source.archipelago-foundation.org/lfg2025/fmcd:0.8.1",
"repoUrl": "https://github.com/minmoto/fmcd" "repoUrl": "https://github.com/minmoto/fmcd"
}, },
{ {
@@ -285,7 +285,7 @@
"icon": "/assets/img/app-icons/fedimint.png", "icon": "/assets/img/app-icons/fedimint.png",
"author": "Fedimint", "author": "Fedimint",
"category": "money", "category": "money",
"dockerImage": "146.59.87.168:3000/lfg2025/gatewayd:v0.10.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/gatewayd:v0.10.0",
"repoUrl": "https://github.com/fedimint/fedimint", "repoUrl": "https://github.com/fedimint/fedimint",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -306,7 +306,7 @@
"icon": "/assets/img/app-icons/bark.png", "icon": "/assets/img/app-icons/bark.png",
"author": "Second", "author": "Second",
"category": "money", "category": "money",
"dockerImage": "146.59.87.168:3000/lfg2025/barkd:0.3.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/barkd:0.3.0",
"repoUrl": "https://gitlab.com/ark-bitcoin/bark", "repoUrl": "https://gitlab.com/ark-bitcoin/bark",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -325,7 +325,7 @@
"icon": "/assets/img/app-icons/jellyfin.webp", "icon": "/assets/img/app-icons/jellyfin.webp",
"author": "Jellyfin", "author": "Jellyfin",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/jellyfin:10.8.13", "dockerImage": "source.archipelago-foundation.org/lfg2025/jellyfin:10.8.13",
"repoUrl": "https://github.com/jellyfin/jellyfin", "repoUrl": "https://github.com/jellyfin/jellyfin",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -345,7 +345,7 @@
"icon": "/assets/img/app-icons/immich.png", "icon": "/assets/img/app-icons/immich.png",
"author": "Immich", "author": "Immich",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/immich-server:release", "dockerImage": "source.archipelago-foundation.org/lfg2025/immich-server:release",
"repoUrl": "https://github.com/immich-app/immich" "repoUrl": "https://github.com/immich-app/immich"
}, },
{ {
@@ -356,7 +356,7 @@
"icon": "/assets/img/app-icons/homeassistant.png", "icon": "/assets/img/app-icons/homeassistant.png",
"author": "Home Assistant", "author": "Home Assistant",
"category": "home", "category": "home",
"dockerImage": "146.59.87.168:3000/lfg2025/home-assistant:2026.7.3", "dockerImage": "source.archipelago-foundation.org/lfg2025/home-assistant:2026.7.3",
"repoUrl": "https://github.com/home-assistant/core", "repoUrl": "https://github.com/home-assistant/core",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -414,7 +414,7 @@
"author": "Tailscale", "author": "Tailscale",
"category": "networking", "category": "networking",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/tailscale:stable", "dockerImage": "source.archipelago-foundation.org/lfg2025/tailscale:stable",
"repoUrl": "https://github.com/tailscale/tailscale", "repoUrl": "https://github.com/tailscale/tailscale",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -442,7 +442,7 @@
"author": "Portainer", "author": "Portainer",
"category": "development", "category": "development",
"tier": "optional", "tier": "optional",
"dockerImage": "146.59.87.168:3000/lfg2025/portainer:2.39.1", "dockerImage": "source.archipelago-foundation.org/lfg2025/portainer:2.39.1",
"repoUrl": "https://github.com/portainer/portainer", "repoUrl": "https://github.com/portainer/portainer",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -487,7 +487,7 @@
"author": "Uptime Kuma", "author": "Uptime Kuma",
"category": "data", "category": "data",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/uptime-kuma:1", "dockerImage": "source.archipelago-foundation.org/lfg2025/uptime-kuma:1",
"repoUrl": "https://github.com/louislam/uptime-kuma", "repoUrl": "https://github.com/louislam/uptime-kuma",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -514,7 +514,7 @@
"icon": "/assets/img/app-icons/photoprism.svg", "icon": "/assets/img/app-icons/photoprism.svg",
"author": "PhotoPrism", "author": "PhotoPrism",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/photoprism:240915", "dockerImage": "source.archipelago-foundation.org/lfg2025/photoprism:240915",
"repoUrl": "https://github.com/photoprism/photoprism", "repoUrl": "https://github.com/photoprism/photoprism",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -537,7 +537,7 @@
"icon": "/assets/img/app-icons/nextcloud.webp", "icon": "/assets/img/app-icons/nextcloud.webp",
"author": "Nextcloud", "author": "Nextcloud",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/nextcloud:29", "dockerImage": "source.archipelago-foundation.org/lfg2025/nextcloud:29",
"repoUrl": "https://github.com/nextcloud/server", "repoUrl": "https://github.com/nextcloud/server",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Postgres backend for BTCPay and NBXplorer. description: Postgres backend for BTCPay and NBXplorer.
container: container:
image: 146.59.87.168:3000/lfg2025/postgres:15.17 image: source.archipelago-foundation.org/lfg2025/postgres:15.17
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
data_uid: "100998:100998" data_uid: "100998:100998"
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: MariaDB backend for the mempool explorer stack. description: MariaDB backend for the mempool explorer stack.
container: container:
image: 146.59.87.168:3000/lfg2025/mariadb:11.4.10 image: source.archipelago-foundation.org/lfg2025/mariadb:11.4.10
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
data_uid: "100998:100998" data_uid: "100998:100998"
+1 -1
View File
@@ -6,7 +6,7 @@ app:
container_name: mempool container_name: mempool
container: container:
image: 146.59.87.168:3000/lfg2025/mempool-frontend:v3.0.1 image: source.archipelago-foundation.org/lfg2025/mempool-frontend:v3.0.1
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: BTCPay blockchain indexer service. description: BTCPay blockchain indexer service.
container: container:
image: 146.59.87.168:3000/lfg2025/nbxplorer:2.6.0 image: source.archipelago-foundation.org/lfg2025/nbxplorer:2.6.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
secret_env: secret_env:
+1 -1
View File
@@ -10,7 +10,7 @@ app:
# apps/barkd/Dockerfile and pushed to the node registry. Pin the tag to # apps/barkd/Dockerfile and pushed to the node registry. Pin the tag to
# match the REST shapes coded in core/archipelago/src/wallet/ark_client.rs # match the REST shapes coded in core/archipelago/src/wallet/ark_client.rs
# (validated against barkd 0.3.0 on signet, 2026-07-14). # (validated against barkd 0.3.0 on signet, 2026-07-14).
image: 146.59.87.168:3000/lfg2025/barkd:0.3.0 image: source.archipelago-foundation.org/lfg2025/barkd:0.3.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
# The entrypoint installs the shared secret below via `barkd secret # The entrypoint installs the shared secret below via `barkd secret
+1 -1
View File
@@ -7,7 +7,7 @@ app:
container_name: bitcoin-core container_name: bitcoin-core
container: container:
image: 146.59.87.168:3000/lfg2025/bitcoin:28.4 image: source.archipelago-foundation.org/lfg2025/bitcoin:28.4
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
entrypoint: ["sh", "-lc"] entrypoint: ["sh", "-lc"]
+1 -1
View File
@@ -7,7 +7,7 @@ app:
container_name: bitcoin-knots container_name: bitcoin-knots
container: container:
image: 146.59.87.168:3000/lfg2025/bitcoin-knots:latest image: source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
entrypoint: ["sh", "-lc"] entrypoint: ["sh", "-lc"]
+1 -1
View File
@@ -6,7 +6,7 @@ app:
category: community category: community
container: container:
image: 146.59.87.168:3000/lfg2025/botfights:1.2.11 image: source.archipelago-foundation.org/lfg2025/botfights:1.2.11
pull_policy: always pull_policy: always
# Auto-generated on first install (random hex, 0600, rootless-owned). The # Auto-generated on first install (random hex, 0600, rootless-owned). The
# 1.2.x image's server/src/middleware/jwt.ts throws at module import when # 1.2.x image's server/src/middleware/jwt.ts throws at module import when
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Electrum server indexing Bitcoin chain data for lightweight wallet queries. description: Electrum server indexing Bitcoin chain data for lightweight wallet queries.
container: container:
image: 146.59.87.168:3000/lfg2025/electrumx:v1.18.0 image: source.archipelago-foundation.org/lfg2025/electrumx:v1.18.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
data_uid: "1000:1000" data_uid: "1000:1000"
+1 -1
View File
@@ -9,7 +9,7 @@ app:
# 0.8.2 — iroh-capable). No usable upstream image exists, so we build + push # 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 # 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). # core/archipelago/src/wallet/fedimint_client.rs (validated against 0.8.2).
image: 146.59.87.168:3000/lfg2025/fmcd:0.8.1 image: source.archipelago-foundation.org/lfg2025/fmcd:0.8.1
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
# No entrypoint override: the image's resilient `fmcd-run` launcher loops # No entrypoint override: the image's resilient `fmcd-run` launcher loops
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Fedimint gateway service with automatic LND-or-LDK backend selection. description: Fedimint gateway service with automatic LND-or-LDK backend selection.
container: container:
image: 146.59.87.168:3000/lfg2025/gatewayd:v0.10.0 image: source.archipelago-foundation.org/lfg2025/gatewayd:v0.10.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
entrypoint: ["sh", "-lc"] entrypoint: ["sh", "-lc"]
+1 -1
View File
@@ -5,7 +5,7 @@ app:
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.
container: container:
image: 146.59.87.168:3000/lfg2025/fedimintd:v0.10.0 image: source.archipelago-foundation.org/lfg2025/fedimintd:v0.10.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
entrypoint: ["sh", "-lc"] entrypoint: ["sh", "-lc"]
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Baseline Archipelago file manager service. description: Baseline Archipelago file manager service.
container: container:
image: 146.59.87.168:3000/lfg2025/filebrowser:v2.27.0 image: source.archipelago-foundation.org/lfg2025/filebrowser:v2.27.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
custom_args: ["--config", "/data/.filebrowser.json"] custom_args: ["--config", "/data/.filebrowser.json"]
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Open source home automation platform. Control and monitor your smart home devices. description: Open source home automation platform. Control and monitor your smart home devices.
container: container:
image: 146.59.87.168:3000/lfg2025/home-assistant:2026.7.3 image: source.archipelago-foundation.org/lfg2025/home-assistant:2026.7.3
pull_policy: if-not-present pull_policy: if-not-present
network: pasta network: pasta
+1 -1
View File
@@ -11,7 +11,7 @@ app:
container_name: immich_postgres container_name: immich_postgres
container: container:
image: 146.59.87.168:3000/lfg2025/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0 image: source.archipelago-foundation.org/lfg2025/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
# postgres drops to its own uid (container 999 → host 100998 under rootless), # postgres drops to its own uid (container 999 → host 100998 under rootless),
+1 -1
View File
@@ -9,7 +9,7 @@ app:
container_name: immich_redis container_name: immich_redis
container: container:
image: 146.59.87.168:3000/lfg2025/valkey:7-alpine image: source.archipelago-foundation.org/lfg2025/valkey:7-alpine
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
+1 -1
View File
@@ -13,7 +13,7 @@ app:
container_name: immich_server container_name: immich_server
container: container:
image: 146.59.87.168:3000/lfg2025/immich-server:release image: source.archipelago-foundation.org/lfg2025/immich-server:release
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
secret_env: secret_env:
+1 -1
View File
@@ -12,7 +12,7 @@ app:
container_name: indeedhub-api container_name: indeedhub-api
container: container:
image: 146.59.87.168:3000/lfg2025/indeedhub-api:1.0.0 image: source.archipelago-foundation.org/lfg2025/indeedhub-api:1.0.0
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
network_aliases: [api] network_aliases: [api]
+1 -1
View File
@@ -11,7 +11,7 @@ app:
container_name: indeedhub-ffmpeg container_name: indeedhub-ffmpeg
container: container:
image: 146.59.87.168:3000/lfg2025/indeedhub-ffmpeg:1.0.0 image: source.archipelago-foundation.org/lfg2025/indeedhub-ffmpeg:1.0.0
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
secret_env: secret_env:
+1 -1
View File
@@ -11,7 +11,7 @@ app:
container_name: indeedhub-minio container_name: indeedhub-minio
container: container:
image: 146.59.87.168:3000/lfg2025/minio:RELEASE.2024-11-07T00-52-20Z image: source.archipelago-foundation.org/lfg2025/minio:RELEASE.2024-11-07T00-52-20Z
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
network_aliases: [minio] network_aliases: [minio]
+1 -1
View File
@@ -14,7 +14,7 @@ app:
container_name: indeedhub-postgres container_name: indeedhub-postgres
container: container:
image: 146.59.87.168:3000/lfg2025/postgres:16.13-alpine image: source.archipelago-foundation.org/lfg2025/postgres:16.13-alpine
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
network_aliases: [postgres] network_aliases: [postgres]
+1 -1
View File
@@ -10,7 +10,7 @@ app:
container_name: indeedhub-redis container_name: indeedhub-redis
container: container:
image: 146.59.87.168:3000/lfg2025/redis:7.4.8-alpine image: source.archipelago-foundation.org/lfg2025/redis:7.4.8-alpine
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
network_aliases: [redis] network_aliases: [redis]
+1 -1
View File
@@ -11,7 +11,7 @@ app:
container_name: indeedhub-relay container_name: indeedhub-relay
container: container:
image: 146.59.87.168:3000/lfg2025/nostr-rs-relay:0.9.0 image: source.archipelago-foundation.org/lfg2025/nostr-rs-relay:0.9.0
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
network_aliases: [relay] network_aliases: [relay]
+1 -1
View File
@@ -12,7 +12,7 @@ app:
container_name: indeedhub container_name: indeedhub
container: container:
image: 146.59.87.168:3000/lfg2025/indeedhub:1.0.0 image: source.archipelago-foundation.org/lfg2025/indeedhub:1.0.0
pull_policy: if-not-present pull_policy: if-not-present
network: indeedhub-net network: indeedhub-net
+1 -1
View File
@@ -12,7 +12,7 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FRONTEND_DIR="${INDEEHUB_FRONTEND:-$HOME/Projects/indeehub-frontend}" FRONTEND_DIR="${INDEEHUB_FRONTEND:-$HOME/Projects/indeehub-frontend}"
VERSION="${1:-latest}" VERSION="${1:-latest}"
REGISTRY="${REGISTRY:-146.59.87.168:3000}" REGISTRY="${REGISTRY:-source.archipelago-foundation.org}"
NAMESPACE="${NAMESPACE:-lfg2025}" NAMESPACE="${NAMESPACE:-lfg2025}"
IMAGE_NAME="indeedhub" IMAGE_NAME="indeedhub"
RUNTIME="${RUNTIME:-podman}" RUNTIME="${RUNTIME:-podman}"
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Free media server. Stream movies, music, and photos. description: Free media server. Stream movies, music, and photos.
container: container:
image: 146.59.87.168:3000/lfg2025/jellyfin:10.8.13 image: source.archipelago-foundation.org/lfg2025/jellyfin:10.8.13
pull_policy: if-not-present pull_policy: if-not-present
network: pasta network: pasta
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Lightning Network implementation by Lightning Labs. Enables instant, low-cost Bitcoin payments. description: Lightning Network implementation by Lightning Labs. Enables instant, low-cost Bitcoin payments.
container: container:
image: 146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta image: source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
# BITCOIND_HOST must follow the node's actual Bitcoin container — Knots or # BITCOIND_HOST must follow the node's actual Bitcoin container — Knots or
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Backend API for mempool explorer. description: Backend API for mempool explorer.
container: container:
image: 146.59.87.168:3000/lfg2025/mempool-backend:v3.0.0 image: source.archipelago-foundation.org/lfg2025/mempool-backend:v3.0.0
pull_policy: if-not-present pull_policy: if-not-present
network: archy-net network: archy-net
# CORE_RPC_HOST must follow the node's actual Bitcoin container — Knots or # CORE_RPC_HOST must follow the node's actual Bitcoin container — Knots or
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Bitcoin mempool and blockchain explorer. Real-time transaction and block visualization. description: Bitcoin mempool and blockchain explorer. Real-time transaction and block visualization.
container: container:
image: 146.59.87.168:3000/lfg2025/mempool-frontend:v3.0.1 image: source.archipelago-foundation.org/lfg2025/mempool-frontend:v3.0.1
image_signature: cosign://... image_signature: cosign://...
pull_policy: if-not-present pull_policy: if-not-present
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Your own private cloud. File sync, calendars, contacts. description: Your own private cloud. File sync, calendars, contacts.
container: container:
image: 146.59.87.168:3000/lfg2025/nextcloud:29 image: source.archipelago-foundation.org/lfg2025/nextcloud:29
pull_policy: if-not-present pull_policy: if-not-present
network: pasta network: pasta
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: AI-powered photo management with facial recognition. description: AI-powered photo management with facial recognition.
container: container:
image: 146.59.87.168:3000/lfg2025/photoprism:240915 image: source.archipelago-foundation.org/lfg2025/photoprism:240915
pull_policy: if-not-present pull_policy: if-not-present
dependencies: dependencies:
+1 -1
View File
@@ -6,7 +6,7 @@ app:
category: development category: development
container: container:
image: 146.59.87.168:3000/lfg2025/portainer:2.39.1 image: source.archipelago-foundation.org/lfg2025/portainer:2.39.1
pull_policy: if-not-present pull_policy: if-not-present
data_uid: "1000:1000" data_uid: "1000:1000"
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Privacy-respecting metasearch engine. Search the web without tracking. description: Privacy-respecting metasearch engine. Search the web without tracking.
container: container:
image: 146.59.87.168:3000/lfg2025/searxng:latest image: source.archipelago-foundation.org/lfg2025/searxng:latest
pull_policy: if-not-present pull_policy: if-not-present
dependencies: dependencies:
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Self-hosted uptime monitoring. description: Self-hosted uptime monitoring.
container: container:
image: 146.59.87.168:3000/lfg2025/uptime-kuma:1 image: source.archipelago-foundation.org/lfg2025/uptime-kuma:1
pull_policy: if-not-present pull_policy: if-not-present
network: pasta network: pasta
custom_args: ["--", "node", "server/server.js"] custom_args: ["--", "node", "server/server.js"]
+1 -1
View File
@@ -5,7 +5,7 @@ app:
description: Self-hosted password vault with zero-knowledge encryption. description: Self-hosted password vault with zero-knowledge encryption.
container: container:
image: 146.59.87.168:3000/lfg2025/vaultwarden:1.30.0-alpine image: source.archipelago-foundation.org/lfg2025/vaultwarden:1.30.0-alpine
pull_policy: if-not-present pull_policy: if-not-present
network: pasta network: pasta
+1 -1
View File
@@ -152,7 +152,7 @@ impl ApiHandler {
} }
if upstreams.is_empty() { if upstreams.is_empty() {
upstreams.push( upstreams.push(
"http://146.59.87.168:3000/lfg2025/app-catalog/raw/branch/main/catalog.json" "https://source.archipelago-foundation.org/lfg2025/app-catalog/raw/branch/main/catalog.json"
.to_string(), .to_string(),
); );
} }
@@ -1925,7 +1925,7 @@ autopilot.active=false\n",
.unwrap_or(true); .unwrap_or(true);
// Registries are configured as `host[:port]/namespace` (for // Registries are configured as `host[:port]/namespace` (for
// example `146.59.87.168:3000/lfg2025`), but the Docker V2 // example `source.archipelago-foundation.org/lfg2025`), but the Docker V2
// registry API lives at `/v2/` on the ROOT of the host — NOT // registry API lives at `/v2/` on the ROOT of the host — NOT
// under the namespace. Strip the namespace before appending // under the namespace. Strip the namespace before appending
// `/v2/` so the reachability probe hits the correct URL. // `/v2/` so the reachability probe hits the correct URL.
@@ -335,15 +335,15 @@ mod tests {
#[test] #[test]
fn image_tag_keeps_registry_port_colon() { fn image_tag_keeps_registry_port_colon() {
assert_eq!( assert_eq!(
image_tag("146.59.87.168:3000/lfg2025/bitcoin:28.4").as_deref(), image_tag("source.archipelago-foundation.org/lfg2025/bitcoin:28.4").as_deref(),
Some("28.4") Some("28.4")
); );
assert_eq!( assert_eq!(
image_tag("146.59.87.168:3000/lfg2025/bitcoin-knots:29.3.knots20260508").as_deref(), image_tag("source.archipelago-foundation.org/lfg2025/bitcoin-knots:29.3.knots20260508").as_deref(),
Some("29.3.knots20260508") Some("29.3.knots20260508")
); );
// No tag => None (don't mistake the registry port for a tag). // No tag => None (don't mistake the registry port for a tag).
assert_eq!(image_tag("146.59.87.168:3000/lfg2025/bitcoin"), None); assert_eq!(image_tag("source.archipelago-foundation.org/lfg2025/bitcoin"), None);
assert_eq!( assert_eq!(
image_tag("docker.io/library/redis:7"), image_tag("docker.io/library/redis:7"),
Some("7".to_string()) Some("7".to_string())
@@ -774,7 +774,7 @@ fn indeedhub_stack_app_ids() -> &'static [&'static str] {
] ]
} }
const REGISTRY: &str = "146.59.87.168:3000/lfg2025"; const REGISTRY: &str = "source.archipelago-foundation.org/lfg2025";
/// Pull an image with retry and exponential backoff (3 attempts). /// Pull an image with retry and exponential backoff (3 attempts).
async fn pull_image_with_retry(image: &str) -> Result<()> { async fn pull_image_with_retry(image: &str) -> Result<()> {
@@ -871,9 +871,9 @@ impl RpcHandler {
} }
let images = [ let images = [
"146.59.87.168:3000/lfg2025/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0", "source.archipelago-foundation.org/lfg2025/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0",
"146.59.87.168:3000/lfg2025/valkey:7-alpine", "source.archipelago-foundation.org/lfg2025/valkey:7-alpine",
"146.59.87.168:3000/lfg2025/immich-server:release", "source.archipelago-foundation.org/lfg2025/immich-server:release",
]; ];
self.set_install_phase("immich", InstallPhase::PullingImage) self.set_install_phase("immich", InstallPhase::PullingImage)
.await; .await;
@@ -947,7 +947,7 @@ impl RpcHandler {
"POSTGRES_USER=postgres", "POSTGRES_USER=postgres",
"-e", "-e",
"POSTGRES_DB=immich", "POSTGRES_DB=immich",
"146.59.87.168:3000/lfg2025/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0", "source.archipelago-foundation.org/lfg2025/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0",
]); ]);
run_required_stack_command("immich", "create postgres", &mut postgres_cmd).await?; run_required_stack_command("immich", "create postgres", &mut postgres_cmd).await?;
tokio::time::sleep(std::time::Duration::from_secs(5)).await; tokio::time::sleep(std::time::Duration::from_secs(5)).await;
@@ -973,7 +973,7 @@ impl RpcHandler {
"--health-cmd=valkey-cli ping || exit 1", "--health-cmd=valkey-cli ping || exit 1",
"--health-interval=30s", "--health-interval=30s",
"--health-retries=3", "--health-retries=3",
"146.59.87.168:3000/lfg2025/valkey:7-alpine", "source.archipelago-foundation.org/lfg2025/valkey:7-alpine",
]); ]);
run_required_stack_command("immich", "create redis", &mut redis_cmd).await?; run_required_stack_command("immich", "create redis", &mut redis_cmd).await?;
tokio::time::sleep(std::time::Duration::from_secs(2)).await; tokio::time::sleep(std::time::Duration::from_secs(2)).await;
@@ -1016,7 +1016,7 @@ impl RpcHandler {
"REDIS_HOSTNAME=immich_redis".to_string(), "REDIS_HOSTNAME=immich_redis".to_string(),
"-e".to_string(), "-e".to_string(),
"UPLOAD_LOCATION=/usr/src/app/upload".to_string(), "UPLOAD_LOCATION=/usr/src/app/upload".to_string(),
"146.59.87.168:3000/lfg2025/immich-server:release".to_string(), "source.archipelago-foundation.org/lfg2025/immich-server:release".to_string(),
], ],
) )
.await?; .await?;
@@ -1517,7 +1517,7 @@ impl RpcHandler {
.into_iter() .into_iter()
.find(|r| r.enabled) .find(|r| r.enabled)
.map(|r| r.url) .map(|r| r.url)
.unwrap_or_else(|| "146.59.87.168:3000/lfg2025".to_string()); .unwrap_or_else(|| "source.archipelago-foundation.org/lfg2025".to_string());
let user_tmp = format!( let user_tmp = format!(
"{}/.local/share/containers/tmp", "{}/.local/share/containers/tmp",
@@ -546,7 +546,7 @@ mod tests {
"apps": { "apps": {
"indeedhub": { "indeedhub": {
"version": "1.0.1", "version": "1.0.1",
"image": "146.59.87.168:3000/lfg2025/indeedhub:1.0.1", "image": "source.archipelago-foundation.org/lfg2025/indeedhub:1.0.1",
"digest": "blake3:deadbeef", "digest": "blake3:deadbeef",
"size": 12345, "size": 12345,
"another_future_field": true "another_future_field": true
@@ -560,7 +560,7 @@ mod tests {
assert_eq!(e.version, "1.0.1"); assert_eq!(e.version, "1.0.1");
assert_eq!( assert_eq!(
e.image.as_deref(), e.image.as_deref(),
Some("146.59.87.168:3000/lfg2025/indeedhub:1.0.1") Some("source.archipelago-foundation.org/lfg2025/indeedhub:1.0.1")
); );
assert_eq!(e.digest.as_deref(), Some("blake3:deadbeef")); assert_eq!(e.digest.as_deref(), Some("blake3:deadbeef"));
} }
@@ -628,7 +628,7 @@ mod tests {
#[test] #[test]
fn catalog_url_derived_from_mirror() { fn catalog_url_derived_from_mirror() {
let mirrors = vec![crate::update::UpdateMirror { let mirrors = vec![crate::update::UpdateMirror {
url: "http://146.59.87.168:3000/lfg2025/archy/raw/branch/main/releases/manifest.json" url: "https://source.archipelago-foundation.org/lfg2025/archy/raw/branch/main/releases/manifest.json"
.to_string(), .to_string(),
label: "Server 1".to_string(), label: "Server 1".to_string(),
}]; }];
@@ -636,7 +636,7 @@ mod tests {
assert_eq!( assert_eq!(
urls, urls,
vec![ vec![
"http://146.59.87.168:3000/lfg2025/archy/raw/branch/main/releases/app-catalog.json" "https://source.archipelago-foundation.org/lfg2025/archy/raw/branch/main/releases/app-catalog.json"
.to_string() .to_string()
] ]
); );
+2 -2
View File
@@ -33,7 +33,7 @@ use tracing::{info, warn};
use crate::container::quadlet::{self, BindMount, NetworkMode, QuadletUnit}; use crate::container::quadlet::{self, BindMount, NetworkMode, QuadletUnit};
use archipelago_container::image_uses_insecure_registry; use archipelago_container::image_uses_insecure_registry;
const COMPANION_REGISTRY: &str = "146.59.87.168:3000/lfg2025"; const COMPANION_REGISTRY: &str = "source.archipelago-foundation.org/lfg2025";
const COMPANION_IMAGE_CHECK_TIMEOUT: Duration = Duration::from_secs(15); const COMPANION_IMAGE_CHECK_TIMEOUT: Duration = Duration::from_secs(15);
const COMPANION_BUILD_TIMEOUT: Duration = Duration::from_secs(900); const COMPANION_BUILD_TIMEOUT: Duration = Duration::from_secs(900);
const COMPANION_PULL_TIMEOUT: Duration = Duration::from_secs(300); const COMPANION_PULL_TIMEOUT: Duration = Duration::from_secs(300);
@@ -54,7 +54,7 @@ pub struct CompanionSpec {
/// Container + unit name (e.g. "archy-bitcoin-ui"). /// Container + unit name (e.g. "archy-bitcoin-ui").
pub name: &'static str, pub name: &'static str,
/// Image base name in the lfg2025 registry namespace /// Image base name in the lfg2025 registry namespace
/// (e.g. "bitcoin-ui" → "146.59.87.168:3000/lfg2025/bitcoin-ui:latest"). /// (e.g. "bitcoin-ui" → "source.archipelago-foundation.org/lfg2025/bitcoin-ui:latest").
pub image_base: &'static str, pub image_base: &'static str,
/// Filesystem locations to look for a local Dockerfile (build wins /// Filesystem locations to look for a local Dockerfile (build wins
/// over registry pull). Searched in order; first hit wins. /// over registry pull). Searched in order; first hit wins.
@@ -8,13 +8,13 @@
/// (git.tx1138.com was removed 2026-07-10: the host is retired and must /// (git.tx1138.com was removed 2026-07-10: the host is retired and must
/// never be pulled through again.) /// never be pulled through again.)
pub const TRUSTED_REGISTRIES: &[&str] = pub const TRUSTED_REGISTRIES: &[&str] =
&["docker.io", "ghcr.io", "localhost", "146.59.87.168:3000"]; &["docker.io", "ghcr.io", "localhost", "source.archipelago-foundation.org"];
/// Validate a container image reference. /// Validate a container image reference.
/// ///
/// Accepts: /// Accepts:
/// * refs whose explicit registry host is on [`TRUSTED_REGISTRIES`] /// * refs whose explicit registry host is on [`TRUSTED_REGISTRIES`]
/// (`docker.io/grafana/grafana`, `146.59.87.168:3000/archy/x:1`), and /// (`docker.io/grafana/grafana`, `source.archipelago-foundation.org/archy/x:1`), and
/// * registry-less Docker Hub shorthand (`nginx`, `grafana/grafana`) — /// * registry-less Docker Hub shorthand (`nginx`, `grafana/grafana`) —
/// the first segment has no `.`/`:` so it cannot name an attacker host; /// the first segment has no `.`/`:` so it cannot name an attacker host;
/// resolution follows the host's registries.conf search order. /// resolution follows the host's registries.conf search order.
@@ -55,7 +55,7 @@ mod tests {
"docker.io/library/nginx:1.25", "docker.io/library/nginx:1.25",
"ghcr.io/owner/app:latest", "ghcr.io/owner/app:latest",
"localhost/archy-dev:1", "localhost/archy-dev:1",
"146.59.87.168:3000/archy/bitcoin-knots:28.1", "source.archipelago-foundation.org/archy/bitcoin-knots:28.1",
] { ] {
assert!(is_valid_docker_image(img), "{img} should be accepted"); assert!(is_valid_docker_image(img), "{img} should be accepted");
} }
@@ -234,7 +234,7 @@ pub fn available_update_for_images(pinned: &str, running_image: &str) -> Option<
} }
/// Extract version tag from a full image reference. /// Extract version tag from a full image reference.
/// e.g. "146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta" → "v0.18.4-beta" /// e.g. "source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta" → "v0.18.4-beta"
/// Returns "latest" if no tag or tag is empty. /// Returns "latest" if no tag or tag is empty.
pub fn extract_version_from_image(image: &str) -> String { pub fn extract_version_from_image(image: &str) -> String {
// Split off the tag after the last colon, but only if it comes after the last slash // Split off the tag after the last colon, but only if it comes after the last slash
@@ -328,11 +328,11 @@ mod tests {
#[test] #[test]
fn test_extract_version() { fn test_extract_version() {
assert_eq!( assert_eq!(
extract_version_from_image("146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta"), extract_version_from_image("source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta"),
"v0.18.4-beta" "v0.18.4-beta"
); );
assert_eq!( assert_eq!(
extract_version_from_image("146.59.87.168:3000/lfg2025/grafana:10.2.0"), extract_version_from_image("source.archipelago-foundation.org/lfg2025/grafana:10.2.0"),
"10.2.0" "10.2.0"
); );
assert_eq!( assert_eq!(
@@ -340,7 +340,7 @@ mod tests {
"latest" "latest"
); );
assert_eq!( assert_eq!(
extract_version_from_image("146.59.87.168:3000/lfg2025/bitcoin-knots:latest"), extract_version_from_image("source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest"),
"latest" "latest"
); );
} }
@@ -348,11 +348,11 @@ mod tests {
#[test] #[test]
fn strips_registry_and_tag_for_image_identity() { fn strips_registry_and_tag_for_image_identity() {
assert_eq!( assert_eq!(
image_without_registry_or_tag("146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta"), image_without_registry_or_tag("source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta"),
"lfg2025/lnd" "lfg2025/lnd"
); );
assert_eq!( assert_eq!(
image_without_registry_or_tag("146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta"), image_without_registry_or_tag("source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta"),
"lfg2025/lnd" "lfg2025/lnd"
); );
} }
@@ -368,8 +368,8 @@ mod tests {
fn available_update_ignores_registry_only_changes() { fn available_update_ignores_registry_only_changes() {
assert_eq!( assert_eq!(
available_update_for_images( available_update_for_images(
"146.59.87.168:3000/lfg2025/nextcloud:29", "source.archipelago-foundation.org/lfg2025/nextcloud:29",
"146.59.87.168:3000/lfg2025/nextcloud:29", "source.archipelago-foundation.org/lfg2025/nextcloud:29",
), ),
None None
); );
@@ -379,8 +379,8 @@ mod tests {
fn available_update_returns_pinned_version_for_same_repo_newer_tag() { fn available_update_returns_pinned_version_for_same_repo_newer_tag() {
assert_eq!( assert_eq!(
available_update_for_images( available_update_for_images(
"146.59.87.168:3000/lfg2025/nextcloud:29", "source.archipelago-foundation.org/lfg2025/nextcloud:29",
"146.59.87.168:3000/lfg2025/nextcloud:28", "source.archipelago-foundation.org/lfg2025/nextcloud:28",
), ),
Some("29".to_string()) Some("29".to_string())
); );
@@ -389,7 +389,7 @@ mod tests {
#[test] #[test]
fn test_parse_image_versions() { fn test_parse_image_versions() {
let content = r#" let content = r#"
ARCHY_REGISTRY="146.59.87.168:3000/lfg2025" ARCHY_REGISTRY="source.archipelago-foundation.org/lfg2025"
LND_IMAGE="$ARCHY_REGISTRY/lnd:v0.18.4-beta" LND_IMAGE="$ARCHY_REGISTRY/lnd:v0.18.4-beta"
GRAFANA_IMAGE="$ARCHY_REGISTRY/grafana:10.2.0" GRAFANA_IMAGE="$ARCHY_REGISTRY/grafana:10.2.0"
# comment # comment
@@ -398,11 +398,11 @@ NOT_AN_IMAGE="something"
let parsed = parse_image_versions(content); let parsed = parse_image_versions(content);
assert_eq!( assert_eq!(
parsed.get("LND_IMAGE"), parsed.get("LND_IMAGE"),
Some(&"146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta".to_string()) Some(&"source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta".to_string())
); );
assert_eq!( assert_eq!(
parsed.get("GRAFANA_IMAGE"), parsed.get("GRAFANA_IMAGE"),
Some(&"146.59.87.168:3000/lfg2025/grafana:10.2.0".to_string()) Some(&"source.archipelago-foundation.org/lfg2025/grafana:10.2.0".to_string())
); );
assert!(!parsed.contains_key("NOT_AN_IMAGE")); assert!(!parsed.contains_key("NOT_AN_IMAGE"));
assert!(!parsed.contains_key("ARCHY_REGISTRY")); assert!(!parsed.contains_key("ARCHY_REGISTRY"));
@@ -5224,7 +5224,7 @@ app:
name: File Browser name: File Browser
version: 1.0.0 version: 1.0.0
container: container:
image: 146.59.87.168:3000/lfg2025/filebrowser:v2.27.0 image: source.archipelago-foundation.org/lfg2025/filebrowser:v2.27.0
custom_args: custom_args:
- --config - --config
- /data/.filebrowser.json - /data/.filebrowser.json
@@ -5248,7 +5248,7 @@ app:
name: LND name: LND
version: 1.0.0 version: 1.0.0
container: container:
image: 146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta image: source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta
secret_env: secret_env:
- key: BITCOIND_RPCPASS - key: BITCOIND_RPCPASS
secret_file: bitcoin-rpc-password secret_file: bitcoin-rpc-password
+2 -2
View File
@@ -956,7 +956,7 @@ mod tests {
QuadletUnit { QuadletUnit {
name: "archy-bitcoin-ui".into(), name: "archy-bitcoin-ui".into(),
description: "Bitcoin RPC UI proxy".into(), description: "Bitcoin RPC UI proxy".into(),
image: "146.59.87.168:3000/lfg2025/bitcoin-ui:1.7.84-alpha".into(), image: "source.archipelago-foundation.org/lfg2025/bitcoin-ui:1.7.84-alpha".into(),
network: NetworkMode::Host, network: NetworkMode::Host,
user: Some("0:0".into()), user: Some("0:0".into()),
memory_mb: Some(128), memory_mb: Some(128),
@@ -984,7 +984,7 @@ mod tests {
let s = sample_unit().render(); let s = sample_unit().render();
assert!(s.contains("[Container]")); assert!(s.contains("[Container]"));
assert!(s.contains("ContainerName=archy-bitcoin-ui")); assert!(s.contains("ContainerName=archy-bitcoin-ui"));
assert!(s.contains("Image=146.59.87.168:3000/lfg2025/bitcoin-ui:1.7.84-alpha")); assert!(s.contains("Image=source.archipelago-foundation.org/lfg2025/bitcoin-ui:1.7.84-alpha"));
assert!(s.contains("Pull=never")); assert!(s.contains("Pull=never"));
assert!(s.contains("Network=host")); assert!(s.contains("Network=host"));
assert!(s.contains("DropCapability=ALL")); assert!(s.contains("DropCapability=ALL"));
+7 -7
View File
@@ -10,7 +10,7 @@ use std::path::Path;
use tokio::fs; use tokio::fs;
const REGISTRY_FILE: &str = "config/registries.json"; const REGISTRY_FILE: &str = "config/registries.json";
const OVH_REGISTRY_URL: &str = "146.59.87.168:3000/lfg2025"; const OVH_REGISTRY_URL: &str = "source.archipelago-foundation.org/lfg2025";
/// Retired registry host (release server retired 2026-06-13; the registry /// Retired registry host (release server retired 2026-06-13; the registry
/// frontend was fully dead by 2026-07-10 — 500 on every /v2 manifest read). /// frontend was fully dead by 2026-07-10 — 500 on every /v2 manifest read).
/// Never a default, never force-enabled; stripped from saved configs on /// Never a default, never force-enabled; stripped from saved configs on
@@ -21,7 +21,7 @@ const RETIRED_TX1138_HOST: &str = "git.tx1138.com";
/// A single container registry. /// A single container registry.
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Registry { pub struct Registry {
/// Registry URL (e.g., "146.59.87.168:3000/lfg2025"). /// Registry URL (e.g., "source.archipelago-foundation.org/lfg2025").
pub url: String, pub url: String,
/// Human-readable name. /// Human-readable name.
pub name: String, pub name: String,
@@ -68,8 +68,8 @@ impl RegistryConfig {
} }
/// Rewrite an image reference to use a specific registry. /// Rewrite an image reference to use a specific registry.
/// E.g., "docker.io/lfg2025/bitcoin-knots:latest" with registry "146.59.87.168:3000/lfg2025" /// E.g., "docker.io/lfg2025/bitcoin-knots:latest" with registry "source.archipelago-foundation.org/lfg2025"
/// becomes "146.59.87.168:3000/lfg2025/bitcoin-knots:latest". /// becomes "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest".
pub fn rewrite_image(&self, image: &str, registry: &Registry) -> String { pub fn rewrite_image(&self, image: &str, registry: &Registry) -> String {
// Extract the image name (last component after the org/namespace) // Extract the image name (last component after the org/namespace)
// Handles: "registry/org/image:tag" -> "image:tag" // Handles: "registry/org/image:tag" -> "image:tag"
@@ -79,7 +79,7 @@ impl RegistryConfig {
} }
/// Extract the image name from a full image reference. /// Extract the image name from a full image reference.
/// "146.59.87.168:3000/lfg2025/bitcoin-knots:latest" -> "bitcoin-knots:latest" /// "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest" -> "bitcoin-knots:latest"
/// "docker.io/gitea/gitea:1.23" -> "gitea:1.23" /// "docker.io/gitea/gitea:1.23" -> "gitea:1.23"
fn extract_image_name(image: &str) -> &str { fn extract_image_name(image: &str) -> &str {
// Split by '/' and take the last segment (image:tag) // Split by '/' and take the last segment (image:tag)
@@ -212,7 +212,7 @@ mod tests {
#[test] #[test]
fn test_extract_image_name() { fn test_extract_image_name() {
assert_eq!( assert_eq!(
extract_image_name("146.59.87.168:3000/lfg2025/bitcoin-knots:latest"), extract_image_name("source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest"),
"bitcoin-knots:latest" "bitcoin-knots:latest"
); );
assert_eq!( assert_eq!(
@@ -230,7 +230,7 @@ mod tests {
let primary = &config.registries[0]; let primary = &config.registries[0];
assert_eq!( assert_eq!(
config.rewrite_image("docker.io/lfg2025/bitcoin-knots:latest", primary), config.rewrite_image("docker.io/lfg2025/bitcoin-knots:latest", primary),
"146.59.87.168:3000/lfg2025/bitcoin-knots:latest" "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest"
); );
} }
+1 -1
View File
@@ -88,7 +88,7 @@ const DEFAULT_UPDATE_MANIFEST_URL: &str =
/// whose DNS or TLS is broken still updates. Dropped from the mirror list /// whose DNS or TLS is broken still updates. Dropped from the mirror list
/// once the fleet has moved. /// once the fleet has moved.
const LEGACY_UPDATE_MANIFEST_URL: &str = const LEGACY_UPDATE_MANIFEST_URL: &str =
"http://146.59.87.168:3000/lfg2025/archy/raw/branch/main/releases/manifest.json"; "https://source.archipelago-foundation.org/lfg2025/archy/raw/branch/main/releases/manifest.json";
const UPDATE_STATE_FILE: &str = "update_state.json"; const UPDATE_STATE_FILE: &str = "update_state.json";
const UPDATE_MIRRORS_FILE: &str = "update-mirrors.json"; const UPDATE_MIRRORS_FILE: &str = "update-mirrors.json";
/// Marker written by apply_update() just before the service restart and /// Marker written by apply_update() just before the service restart and
+3 -3
View File
@@ -742,7 +742,7 @@ impl PodmanClient {
/// Registries we ship with as `--tls-verify=false` because they're internal /// Registries we ship with as `--tls-verify=false` because they're internal
/// HTTP mirrors. Add a host:port here only if it's a controlled mirror that /// HTTP mirrors. Add a host:port here only if it's a controlled mirror that
/// the fleet trusts and operators won't ever paste a malicious URL into. /// the fleet trusts and operators won't ever paste a malicious URL into.
const INSECURE_REGISTRY_HOSTS: &[&str] = &["146.59.87.168:3000"]; const INSECURE_REGISTRY_HOSTS: &[&str] = &["source.archipelago-foundation.org"];
pub fn image_uses_insecure_registry(image: &str) -> bool { pub fn image_uses_insecure_registry(image: &str) -> bool {
image image
@@ -1087,7 +1087,7 @@ mod tests {
#[test] #[test]
fn insecure_registry_detection_matches_http_mirrors_only() { fn insecure_registry_detection_matches_http_mirrors_only() {
assert!(image_uses_insecure_registry( assert!(image_uses_insecure_registry(
"146.59.87.168:3000/lfg2025/bitcoin-knots:latest" "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest"
)); ));
// The legacy Hetzner mirror at 23.182.128.160 was decommissioned and // The legacy Hetzner mirror at 23.182.128.160 was decommissioned and
// is no longer trusted — it must NOT bypass TLS even if a stale // is no longer trusted — it must NOT bypass TLS even if a stale
@@ -1106,7 +1106,7 @@ mod tests {
// string into its own URL still has the attacker host in the // string into its own URL still has the attacker host in the
// registry-host slot, so it does NOT match. // registry-host slot, so it does NOT match.
assert!(!image_uses_insecure_registry( assert!(!image_uses_insecure_registry(
"evil.example:80/146.59.87.168:3000/lfg2025/x:latest" "evil.example:80/source.archipelago-foundation.org/lfg2025/x:latest"
)); ));
} }
+1 -1
View File
@@ -1,7 +1,7 @@
# Copy to .env and adjust. Used by demo-deploy/docker-compose.yml. # Copy to .env and adjust. Used by demo-deploy/docker-compose.yml.
# Registry host + namespace that holds the prebuilt demo images. # Registry host + namespace that holds the prebuilt demo images.
REGISTRY=146.59.87.168:3000/lfg2025 REGISTRY=source.archipelago-foundation.org/lfg2025
# Image tag to deploy (CI publishes :demo and :<git-sha>). # Image tag to deploy (CI publishes :demo and :<git-sha>).
IMAGE_TAG=demo IMAGE_TAG=demo
+2 -2
View File
@@ -18,7 +18,7 @@
services: services:
neode-backend: neode-backend:
image: ${REGISTRY:-146.59.87.168:3000/lfg2025}/archy-demo-backend:${IMAGE_TAG:-demo} image: ${REGISTRY:-source.archipelago-foundation.org/lfg2025}/archy-demo-backend:${IMAGE_TAG:-demo}
container_name: archy-demo-backend container_name: archy-demo-backend
environment: environment:
DEMO: "1" DEMO: "1"
@@ -40,7 +40,7 @@ services:
retries: 3 retries: 3
neode-web: neode-web:
image: ${REGISTRY:-146.59.87.168:3000/lfg2025}/archy-demo-web:${IMAGE_TAG:-demo} image: ${REGISTRY:-source.archipelago-foundation.org/lfg2025}/archy-demo-web:${IMAGE_TAG:-demo}
container_name: archy-demo-web container_name: archy-demo-web
ports: ports:
- "${DEMO_WEB_PORT:-2100}:80" - "${DEMO_WEB_PORT:-2100}:80"
+1 -1
View File
@@ -5,7 +5,7 @@
# the frontend re-resolves the backend (mempool-api) via DNS on every request. # the frontend re-resolves the backend (mempool-api) via DNS on every request.
# Without this, nginx pins the backend IP at startup and serves 502 / "offline" # Without this, nginx pins the backend IP at startup and serves 502 / "offline"
# after any backend restart (podman reassigns the IP). See the script header. # after any backend restart (podman reassigns the IP). See the script header.
ARG BASE=146.59.87.168:3000/lfg2025/mempool-frontend:v3.0.0 ARG BASE=source.archipelago-foundation.org/lfg2025/mempool-frontend:v3.0.0
FROM ${BASE} FROM ${BASE}
# --chmod keeps the exec bit (build runs as USER 1000, plain COPY lands root:0644 # --chmod keeps the exec bit (build runs as USER 1000, plain COPY lands root:0644
+2 -2
View File
@@ -71,7 +71,7 @@ arbitrary app catalog to the entire fleet — fully unattended under
install cosign + publish real `image_signature` values (in that order); tracked with install cosign + publish real `image_signature` values (in that order); tracked with
the Workstream B signing ceremony item. the Workstream B signing ceremony item.
- [ ] 🟠 **Move the image mirror to HTTPS; drop `--tls-verify=false`.** - [ ] 🟠 **Move the image mirror to HTTPS; drop `--tls-verify=false`.**
`podman_client.rs:641` `INSECURE_REGISTRY_HOSTS = ["146.59.87.168:3000"]` + `podman_client.rs:641` `INSECURE_REGISTRY_HOSTS = ["source.archipelago-foundation.org"]` +
`config.rs:104,124` allowlist pull images over unauthenticated HTTP. Remove the raw-IP `config.rs:104,124` allowlist pull images over unauthenticated HTTP. Remove the raw-IP
entries; give the mirror a valid/pinned cert. (Same host also baked insecurely into entries; give the mirror a valid/pinned cert. (Same host also baked insecurely into
the ISO — see §F.) the ISO — see §F.)
@@ -310,7 +310,7 @@ media (latest artifact only one minor behind).
`archipelago ceremony verify` against the pinned anchor; build host never holds the `archipelago ceremony verify` against the pinned anchor; build host never holds the
key). **Still open:** Secure Boot — `BOOTX64.EFI` is unsigned though key). **Still open:** Secure Boot — `BOOTX64.EFI` is unsigned though
`grub-efi-amd64-signed` is installed. `grub-efi-amd64-signed` is installed.
- [ ] 🟠 **Registries over HTTPS in the image too**`146.59.87.168:3000` - [ ] 🟠 **Registries over HTTPS in the image too**`source.archipelago-foundation.org`
are baked `insecure=true`/`tls_verify:false` (`:216`, `:2308`). (Ties to §A.) are baked `insecure=true`/`tls_verify:false` (`:216`, `:2308`). (Ties to §A.)
- [ ] 🟡 **Add `unattended-upgrades` + a default-deny nftables firewall** (allow 22/80/443 + - [ ] 🟡 **Add `unattended-upgrades` + a default-deny nftables firewall** (allow 22/80/443 +
mesh/WG). Neither exists today; OS packages drift until reflash and there is no host mesh/WG). Neither exists today; OS packages drift until reflash and there is no host
+2 -2
View File
@@ -46,7 +46,7 @@ layer**.
CI: build archy-demo-web + archy-demo-backend CI: build archy-demo-web + archy-demo-backend
│ push :demo / :latest │ push :demo / :latest
registry (146.59.87.168:3000 / vps2) registry (source.archipelago-foundation.org / vps2)
│ Portainer webhook / re-pull │ Portainer webhook / re-pull
archy-demo (public repo — tiny) archy-demo (public repo — tiny)
@@ -162,7 +162,7 @@ Today filebrowser upload/delete/rename are 200-OK no-ops.
1. **Demo host** — which Portainer instance (OVH `.168`? a dedicated VPS)? Public 1. **Demo host** — which Portainer instance (OVH `.168`? a dedicated VPS)? Public
DNS + TLS for `demo.<domain>`? DNS + TLS for `demo.<domain>`?
2. **Registry for `:demo` images**`146.59.87.168:3000` vs vps2; public-pull or 2. **Registry for `:demo` images**`source.archipelago-foundation.org` vs vps2; public-pull or
creds baked into Portainer? creds baked into Portainer?
3. **Session TTL + concurrency cap** — concrete numbers (30 min / N sessions / 50 MB)? 3. **Session TTL + concurrency cap** — concrete numbers (30 min / N sessions / 50 MB)?
4. **Chat in the demo** — enable Claude chat (needs key + budget cap) or stub it? 4. **Chat in the demo** — enable Claude chat (needs key + budget cap) or stub it?
+1 -1
View File
@@ -111,7 +111,7 @@ green first), `MEMORY → project_decoupled_app_updates`,
|-------|-------| |-------|-------|
| `apps/bitcoin-core/Dockerfile` | `FROM bitcoin/bitcoin:24.0` — a **community** image, **stale** (manifest says 28.4), no project-official Docker image exists | | `apps/bitcoin-core/Dockerfile` | `FROM bitcoin/bitcoin:24.0` — a **community** image, **stale** (manifest says 28.4), no project-official Docker image exists |
| `apps/bitcoin-knots/` | **no Dockerfile**`:latest` is built/pushed by hand | | `apps/bitcoin-knots/` | **no Dockerfile**`:latest` is built/pushed by hand |
| Registry | `scripts/image-versions.sh``ARCHY_REGISTRY="146.59.87.168:3000/lfg2025"`; only `BITCOIN_KNOTS_IMAGE=…/bitcoin-knots:latest` pinned, no Core pin | | Registry | `scripts/image-versions.sh``ARCHY_REGISTRY="source.archipelago-foundation.org/lfg2025"`; only `BITCOIN_KNOTS_IMAGE=…/bitcoin-knots:latest` pinned, no Core pin |
| Tags in registry | **one tag per image**. No historical versions. | | Tags in registry | **one tag per image**. No historical versions. |
### Version pinning ### Version pinning
+1 -1
View File
@@ -45,7 +45,7 @@ Three **stacked** bugs, plus a data-corruption hazard:
removed `USER bitcoin` → run as **container-root** like legacy (still 100% rootless: removed `USER bitcoin` → run as **container-root** like legacy (still 100% rootless:
container-root maps to the unprivileged host service user; `CAP_DAC_OVERRIDE` from the container-root maps to the unprivileged host service user; `CAP_DAC_OVERRIDE` from the
manifest lets bitcoind read the `data_uid`-owned datadir). **All** images rebuilt root + manifest lets bitcoind read the `data_uid`-owned datadir). **All** images rebuilt root +
pushed to the mirror (`146.59.87.168:3000/lfg2025`): pushed to the mirror (`source.archipelago-foundation.org/lfg2025`):
- Knots: `29.3.knots20260508`, `29.3.knots20260507`, `29.3.knots20260210`, `29.2.knots20251110` - Knots: `29.3.knots20260508`, `29.3.knots20260507`, `29.3.knots20260210`, `29.2.knots20251110`
- Core: `25.2 26.2 27.2 28.4 29.2 29.3 30.2 31.0` + `latest` (→31.0) - Core: `25.2 26.2 27.2 28.4 29.2 29.3 30.2 31.0` + `latest` (→31.0)
- **Catalog** (`scripts/generate-app-catalog.sh` VERSIONS map + regenerated - **Catalog** (`scripts/generate-app-catalog.sh` VERSIONS map + regenerated
+1 -1
View File
@@ -842,7 +842,7 @@
</ul> </ul>
<h4>Registry</h4> <h4>Registry</h4>
<ul> <ul>
<li>Private registry at <code>146.59.87.168:3000/lfg2025/</code></li> <li>Private registry at <code>source.archipelago-foundation.org/lfg2025/</code></li>
<li>HTTPS (self-hosted Gitea)</li> <li>HTTPS (self-hosted Gitea)</li>
<li>All images pre-pulled into registry; nodes pull on first boot</li> <li>All images pre-pulled into registry; nodes pull on first boot</li>
</ul> </ul>
+2 -2
View File
@@ -3,7 +3,7 @@
**Status:** implemented & deployable (2026-07-14) **Status:** implemented & deployable (2026-07-14)
**Branch:** `main` — the demo machinery was merged from the old `demo-build` **Branch:** `main` — the demo machinery was merged from the old `demo-build`
branch and now lives on main, pushed to branch and now lives on main, pushed to
`gitea-vps2` = `http://146.59.87.168:3000/lfg2025/archy.git`. `gitea-vps2` = `https://source.archipelago-foundation.org/lfg2025/archy.git`.
A public, click-to-play demo of the Archipelago UI, 100% mock-data driven, A public, click-to-play demo of the Archipelago UI, 100% mock-data driven,
multi-visitor, deployed via Portainer. See also `docs/archive/demo-deployment-design.md` multi-visitor, deployed via Portainer. See also `docs/archive/demo-deployment-design.md`
@@ -17,7 +17,7 @@ Build-from-repo (works today, no registry needed):
| Field | Value | | Field | Value |
|-------|-------| |-------|-------|
| Repository URL | `http://146.59.87.168:3000/lfg2025/archy.git` | | Repository URL | `https://source.archipelago-foundation.org/lfg2025/archy.git` |
| Reference | `refs/heads/main` | | Reference | `refs/heads/main` |
| Compose path | `docker-compose.demo.yml` | | Compose path | `docker-compose.demo.yml` |
| Auth | user `lfg2025`, password = Gitea token | | Auth | user `lfg2025`, password = Gitea token |
+3 -3
View File
@@ -28,7 +28,7 @@ origin":
### OTA (`core/archipelago/src/update.rs`) ### OTA (`core/archipelago/src/update.rs`)
- Manifest at `DEFAULT_UPDATE_MANIFEST_URL` (`update.rs:67`) = vps2 OVH - Manifest at `DEFAULT_UPDATE_MANIFEST_URL` (`update.rs:67`) = vps2 OVH
(`146.59.87.168:3000/lfg2025/archy/raw/branch/main/releases/manifest.json`). (`source.archipelago-foundation.org/lfg2025/archy/raw/branch/main/releases/manifest.json`).
- `check_for_updates()` (`:565`) walks an operator mirror list (`default_mirrors()` `:105`, - `check_for_updates()` (`:565`) walks an operator mirror list (`default_mirrors()` `:105`,
`load_mirrors()` `:123`), origin-rewrites component URLs to the chosen mirror `load_mirrors()` `:123`), origin-rewrites component URLs to the chosen mirror
(`rewrite_manifest_origins()` `:227`). (`rewrite_manifest_origins()` `:227`).
@@ -65,9 +65,9 @@ origin":
### IndeeHub (the streaming target) ### IndeeHub (the streaming target)
- Original platform (not a fork). Working source: `~/Projects/Indeedhub Prototype/` - Original platform (not a fork). Working source: `~/Projects/Indeedhub Prototype/`
(Vue 3 + NestJS). Submodule `146.59.87.168:3000/lfg2025/indeehub.git` (repointed off the retired host — (Vue 3 + NestJS). Submodule `source.archipelago-foundation.org/lfg2025/indeehub.git` (repointed off the retired host —
needs a live remote). In `archy`: image-only, `apps/indeedhub/manifest.yml` pulls needs a live remote). In `archy`: image-only, `apps/indeedhub/manifest.yml` pulls
`146.59.87.168:3000/lfg2025/indeedhub:1.0.0` (+ `-api`, `-ffmpeg`, postgres, redis, `source.archipelago-foundation.org/lfg2025/indeedhub:1.0.0` (+ `-api`, `-ffmpeg`, postgres, redis,
minio, nostr-rs-relay). minio, nostr-rs-relay).
- Streaming today: FFmpeg → **HLS (.m3u8 + AES-128 .ts segments)** in **MinIO** - Streaming today: FFmpeg → **HLS (.m3u8 + AES-128 .ts segments)** in **MinIO**
(`indeedhub-private`/`-public`), metadata in Postgres, transcode queue in Redis, (`indeedhub-private`/`-public`), metadata in Postgres, transcode queue in Redis,
+1 -1
View File
@@ -94,7 +94,7 @@ in sync with the manifest env. clientd is a **client, not the guardian** — it
under `image-recipe/_archived/` (likely stale); `first-boot-containers.sh`/`image-versions.sh` under `image-recipe/_archived/` (likely stale); `first-boot-containers.sh`/`image-versions.sh`
are current. are current.
- Image: build from source (no official image; `flake.nix` only) → push to vps2 - Image: build from source (no official image; `flake.nix` only) → push to vps2
`146.59.87.168:3000/lfg2025/fedimint-clientd:v0.4.0`. `source.archipelago-foundation.org/lfg2025/fedimint-clientd:v0.4.0`.
### 5. Unified balance ### 5. Unified balance
`HomeWalletCard` ecash row = Cashu `wallet.ecash-balance` + Fedimint `wallet.fedimint-balance`. `HomeWalletCard` ecash row = Cashu `wallet.ecash-balance` + Fedimint `wallet.fedimint-balance`.
@@ -112,7 +112,7 @@ jobs:
run: | run: |
sudo mkdir -p /etc/containers/registries.conf.d sudo mkdir -p /etc/containers/registries.conf.d
echo '[[registry]] echo '[[registry]]
location = "146.59.87.168:3000" location = "source.archipelago-foundation.org"
insecure = true' | sudo tee /etc/containers/registries.conf.d/archipelago.conf insecure = true' | sudo tee /etc/containers/registries.conf.d/archipelago.conf
- name: Build unbundled ISO - name: Build unbundled ISO
@@ -223,7 +223,7 @@ check_tools() {
fi fi
if mkdir -p "$REGCONF_DIR" 2>/dev/null && cat > "$REGCONF_DIR/archipelago.conf" 2>/dev/null <<'REGCONF' if mkdir -p "$REGCONF_DIR" 2>/dev/null && cat > "$REGCONF_DIR/archipelago.conf" 2>/dev/null <<'REGCONF'
[[registry]] [[registry]]
location = "146.59.87.168:3000" location = "source.archipelago-foundation.org"
insecure = true insecure = true
REGCONF REGCONF
then then
@@ -241,7 +241,7 @@ mkdir -p "$OUTPUT_DIR"
container_pull() { container_pull() {
local image="$1" local image="$1"
if [[ "$CONTAINER_CMD" == podman* && "$image" == 146.59.87.168:3000/* ]]; then if [[ "$CONTAINER_CMD" == podman* && "$image" == source.archipelago-foundation.org/* ]]; then
$CONTAINER_CMD pull --tls-verify=false --platform "$CONTAINER_PLATFORM" "$image" $CONTAINER_CMD pull --tls-verify=false --platform "$CONTAINER_PLATFORM" "$image"
else else
$CONTAINER_CMD pull --platform "$CONTAINER_PLATFORM" "$image" $CONTAINER_CMD pull --platform "$CONTAINER_PLATFORM" "$image"
@@ -1317,11 +1317,11 @@ fi
# Extract nostr-rs-relay binary from container image (native system service for VPN signaling) # Extract nostr-rs-relay binary from container image (native system service for VPN signaling)
echo " Extracting nostr-rs-relay binary..." echo " Extracting nostr-rs-relay binary..."
RELAY_IMAGE="$($CONTAINER_CMD images -q 146.59.87.168:3000/lfg2025/nostr-rs-relay:0.9.0 2>/dev/null)" RELAY_IMAGE="$($CONTAINER_CMD images -q source.archipelago-foundation.org/lfg2025/nostr-rs-relay:0.9.0 2>/dev/null)"
if [ -z "$RELAY_IMAGE" ]; then if [ -z "$RELAY_IMAGE" ]; then
$CONTAINER_CMD pull 146.59.87.168:3000/lfg2025/nostr-rs-relay:0.9.0 2>/dev/null || true $CONTAINER_CMD pull source.archipelago-foundation.org/lfg2025/nostr-rs-relay:0.9.0 2>/dev/null || true
fi fi
RELAY_CONTAINER=$($CONTAINER_CMD create 146.59.87.168:3000/lfg2025/nostr-rs-relay:0.9.0 2>/dev/null) || true RELAY_CONTAINER=$($CONTAINER_CMD create source.archipelago-foundation.org/lfg2025/nostr-rs-relay:0.9.0 2>/dev/null) || true
if [ -n "$RELAY_CONTAINER" ]; then if [ -n "$RELAY_CONTAINER" ]; then
# The relay image builds to its WORKDIR /usr/src/app and execs # The relay image builds to its WORKDIR /usr/src/app and execs
# ./nostr-rs-relay from there (not /usr/local/bin — that path was from an # ./nostr-rs-relay from there (not /usr/local/bin — that path was from an
@@ -1346,7 +1346,7 @@ if [ -n "$MISSING_VPN_BINARIES" ]; then
echo " ⚠ Building WITHOUT:$MISSING_VPN_BINARIES (ALLOW_MISSING_VPN_BINARIES=1)" echo " ⚠ Building WITHOUT:$MISSING_VPN_BINARIES (ALLOW_MISSING_VPN_BINARIES=1)"
else else
echo " ❌ Required binaries not extracted:$MISSING_VPN_BINARIES" echo " ❌ Required binaries not extracted:$MISSING_VPN_BINARIES"
echo " The registry (146.59.87.168:3000) must be reachable and hold the images," echo " The registry (source.archipelago-foundation.org) must be reachable and hold the images,"
echo " or set ALLOW_MISSING_VPN_BINARIES=1 to ship without VPN signaling." echo " or set ALLOW_MISSING_VPN_BINARIES=1 to ship without VPN signaling."
exit 1 exit 1
fi fi
@@ -3002,11 +3002,11 @@ cat > /mnt/target/home/archipelago/.config/containers/registries.conf <<'REGCONF
unqualified-search-registries = ["docker.io"] unqualified-search-registries = ["docker.io"]
[[registry]] [[registry]]
location = "146.59.87.168:3000" location = "source.archipelago-foundation.org"
insecure = true insecure = true
[[registry]] [[registry]]
location = "146.59.87.168:3000" location = "source.archipelago-foundation.org"
insecure = true insecure = true
REGCONF REGCONF
chown -R 1000:1000 /mnt/target/home/archipelago/.config chown -R 1000:1000 /mnt/target/home/archipelago/.config
@@ -3016,8 +3016,8 @@ mkdir -p /mnt/target/var/lib/archipelago/config
cat > /mnt/target/var/lib/archipelago/config/registries.json <<'DYNREG' cat > /mnt/target/var/lib/archipelago/config/registries.json <<'DYNREG'
{ {
"registries": [ "registries": [
{"url": "146.59.87.168:3000/lfg2025", "name": "Archipelago Primary", "tls_verify": false, "enabled": true, "priority": 0}, {"url": "source.archipelago-foundation.org/lfg2025", "name": "Archipelago Primary", "tls_verify": false, "enabled": true, "priority": 0},
{"url": "146.59.87.168:3000/lfg2025", "name": "Archipelago Fallback", "tls_verify": true, "enabled": true, "priority": 10} {"url": "source.archipelago-foundation.org/lfg2025", "name": "Archipelago Fallback", "tls_verify": true, "enabled": true, "priority": 10}
] ]
} }
DYNREG DYNREG
@@ -3191,7 +3191,7 @@ if [ -d "$REPO_DIR/.git" ]; then
exit 0 # Already cloned exit 0 # Already cloned
fi fi
echo "[update] Cloning Archipelago repo for self-updates..." echo "[update] Cloning Archipelago repo for self-updates..."
su - archipelago -c "git clone https://146.59.87.168:3000/lfg2025/archy $REPO_DIR" 2>/dev/null || { su - archipelago -c "git clone https://source.archipelago-foundation.org/lfg2025/archy $REPO_DIR" 2>/dev/null || {
echo "[update] Git clone failed (network?). Updates will retry on next boot." echo "[update] Git clone failed (network?). Updates will retry on next boot."
exit 0 exit 0
} }
+2 -2
View File
@@ -40,10 +40,10 @@ EOF
# Configure registries (use Docker Hub and quay.io) # Configure registries (use Docker Hub and quay.io)
mkdir -p /home/archipelago/.config/containers/registries.conf.d mkdir -p /home/archipelago/.config/containers/registries.conf.d
cat > /home/archipelago/.config/containers/registries.conf <<EOF cat > /home/archipelago/.config/containers/registries.conf <<EOF
unqualified-search-registries = ["docker.io", "ghcr.io", "quay.io", "146.59.87.168:3000"] unqualified-search-registries = ["docker.io", "ghcr.io", "quay.io", "source.archipelago-foundation.org"]
[[registry]] [[registry]]
location = "146.59.87.168:3000" location = "source.archipelago-foundation.org"
insecure = true insecure = true
EOF EOF
+23 -23
View File
@@ -1,7 +1,7 @@
{ {
"version": 2, "version": 2,
"updated": "2026-04-22T00:00:00Z", "updated": "2026-04-22T00:00:00Z",
"registry": "146.59.87.168:3000/lfg2025", "registry": "source.archipelago-foundation.org/lfg2025",
"featured": { "featured": {
"id": "indeedhub", "id": "indeedhub",
"banner": "/assets/img/featured/indeedhub-banner.jpg", "banner": "/assets/img/featured/indeedhub-banner.jpg",
@@ -19,7 +19,7 @@
"author": "Bitcoin Knots", "author": "Bitcoin Knots",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/bitcoin-knots:latest", "dockerImage": "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest",
"repoUrl": "https://github.com/bitcoinknots/bitcoin" "repoUrl": "https://github.com/bitcoinknots/bitcoin"
}, },
{ {
@@ -31,7 +31,7 @@
"author": "Bitcoin Core contributors", "author": "Bitcoin Core contributors",
"category": "money", "category": "money",
"tier": "optional", "tier": "optional",
"dockerImage": "146.59.87.168:3000/lfg2025/bitcoin:28.4", "dockerImage": "source.archipelago-foundation.org/lfg2025/bitcoin:28.4",
"repoUrl": "https://github.com/bitcoin/bitcoin" "repoUrl": "https://github.com/bitcoin/bitcoin"
}, },
{ {
@@ -43,7 +43,7 @@
"author": "Lightning Labs", "author": "Lightning Labs",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta", "dockerImage": "source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta",
"repoUrl": "https://github.com/lightningnetwork/lnd", "repoUrl": "https://github.com/lightningnetwork/lnd",
"requires": [ "requires": [
"bitcoin-knots" "bitcoin-knots"
@@ -73,7 +73,7 @@
"author": "Mempool", "author": "Mempool",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/mempool-frontend:v3.0.1", "dockerImage": "source.archipelago-foundation.org/lfg2025/mempool-frontend:v3.0.1",
"repoUrl": "https://github.com/mempool/mempool", "repoUrl": "https://github.com/mempool/mempool",
"requires": [ "requires": [
"bitcoin-knots", "bitcoin-knots",
@@ -89,7 +89,7 @@
"author": "Luke Childs", "author": "Luke Childs",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/electrumx:v1.18.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/electrumx:v1.18.0",
"repoUrl": "https://github.com/spesmilo/electrumx", "repoUrl": "https://github.com/spesmilo/electrumx",
"requires": [ "requires": [
"bitcoin-knots" "bitcoin-knots"
@@ -103,7 +103,7 @@
"icon": "/assets/img/app-icons/indeedhub.png", "icon": "/assets/img/app-icons/indeedhub.png",
"author": "IndeeHub", "author": "IndeeHub",
"category": "community", "category": "community",
"dockerImage": "146.59.87.168:3000/lfg2025/indeedhub:1.0.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/indeedhub:1.0.0",
"repoUrl": "https://github.com/indeedhub/indeedhub" "repoUrl": "https://github.com/indeedhub/indeedhub"
}, },
{ {
@@ -114,7 +114,7 @@
"icon": "/assets/img/app-icons/botfights.svg", "icon": "/assets/img/app-icons/botfights.svg",
"author": "BotFights", "author": "BotFights",
"category": "community", "category": "community",
"dockerImage": "146.59.87.168:3000/lfg2025/botfights:1.2.11", "dockerImage": "source.archipelago-foundation.org/lfg2025/botfights:1.2.11",
"repoUrl": "https://botfights.net", "repoUrl": "https://botfights.net",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -172,7 +172,7 @@
"author": "File Browser", "author": "File Browser",
"category": "data", "category": "data",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/filebrowser:v2.27.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/filebrowser:v2.27.0",
"repoUrl": "https://github.com/filebrowser/filebrowser", "repoUrl": "https://github.com/filebrowser/filebrowser",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -223,7 +223,7 @@
"author": "Vaultwarden", "author": "Vaultwarden",
"category": "data", "category": "data",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/vaultwarden:1.30.0-alpine", "dockerImage": "source.archipelago-foundation.org/lfg2025/vaultwarden:1.30.0-alpine",
"repoUrl": "https://github.com/dani-garcia/vaultwarden", "repoUrl": "https://github.com/dani-garcia/vaultwarden",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -243,7 +243,7 @@
"author": "SearXNG", "author": "SearXNG",
"category": "data", "category": "data",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/searxng:latest", "dockerImage": "source.archipelago-foundation.org/lfg2025/searxng:latest",
"repoUrl": "https://github.com/searxng/searxng", "repoUrl": "https://github.com/searxng/searxng",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -262,7 +262,7 @@
"icon": "/assets/img/app-icons/fedimint.png", "icon": "/assets/img/app-icons/fedimint.png",
"author": "Fedimint", "author": "Fedimint",
"category": "money", "category": "money",
"dockerImage": "146.59.87.168:3000/lfg2025/fedimintd:v0.10.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/fedimintd:v0.10.0",
"repoUrl": "https://github.com/fedimint/fedimint" "repoUrl": "https://github.com/fedimint/fedimint"
}, },
{ {
@@ -274,7 +274,7 @@
"author": "Fedimint", "author": "Fedimint",
"category": "money", "category": "money",
"tier": "core", "tier": "core",
"dockerImage": "146.59.87.168:3000/lfg2025/fmcd:0.8.1", "dockerImage": "source.archipelago-foundation.org/lfg2025/fmcd:0.8.1",
"repoUrl": "https://github.com/minmoto/fmcd" "repoUrl": "https://github.com/minmoto/fmcd"
}, },
{ {
@@ -285,7 +285,7 @@
"icon": "/assets/img/app-icons/fedimint.png", "icon": "/assets/img/app-icons/fedimint.png",
"author": "Fedimint", "author": "Fedimint",
"category": "money", "category": "money",
"dockerImage": "146.59.87.168:3000/lfg2025/gatewayd:v0.10.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/gatewayd:v0.10.0",
"repoUrl": "https://github.com/fedimint/fedimint", "repoUrl": "https://github.com/fedimint/fedimint",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -306,7 +306,7 @@
"icon": "/assets/img/app-icons/bark.png", "icon": "/assets/img/app-icons/bark.png",
"author": "Second", "author": "Second",
"category": "money", "category": "money",
"dockerImage": "146.59.87.168:3000/lfg2025/barkd:0.3.0", "dockerImage": "source.archipelago-foundation.org/lfg2025/barkd:0.3.0",
"repoUrl": "https://gitlab.com/ark-bitcoin/bark", "repoUrl": "https://gitlab.com/ark-bitcoin/bark",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -325,7 +325,7 @@
"icon": "/assets/img/app-icons/jellyfin.webp", "icon": "/assets/img/app-icons/jellyfin.webp",
"author": "Jellyfin", "author": "Jellyfin",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/jellyfin:10.8.13", "dockerImage": "source.archipelago-foundation.org/lfg2025/jellyfin:10.8.13",
"repoUrl": "https://github.com/jellyfin/jellyfin", "repoUrl": "https://github.com/jellyfin/jellyfin",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -345,7 +345,7 @@
"icon": "/assets/img/app-icons/immich.png", "icon": "/assets/img/app-icons/immich.png",
"author": "Immich", "author": "Immich",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/immich-server:release", "dockerImage": "source.archipelago-foundation.org/lfg2025/immich-server:release",
"repoUrl": "https://github.com/immich-app/immich" "repoUrl": "https://github.com/immich-app/immich"
}, },
{ {
@@ -356,7 +356,7 @@
"icon": "/assets/img/app-icons/homeassistant.png", "icon": "/assets/img/app-icons/homeassistant.png",
"author": "Home Assistant", "author": "Home Assistant",
"category": "home", "category": "home",
"dockerImage": "146.59.87.168:3000/lfg2025/home-assistant:2026.7.3", "dockerImage": "source.archipelago-foundation.org/lfg2025/home-assistant:2026.7.3",
"repoUrl": "https://github.com/home-assistant/core", "repoUrl": "https://github.com/home-assistant/core",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -414,7 +414,7 @@
"author": "Tailscale", "author": "Tailscale",
"category": "networking", "category": "networking",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/tailscale:stable", "dockerImage": "source.archipelago-foundation.org/lfg2025/tailscale:stable",
"repoUrl": "https://github.com/tailscale/tailscale", "repoUrl": "https://github.com/tailscale/tailscale",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -442,7 +442,7 @@
"author": "Portainer", "author": "Portainer",
"category": "development", "category": "development",
"tier": "optional", "tier": "optional",
"dockerImage": "146.59.87.168:3000/lfg2025/portainer:2.39.1", "dockerImage": "source.archipelago-foundation.org/lfg2025/portainer:2.39.1",
"repoUrl": "https://github.com/portainer/portainer", "repoUrl": "https://github.com/portainer/portainer",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -487,7 +487,7 @@
"author": "Uptime Kuma", "author": "Uptime Kuma",
"category": "data", "category": "data",
"tier": "recommended", "tier": "recommended",
"dockerImage": "146.59.87.168:3000/lfg2025/uptime-kuma:1", "dockerImage": "source.archipelago-foundation.org/lfg2025/uptime-kuma:1",
"repoUrl": "https://github.com/louislam/uptime-kuma", "repoUrl": "https://github.com/louislam/uptime-kuma",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -514,7 +514,7 @@
"icon": "/assets/img/app-icons/photoprism.svg", "icon": "/assets/img/app-icons/photoprism.svg",
"author": "PhotoPrism", "author": "PhotoPrism",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/photoprism:240915", "dockerImage": "source.archipelago-foundation.org/lfg2025/photoprism:240915",
"repoUrl": "https://github.com/photoprism/photoprism", "repoUrl": "https://github.com/photoprism/photoprism",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
@@ -537,7 +537,7 @@
"icon": "/assets/img/app-icons/nextcloud.webp", "icon": "/assets/img/app-icons/nextcloud.webp",
"author": "Nextcloud", "author": "Nextcloud",
"category": "data", "category": "data",
"dockerImage": "146.59.87.168:3000/lfg2025/nextcloud:29", "dockerImage": "source.archipelago-foundation.org/lfg2025/nextcloud:29",
"repoUrl": "https://github.com/nextcloud/server", "repoUrl": "https://github.com/nextcloud/server",
"containerConfig": { "containerConfig": {
"ports": [ "ports": [
+1 -1
View File
@@ -31,7 +31,7 @@ export const BUNDLED_APPS: BundledApp[] = [
{ {
id: 'bitcoin-knots', id: 'bitcoin-knots',
name: 'Bitcoin Knots', name: 'Bitcoin Knots',
image: '146.59.87.168:3000/lfg2025/bitcoin-knots:latest', image: 'source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest',
description: 'Full Bitcoin node with additional features', description: 'Full Bitcoin node with additional features',
icon: '₿', icon: '₿',
ports: [{ host: 8334, container: 80 }], ports: [{ host: 8334, container: 80 }],
+1 -1
View File
@@ -507,7 +507,7 @@ const features = computed(() => {
}) })
/** App dependency definitions */ /** App dependency definitions */
const R = '146.59.87.168:3000/lfg2025' const R = 'source.archipelago-foundation.org/lfg2025'
const APP_DEPENDENCIES: Record<string, { id: string; title: string; dockerImage: string }[]> = { const APP_DEPENDENCIES: Record<string, { id: string; title: string; dockerImage: string }[]> = {
'electrumx': [{ id: 'bitcoin-knots', title: 'Bitcoin Knots', dockerImage: `${R}/bitcoin-knots:latest` }], 'electrumx': [{ id: 'bitcoin-knots', title: 'Bitcoin Knots', dockerImage: `${R}/bitcoin-knots:latest` }],
'lnd': [{ id: 'bitcoin-knots', title: 'Bitcoin Knots', dockerImage: `${R}/bitcoin-knots:latest` }], 'lnd': [{ id: 'bitcoin-knots', title: 'Bitcoin Knots', dockerImage: `${R}/bitcoin-knots:latest` }],
+1 -1
View File
@@ -1,6 +1,6 @@
import type { MarketplaceApp } from './types' import type { MarketplaceApp } from './types'
const R = '146.59.87.168:3000/lfg2025' const R = 'source.archipelago-foundation.org/lfg2025'
// ---------- Dynamic catalog from registry ---------- // ---------- Dynamic catalog from registry ----------
export interface CatalogFeatured { export interface CatalogFeatured {
@@ -46,7 +46,7 @@ export interface InstallProgress {
} }
/** Archipelago app registry — all app images are mirrored here */ /** Archipelago app registry — all app images are mirrored here */
const REGISTRY = '146.59.87.168:3000/lfg2025' const REGISTRY = 'source.archipelago-foundation.org/lfg2025'
/** Marketplace app ID -> backend package keys (for "Already Installed" when first-boot/deploy created them) */ /** Marketplace app ID -> backend package keys (for "Already Installed" when first-boot/deploy created them) */
export const INSTALLED_ALIASES: Record<string, string[]> = { export const INSTALLED_ALIASES: Record<string, string[]> = {
@@ -390,7 +390,7 @@ export function getCuratedAppList(): MarketplaceApp[] {
description: 'Bitcoin documentary streaming platform with Nostr identity sign-in. Stream God Bless Bitcoin and other educational content about sovereignty and decentralized technology.', description: 'Bitcoin documentary streaming platform with Nostr identity sign-in. Stream God Bless Bitcoin and other educational content about sovereignty and decentralized technology.',
icon: '/assets/img/app-icons/indeedhub.png', icon: '/assets/img/app-icons/indeedhub.png',
author: 'Indeehub Team', author: 'Indeehub Team',
dockerImage: '146.59.87.168:3000/lfg2025/indeedhub:latest', dockerImage: 'source.archipelago-foundation.org/lfg2025/indeedhub:latest',
manifestUrl: undefined, manifestUrl: undefined,
repoUrl: 'https://github.com/indeedhub/indeedhub' repoUrl: 'https://github.com/indeedhub/indeedhub'
}, },
+1 -1
View File
@@ -31,7 +31,7 @@ from pathlib import Path
import yaml import yaml
INSECURE_REGISTRIES = ("146.59.87.168:3000", "23.182.128.160:3000") INSECURE_REGISTRIES = ("source.archipelago-foundation.org", "23.182.128.160:3000")
def run(cmd: list[str], timeout: int = 120) -> subprocess.CompletedProcess[str]: def run(cmd: list[str], timeout: int = 120) -> subprocess.CompletedProcess[str]:
+2 -2
View File
@@ -78,7 +78,7 @@ if $DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -q '^electrumx$'; then
-e "DAEMON_URL=http://${RPC_USER}:${RPC_PASS}@bitcoin-knots:8332/" \ -e "DAEMON_URL=http://${RPC_USER}:${RPC_PASS}@bitcoin-knots:8332/" \
-e COIN=Bitcoin -e DB_DIRECTORY=/data \ -e COIN=Bitcoin -e DB_DIRECTORY=/data \
-e "SERVICES=tcp://:50001,rpc://0.0.0.0:8000" \ -e "SERVICES=tcp://:50001,rpc://0.0.0.0:8000" \
"${ELECTRUMX_IMAGE:-146.59.87.168:3000/lfg2025/electrumx:v1.18.0}" "${ELECTRUMX_IMAGE:-source.archipelago-foundation.org/lfg2025/electrumx:v1.18.0}"
fi fi
# Mempool API # Mempool API
@@ -98,7 +98,7 @@ if $DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -q '^mempool-api$'; th
-e "DATABASE_ENABLED=true" -e "DATABASE_HOST=archy-mempool-db" \ -e "DATABASE_ENABLED=true" -e "DATABASE_HOST=archy-mempool-db" \
-e "DATABASE_DATABASE=mempool" -e "DATABASE_USERNAME=mempool" \ -e "DATABASE_DATABASE=mempool" -e "DATABASE_USERNAME=mempool" \
-e "DATABASE_PASSWORD=$(cat "$SECRETS_DIR/mempool-db-password" 2>/dev/null || echo mempoolpass)" \ -e "DATABASE_PASSWORD=$(cat "$SECRETS_DIR/mempool-db-password" 2>/dev/null || echo mempoolpass)" \
"${MEMPOOL_API_IMAGE:-146.59.87.168:3000/lfg2025/mempool-api:v3.2.0}" "${MEMPOOL_API_IMAGE:-source.archipelago-foundation.org/lfg2025/mempool-api:v3.2.0}"
fi fi
# Stop Tor tunnel if it was active # Stop Tor tunnel if it was active
+1 -1
View File
@@ -18,7 +18,7 @@ RELEASE_DATE=""
OUTPUT_FILE="manifest.json" OUTPUT_FILE="manifest.json"
BACKEND_BINARY="" BACKEND_BINARY=""
FRONTEND_ARCHIVE="" FRONTEND_ARCHIVE=""
BASE_URL="http://146.59.87.168:3000/lfg2025/archy/releases/download" BASE_URL="https://source.archipelago-foundation.org/lfg2025/archy/releases/download"
usage() { usage() {
echo "Usage: $0 --version VERSION [--date DATE] [--output FILE]" echo "Usage: $0 --version VERSION [--date DATE] [--output FILE]"
+1 -1
View File
@@ -293,4 +293,4 @@ echo " 2. Publish commits, tag, artifacts, and verify download URLs:"
echo " scripts/publish-release-assets.sh ${VERSION} gitea-vps2" echo " scripts/publish-release-assets.sh ${VERSION} gitea-vps2"
echo " 3. Verify manifest is live on both mirrors:" echo " 3. Verify manifest is live on both mirrors:"
echo " curl -fsS http://localhost:3000/lfg2025/archy/raw/branch/main/releases/manifest.json" echo " curl -fsS http://localhost:3000/lfg2025/archy/raw/branch/main/releases/manifest.json"
echo " curl -fsS http://146.59.87.168:3000/lfg2025/archy/raw/branch/main/releases/manifest.json" echo " curl -fsS https://source.archipelago-foundation.org/lfg2025/archy/raw/branch/main/releases/manifest.json"
+1 -1
View File
@@ -74,7 +74,7 @@ mkdir -p "$BUILD_DIR"
# Create Dockerfile # Create Dockerfile
cat > "$BUILD_DIR/Dockerfile" << 'EOF' cat > "$BUILD_DIR/Dockerfile" << 'EOF'
FROM ${NGINX_ALPINE_IMAGE:-146.59.87.168:3000/lfg2025/nginx:1.29.6-alpine} FROM ${NGINX_ALPINE_IMAGE:-source.archipelago-foundation.org/lfg2025/nginx:1.29.6-alpine}
# Copy the static UI # Copy the static UI
COPY index.html /usr/share/nginx/html/ COPY index.html /usr/share/nginx/html/
+1 -1
View File
@@ -151,7 +151,7 @@ run_smoke_tests() {
# Test 3: Install a lightweight container (filebrowser — small, fast, no deps) # Test 3: Install a lightweight container (filebrowser — small, fast, no deps)
TESTS=$((TESTS + 1)) TESTS=$((TESTS + 1))
local install_img="146.59.87.168:3000/lfg2025/filebrowser:v2.27.0" local install_img="source.archipelago-foundation.org/lfg2025/filebrowser:v2.27.0"
# Check if already installed # Check if already installed
local fb_state local fb_state
fb_state=$(ssh $SSH_OPTS "$SSH_HOST" "podman inspect filebrowser --format '{{.State.Status}}' 2>/dev/null || echo 'none'") fb_state=$(ssh $SSH_OPTS "$SSH_HOST" "podman inspect filebrowser --format '{{.State.Status}}' 2>/dev/null || echo 'none'")
+1 -1
View File
@@ -9,7 +9,7 @@
# #
# Image versions: sourced from /opt/archipelago/image-versions.sh (single source of truth). # Image versions: sourced from /opt/archipelago/image-versions.sh (single source of truth).
# All container image references use the $*_IMAGE variables defined there. # All container image references use the $*_IMAGE variables defined there.
# Images pull from the Archipelago app registry (146.59.87.168:3000/lfg2025/). # Images pull from the Archipelago app registry (source.archipelago-foundation.org/lfg2025/).
# #
# --- PLANNED REFACTOR (post-beta) --- # --- PLANNED REFACTOR (post-beta) ---
# This script is ~995 lines and should be split into a modular library. # This script is ~995 lines and should be split into a modular library.
+1 -1
View File
@@ -172,7 +172,7 @@ if os.environ.get("EMBED_MANIFESTS") and apps_dir:
# image.sh (Phase 0) publishes more tagged images, e.g.: # image.sh (Phase 0) publishes more tagged images, e.g.:
# {"version": "30.0", "image": f"{REGISTRY}/bitcoin:30.0"}, # {"version": "30.0", "image": f"{REGISTRY}/bitcoin:30.0"},
# {"version": "27.2", "image": f"{REGISTRY}/bitcoin:27.2", "deprecated": True, "eol": "2026-12-31"}, # {"version": "27.2", "image": f"{REGISTRY}/bitcoin:27.2", "deprecated": True, "eol": "2026-12-31"},
REGISTRY = os.environ.get("ARCHY_REGISTRY", "146.59.87.168:3000/lfg2025") REGISTRY = os.environ.get("ARCHY_REGISTRY", "source.archipelago-foundation.org/lfg2025")
VERSIONS = { VERSIONS = {
# Curated Core set (latest patch per major, current → 25). Images built + # Curated Core set (latest patch per major, current → 25). Images built +
# verified (SHA-256 + OpenPGP, fail-closed) and pushed by # verified (SHA-256 + OpenPGP, fail-closed) and pushed by
+3 -3
View File
@@ -5,12 +5,12 @@
# Usage: source /opt/archipelago/image-versions.sh 2>/dev/null || true # Usage: source /opt/archipelago/image-versions.sh 2>/dev/null || true
# source "$(dirname "$0")/image-versions.sh" 2>/dev/null || true # source "$(dirname "$0")/image-versions.sh" 2>/dev/null || true
# #
# Tags MUST match what's actually in the registry at 146.59.87.168:3000/lfg2025/ # Tags MUST match what's actually in the registry at source.archipelago-foundation.org/lfg2025/
# Run: podman images --format '{{.Repository}}:{{.Tag}}' | grep '146.59.87.168:3000' | sort # Run: podman images --format '{{.Repository}}:{{.Tag}}' | grep 'source.archipelago-foundation.org' | sort
# to verify against the registry. # to verify against the registry.
# Archipelago app registries (primary + fallback) # Archipelago app registries (primary + fallback)
ARCHY_REGISTRY="146.59.87.168:3000/lfg2025" ARCHY_REGISTRY="source.archipelago-foundation.org/lfg2025"
# No fallback registry: the old tx1138 registry host was retired (2026-06-13); empty disables the fallback path. # No fallback registry: the old tx1138 registry host was retired (2026-06-13); empty disables the fallback path.
ARCHY_REGISTRY_FALLBACK="" ARCHY_REGISTRY_FALLBACK=""
+3 -3
View File
@@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# Self-update: pull latest code from the OVH Gitea (146.59.87.168:3000) and apply # Self-update: pull latest code from the OVH Gitea (source.archipelago-foundation.org) and apply
# Designed to run on installed Archipelago nodes (as archipelago user) # Designed to run on installed Archipelago nodes (as archipelago user)
# #
# Usage: # Usage:
@@ -8,7 +8,7 @@
# ./self-update.sh --force # Apply even if already up to date # ./self-update.sh --force # Apply even if already up to date
# #
# The script: # The script:
# 1. Pulls latest code from origin (146.59.87.168:3000) # 1. Pulls latest code from origin (source.archipelago-foundation.org)
# 2. Builds the Rust backend (release mode) # 2. Builds the Rust backend (release mode)
# 3. Builds the Vue frontend (production mode) # 3. Builds the Vue frontend (production mode)
# 4. Installs the new binary and web UI # 4. Installs the new binary and web UI
@@ -69,7 +69,7 @@ done
# Ensure repo exists # Ensure repo exists
if [ ! -d "$REPO_DIR/.git" ]; then if [ ! -d "$REPO_DIR/.git" ]; then
err "Repo not found at $REPO_DIR" err "Repo not found at $REPO_DIR"
err "Clone it first: git clone http://146.59.87.168:3000/lfg2025/archy ~/archy" err "Clone it first: git clone https://source.archipelago-foundation.org/lfg2025/archy ~/archy"
exit 1 exit 1
fi fi
+1 -1
View File
@@ -137,7 +137,7 @@ fi
if [[ -n "$IMAGE" ]]; then if [[ -n "$IMAGE" ]]; then
TRUSTED=false TRUSTED=false
for reg in "docker.io" "ghcr.io" "quay.io" "registry.hub.docker.com" "146.59.87.168:3000" "localhost/"; do for reg in "docker.io" "ghcr.io" "quay.io" "registry.hub.docker.com" "source.archipelago-foundation.org" "localhost/"; do
if [[ "$IMAGE" == *"$reg"* ]]; then if [[ "$IMAGE" == *"$reg"* ]]; then
TRUSTED=true TRUSTED=true
break break
+1 -1
View File
@@ -15,7 +15,7 @@
load '../lib/rpc.bash' load '../lib/rpc.bash'
IMMICH_IMAGE="146.59.87.168:3000/lfg2025/immich-server:release" IMMICH_IMAGE="source.archipelago-foundation.org/lfg2025/immich-server:release"
setup_file() { setup_file() {
: "${ARCHY_PASSWORD:?Set ARCHY_PASSWORD env var to the UI password}" : "${ARCHY_PASSWORD:?Set ARCHY_PASSWORD env var to the UI password}"
+21 -21
View File
@@ -133,29 +133,29 @@ is_pruned_node() {
image_for() { image_for() {
case "$1" in case "$1" in
bitcoin-knots) echo "146.59.87.168:3000/lfg2025/bitcoin-knots:latest" ;; bitcoin-knots) echo "source.archipelago-foundation.org/lfg2025/bitcoin-knots:latest" ;;
bitcoin-core) echo "docker.io/bitcoin/bitcoin:28.4" ;; bitcoin-core) echo "docker.io/bitcoin/bitcoin:28.4" ;;
btcpay-server) echo "docker.io/btcpayserver/btcpayserver:2.3.9" ;; btcpay-server) echo "docker.io/btcpayserver/btcpayserver:2.3.9" ;;
lnd) echo "146.59.87.168:3000/lfg2025/lnd:v0.18.4-beta" ;; lnd) echo "source.archipelago-foundation.org/lfg2025/lnd:v0.18.4-beta" ;;
mempool) echo "146.59.87.168:3000/lfg2025/mempool-frontend:v3.0.0" ;; mempool) echo "source.archipelago-foundation.org/lfg2025/mempool-frontend:v3.0.0" ;;
homeassistant) echo "146.59.87.168:3000/lfg2025/home-assistant:2024.1" ;; homeassistant) echo "source.archipelago-foundation.org/lfg2025/home-assistant:2024.1" ;;
grafana) echo "146.59.87.168:3000/lfg2025/grafana:10.2.0" ;; grafana) echo "source.archipelago-foundation.org/lfg2025/grafana:10.2.0" ;;
searxng) echo "146.59.87.168:3000/lfg2025/searxng:latest" ;; searxng) echo "source.archipelago-foundation.org/lfg2025/searxng:latest" ;;
ollama) echo "146.59.87.168:3000/lfg2025/ollama:latest" ;; ollama) echo "source.archipelago-foundation.org/lfg2025/ollama:latest" ;;
nextcloud) echo "146.59.87.168:3000/lfg2025/nextcloud:28" ;; nextcloud) echo "source.archipelago-foundation.org/lfg2025/nextcloud:28" ;;
vaultwarden) echo "146.59.87.168:3000/lfg2025/vaultwarden:1.30.0-alpine" ;; vaultwarden) echo "source.archipelago-foundation.org/lfg2025/vaultwarden:1.30.0-alpine" ;;
jellyfin) echo "146.59.87.168:3000/lfg2025/jellyfin:10.8.13" ;; jellyfin) echo "source.archipelago-foundation.org/lfg2025/jellyfin:10.8.13" ;;
photoprism) echo "146.59.87.168:3000/lfg2025/photoprism:240915" ;; photoprism) echo "source.archipelago-foundation.org/lfg2025/photoprism:240915" ;;
immich) echo "146.59.87.168:3000/lfg2025/immich-server:release" ;; immich) echo "source.archipelago-foundation.org/lfg2025/immich-server:release" ;;
filebrowser) echo "146.59.87.168:3000/lfg2025/filebrowser:v2.27.0" ;; filebrowser) echo "source.archipelago-foundation.org/lfg2025/filebrowser:v2.27.0" ;;
nginx-proxy-manager) echo "146.59.87.168:3000/lfg2025/nginx-proxy-manager:latest" ;; nginx-proxy-manager) echo "source.archipelago-foundation.org/lfg2025/nginx-proxy-manager:latest" ;;
portainer) echo "146.59.87.168:3000/lfg2025/portainer:latest" ;; portainer) echo "source.archipelago-foundation.org/lfg2025/portainer:latest" ;;
uptime-kuma) echo "146.59.87.168:3000/lfg2025/uptime-kuma:1" ;; uptime-kuma) echo "source.archipelago-foundation.org/lfg2025/uptime-kuma:1" ;;
tailscale) echo "146.59.87.168:3000/lfg2025/tailscale:stable" ;; tailscale) echo "source.archipelago-foundation.org/lfg2025/tailscale:stable" ;;
electrumx) echo "146.59.87.168:3000/lfg2025/electrumx:v1.18.0" ;; electrumx) echo "source.archipelago-foundation.org/lfg2025/electrumx:v1.18.0" ;;
fedimint) echo "146.59.87.168:3000/lfg2025/fedimintd:v0.10.0" ;; fedimint) echo "source.archipelago-foundation.org/lfg2025/fedimintd:v0.10.0" ;;
indeedhub) echo "146.59.87.168:3000/lfg2025/indeedhub:1.0.0" ;; indeedhub) echo "source.archipelago-foundation.org/lfg2025/indeedhub:1.0.0" ;;
botfights) echo "146.59.87.168:3000/lfg2025/botfights:1.1.0" ;; botfights) echo "source.archipelago-foundation.org/lfg2025/botfights:1.1.0" ;;
gitea) echo "docker.io/gitea/gitea:1.23" ;; gitea) echo "docker.io/gitea/gitea:1.23" ;;
*) return 1 ;; *) return 1 ;;
esac esac