feat: migrate all container images to Archipelago app registry

All container image references now pull from 80.71.235.15:3000/archipelago/
instead of Docker Hub and ghcr.io. image-versions.sh is the single source
of truth; all scripts use $*_IMAGE variables instead of hardcoded refs.

Files updated:
- scripts/image-versions.sh: central ARCHY_REGISTRY variable
- core/*/config.rs: registry whitelist includes app registry
- core/*/stacks.rs: Immich + Penpot stack images
- scripts/{first-boot,deploy-to-target,container-specs}.sh: use variables
- docker/*/Dockerfile: nginx base image from registry
- image-recipe/: ISO build, podman config, menu script
- scripts/{container-doctor,deploy-bitcoin-knots,fix-indeedhub,validate-app-manifest}.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian 2026-03-26 14:06:21 +00:00
parent 18cd0cf387
commit 35c8420095
16 changed files with 196 additions and 220 deletions

View File

@ -4,7 +4,7 @@ use anyhow::{Context, Result};
/// Trusted Docker registries. Only images from these sources are allowed.
#[allow(dead_code)]
pub(super) const TRUSTED_REGISTRIES: &[&str] = &["docker.io/", "ghcr.io/", "localhost/"];
pub(super) const TRUSTED_REGISTRIES: &[&str] = &["docker.io/", "ghcr.io/", "localhost/", "80.71.235.15:3000/"];
/// Detect which Bitcoin container is running on archy-net for DNS resolution.
/// Returns the container name to use as the RPC host (e.g., "bitcoin-knots").
@ -40,7 +40,7 @@ pub(super) fn is_valid_docker_image(image: &str) -> bool {
Some(r) => r,
None => return false,
};
matches!(registry, "docker.io" | "ghcr.io" | "localhost")
matches!(registry, "docker.io" | "ghcr.io" | "localhost" | "80.71.235.15:3000")
}
/// Per-app Linux capabilities needed beyond the default cap-drop=ALL.

View File

@ -33,9 +33,9 @@ impl RpcHandler {
}
let images = [
"ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0",
"docker.io/valkey/valkey:7-alpine",
"ghcr.io/immich-app/immich-server:release",
"80.71.235.15:3000/archipelago/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0",
"80.71.235.15:3000/archipelago/valkey:7-alpine",
"80.71.235.15:3000/archipelago/immich-server:release",
];
for img in &images {
let _ = tokio::process::Command::new("podman")
@ -76,7 +76,7 @@ impl RpcHandler {
"POSTGRES_USER=postgres",
"-e",
"POSTGRES_DB=immich",
"ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0",
"80.71.235.15:3000/archipelago/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0",
])
.output()
.await;
@ -92,7 +92,7 @@ impl RpcHandler {
"unless-stopped",
"--network",
"immich-net",
"docker.io/valkey/valkey:7-alpine",
"80.71.235.15:3000/archipelago/valkey:7-alpine",
])
.output()
.await;
@ -124,7 +124,7 @@ impl RpcHandler {
"REDIS_HOSTNAME=immich_redis",
"-e",
"UPLOAD_LOCATION=/usr/src/app/upload",
"ghcr.io/immich-app/immich-server:release",
"80.71.235.15:3000/archipelago/immich-server:release",
])
.output()
.await
@ -161,11 +161,11 @@ impl RpcHandler {
}
let images = [
"docker.io/postgres:15",
"docker.io/valkey/valkey:8.1",
"docker.io/penpotapp/backend:2.4",
"docker.io/penpotapp/exporter:2.4",
"docker.io/penpotapp/frontend:2.4",
"80.71.235.15:3000/archipelago/postgres:15",
"80.71.235.15:3000/archipelago/valkey:8.1",
"80.71.235.15:3000/archipelago/penpot-backend:2.4",
"80.71.235.15:3000/archipelago/penpot-exporter:2.4",
"80.71.235.15:3000/archipelago/penpot-frontend:2.4",
];
for img in &images {
let _ = tokio::process::Command::new("podman")
@ -211,7 +211,7 @@ impl RpcHandler {
"POSTGRES_USER=penpot",
"-e",
"POSTGRES_PASSWORD=penpot",
"docker.io/postgres:15",
"80.71.235.15:3000/archipelago/postgres:15",
])
.output()
.await;
@ -229,7 +229,7 @@ impl RpcHandler {
"penpot-net",
"-e",
"VALKEY_EXTRA_FLAGS=--maxmemory 128mb --maxmemory-policy volatile-lfu",
"docker.io/valkey/valkey:8.1",
"80.71.235.15:3000/archipelago/valkey:8.1",
])
.output()
.await;
@ -265,7 +265,7 @@ impl RpcHandler {
"PENPOT_OBJECTS_STORAGE_FS_DIRECTORY=/opt/data/assets",
"-e",
"PENPOT_FLAGS=disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies",
"docker.io/penpotapp/backend:2.4",
"80.71.235.15:3000/archipelago/penpot-backend:2.4",
])
.output()
.await;
@ -287,7 +287,7 @@ impl RpcHandler {
"PENPOT_PUBLIC_URI=http://penpot-frontend:8080",
"-e",
"PENPOT_REDIS_URI=redis://penpot-valkey/0",
"docker.io/penpotapp/exporter:2.4",
"80.71.235.15:3000/archipelago/penpot-exporter:2.4",
])
.output()
.await;
@ -311,7 +311,7 @@ impl RpcHandler {
&format!("PENPOT_PUBLIC_URI=http://{}:9001", host_ip),
"-e",
"PENPOT_FLAGS=disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies",
"docker.io/penpotapp/frontend:2.4",
"80.71.235.15:3000/archipelago/penpot-frontend:2.4",
])
.output()
.await

View File

@ -1,4 +1,4 @@
FROM docker.io/library/nginx:alpine
FROM 80.71.235.15:3000/archipelago/nginx:1.29.6-alpine
COPY index.html /usr/share/nginx/html/
COPY 50x.html /usr/share/nginx/html/
COPY assets/ /usr/share/nginx/html/assets/

View File

@ -1,4 +1,4 @@
FROM docker.io/library/nginx:alpine
FROM 80.71.235.15:3000/archipelago/nginx:1.29.6-alpine
COPY index.html /usr/share/nginx/html/
COPY 50x.html /usr/share/nginx/html/
COPY assets/ /usr/share/nginx/html/assets/

View File

@ -1,4 +1,4 @@
FROM docker.io/library/nginx:alpine
FROM 80.71.235.15:3000/archipelago/nginx:1.29.6-alpine
# Copy the HTML file
COPY index.html /usr/share/nginx/html/

View File

@ -240,7 +240,7 @@ setup_btcpay() {
echo ""
echo " 🐳 Pulling BTCPay Server image..."
podman pull "${BTCPAY_IMAGE:-docker.io/btcpayserver/btcpayserver:1.14.5}"
podman pull "${BTCPAY_IMAGE}"
# Create data directory
mkdir -p ~/.btcpay

View File

@ -620,7 +620,7 @@ if [ "$UNBUNDLED" = "1" ]; then
IMAGES_DIR="$ARCH_DIR/container-images"
mkdir -p "$IMAGES_DIR"
# FileBrowser is a core dependency (powers the Cloud file manager) — always bundle it
CORE_IMAGE="${FILEBROWSER_IMAGE:-docker.io/filebrowser/filebrowser:v2}"
CORE_IMAGE="${FILEBROWSER_IMAGE}"
CORE_FILE="filebrowser.tar"
if [ -f "$IMAGES_DIR/$CORE_FILE" ]; then
echo " ✅ Using cached: $CORE_FILE"
@ -665,34 +665,34 @@ fi
# bitcoin-ui and lnd-ui are custom and normally captured from server or built separately.
# Alpha: core Bitcoin/Lightning stack + essential apps. Others pulled on-demand from Marketplace.
CONTAINER_IMAGES="
${BITCOIN_KNOTS_IMAGE:-docker.io/bitcoinknots/bitcoin:28.1} bitcoin-knots.tar
${LND_IMAGE:-docker.io/lightninglabs/lnd:v0.18.5-beta} lnd.tar
${HOMEASSISTANT_IMAGE:-ghcr.io/home-assistant/home-assistant:2024.12} homeassistant.tar
${BTCPAY_IMAGE:-docker.io/btcpayserver/btcpayserver:1.13.7} btcpayserver.tar
${NBXPLORER_IMAGE:-docker.io/nicolasdorier/nbxplorer:2.5.13} nbxplorer.tar
${POSTGRES_IMAGE:-docker.io/library/postgres:16} postgres-btcpay.tar
${MEMPOOL_BACKEND_IMAGE:-docker.io/mempool/backend:v3.0.0} mempool-backend.tar
${MEMPOOL_WEB_IMAGE:-docker.io/mempool/frontend:v3.0.0} mempool-frontend.tar
${ELECTRUMX_IMAGE:-docker.io/lukechilds/electrumx:v1.16.0} electrumx.tar
${MARIADB_IMAGE:-docker.io/library/mariadb:11.4} mariadb-mempool.tar
${FEDIMINT_IMAGE:-docker.io/fedimint/fedimintd:v0.5.1} fedimint.tar
${FEDIMINT_GATEWAY_IMAGE:-docker.io/fedimint/gatewayd:v0.5.1} fedimint-gateway.tar
${FILEBROWSER_IMAGE:-docker.io/filebrowser/filebrowser:v2} filebrowser.tar
${ALPINE_TOR_IMAGE:-docker.io/andrius/alpine-tor:0.4.8.13} alpine-tor.tar
${NGINX_ALPINE_IMAGE:-docker.io/library/nginx:alpine} nginx-alpine.tar
${DWN_SERVER_IMAGE:-ghcr.io/tbd54566975/dwn-server:main} dwn-server.tar
${GRAFANA_IMAGE:-docker.io/grafana/grafana:11.4.0} grafana.tar
${UPTIME_KUMA_IMAGE:-docker.io/louislam/uptime-kuma:1} uptime-kuma.tar
${VAULTWARDEN_IMAGE:-docker.io/vaultwarden/server:1.32.5} vaultwarden.tar
${SEARXNG_IMAGE:-docker.io/searxng/searxng:2026.3.20-6c7e9c197} searxng.tar
${PORTAINER_IMAGE:-docker.io/portainer/portainer-ce:2.21.5} portainer.tar
${TAILSCALE_IMAGE:-docker.io/tailscale/tailscale:v1.78.3} tailscale.tar
${JELLYFIN_IMAGE:-docker.io/jellyfin/jellyfin:10.10.3} jellyfin.tar
${PHOTOPRISM_IMAGE:-docker.io/photoprism/photoprism:240915} photoprism.tar
${NEXTCLOUD_IMAGE:-docker.io/library/nextcloud:30} nextcloud.tar
${NPM_IMAGE:-docker.io/jc21/nginx-proxy-manager:2} nginx-proxy-manager.tar
${ONLYOFFICE_IMAGE:-docker.io/onlyoffice/documentserver:8.2} onlyoffice.tar
${ADGUARDHOME_IMAGE:-docker.io/adguard/adguardhome:v0.107.55} adguardhome.tar
${BITCOIN_KNOTS_IMAGE} bitcoin-knots.tar
${LND_IMAGE} lnd.tar
${HOMEASSISTANT_IMAGE} homeassistant.tar
${BTCPAY_IMAGE} btcpayserver.tar
${NBXPLORER_IMAGE} nbxplorer.tar
${POSTGRES_IMAGE} postgres-btcpay.tar
${MEMPOOL_BACKEND_IMAGE} mempool-backend.tar
${MEMPOOL_WEB_IMAGE} mempool-frontend.tar
${ELECTRUMX_IMAGE} electrumx.tar
${MARIADB_IMAGE} mariadb-mempool.tar
${FEDIMINT_IMAGE} fedimint.tar
${FEDIMINT_GATEWAY_IMAGE} fedimint-gateway.tar
${FILEBROWSER_IMAGE} filebrowser.tar
${ALPINE_TOR_IMAGE} alpine-tor.tar
${NGINX_ALPINE_IMAGE} nginx-alpine.tar
${DWN_SERVER_IMAGE} dwn-server.tar
${GRAFANA_IMAGE} grafana.tar
${UPTIME_KUMA_IMAGE} uptime-kuma.tar
${VAULTWARDEN_IMAGE} vaultwarden.tar
${SEARXNG_IMAGE} searxng.tar
${PORTAINER_IMAGE} portainer.tar
${TAILSCALE_IMAGE} tailscale.tar
${JELLYFIN_IMAGE} jellyfin.tar
${PHOTOPRISM_IMAGE} photoprism.tar
${NEXTCLOUD_IMAGE} nextcloud.tar
${NPM_IMAGE} nginx-proxy-manager.tar
${ONLYOFFICE_IMAGE} onlyoffice.tar
${ADGUARDHOME_IMAGE} adguardhome.tar
"
# Pull and save each image (force target arch) only if not already present
@ -871,7 +871,7 @@ else
sudo $DOCKER run -d --name archy-tor --restart unless-stopped --network host \
-v "$TOR_DIR:$TOR_DIR" \
--entrypoint tor \
${ALPINE_TOR_IMAGE:-docker.io/andrius/alpine-tor:0.4.8.13} \
${ALPINE_TOR_IMAGE} \
-f /etc/tor/torrc >> "$LOG" 2>&1
echo "$(date): Tor container started" >> "$LOG"
fi
@ -922,7 +922,7 @@ if ! $DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -q filebrowser; then
--memory=256m \
-p 8083:80 \
-v /var/lib/archipelago/filebrowser:/srv \
docker.io/filebrowser/filebrowser:v2 2>>"$LOG" && \
"$FILEBROWSER_IMAGE" 2>>"$LOG" && \
echo "[$(date)] FileBrowser created successfully" >> "$LOG" || \
echo "[$(date)] WARNING: FileBrowser creation failed" >> "$LOG"
fi

View File

@ -28,10 +28,10 @@ EOF
mkdir -p /home/archipelago/.config/containers/registries.conf.d
cat > /home/archipelago/.config/containers/registries.conf.d/000-shortnames.conf <<EOF
[registries.search]
registries = ['docker.io', 'quay.io', 'ghcr.io']
registries = ['80.71.235.15:3000', 'docker.io', 'quay.io', 'ghcr.io']
[registries.insecure]
registries = []
registries = ['80.71.235.15:3000']
[registries.block]
registries = []

View File

@ -198,7 +198,7 @@ fix_searxng() {
-v searxng-cache:/var/cache/searxng:rw \
-p "${host_port}:8080" \
--memory=512m \
"${SEARXNG_IMAGE:-docker.io/searxng/searxng:2024.11.17}" 2>&1 || true
"${SEARXNG_IMAGE}" 2>&1 || true
log "SearXNG recreated (no readonly, no cap-drop ALL)"
return 0

View File

@ -82,7 +82,7 @@ reset_spec() {
load_spec_archy-mempool-db() {
reset_spec
SPEC_NAME="archy-mempool-db"
SPEC_IMAGE="${MARIADB_IMAGE:-docker.io/library/mariadb:11.4}"
SPEC_IMAGE="${MARIADB_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_MEMORY="$(mem_limit archy-mempool-db)"
SPEC_VOLUMES="/var/lib/archipelago/mysql-mempool:/var/lib/mysql"
@ -97,7 +97,7 @@ load_spec_archy-mempool-db() {
load_spec_archy-btcpay-db() {
reset_spec
SPEC_NAME="archy-btcpay-db"
SPEC_IMAGE="${BTCPAY_POSTGRES_IMAGE:-docker.io/library/postgres:15}"
SPEC_IMAGE="${BTCPAY_POSTGRES_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_MEMORY="$(mem_limit archy-btcpay-db)"
SPEC_VOLUMES="/var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data"
@ -112,7 +112,7 @@ load_spec_archy-btcpay-db() {
load_spec_immich_postgres() {
reset_spec
SPEC_NAME="immich_postgres"
SPEC_IMAGE="ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0"
SPEC_IMAGE="${IMMICH_POSTGRES_IMAGE}"
SPEC_NETWORK="bridge"
SPEC_MEMORY="$(mem_limit immich_postgres)"
SPEC_VOLUMES="/var/lib/archipelago/immich-db:/var/lib/postgresql/data"
@ -127,7 +127,7 @@ load_spec_immich_postgres() {
load_spec_immich_redis() {
reset_spec
SPEC_NAME="immich_redis"
SPEC_IMAGE="${VALKEY_IMAGE:-docker.io/valkey/valkey:8}"
SPEC_IMAGE="${VALKEY_IMAGE}"
SPEC_NETWORK="bridge"
SPEC_MEMORY="$(mem_limit immich_redis)"
SPEC_TIER="0"
@ -140,7 +140,7 @@ load_spec_immich_redis() {
load_spec_bitcoin-knots() {
reset_spec
SPEC_NAME="bitcoin-knots"
SPEC_IMAGE="${BITCOIN_KNOTS_IMAGE:-docker.io/bitcoinknots/bitcoin:28.1}"
SPEC_IMAGE="${BITCOIN_KNOTS_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="8332:8332 8333:8333"
SPEC_VOLUMES="/var/lib/archipelago/bitcoin:/home/bitcoin/.bitcoin"
@ -160,7 +160,7 @@ load_spec_bitcoin-knots() {
load_spec_electrumx() {
reset_spec
SPEC_NAME="electrumx"
SPEC_IMAGE="docker.io/lukechilds/electrumx:v1.16.0"
SPEC_IMAGE="${ELECTRUMX_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="50001:50001"
SPEC_VOLUMES="/var/lib/archipelago/electrumx:/data"
@ -178,7 +178,7 @@ load_spec_electrumx() {
load_spec_lnd() {
reset_spec
SPEC_NAME="lnd"
SPEC_IMAGE="${LND_IMAGE:-docker.io/lightninglabs/lnd:v0.18.5-beta}"
SPEC_IMAGE="${LND_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="9735:9735 10009:10009 8080:8080"
SPEC_VOLUMES="/var/lib/archipelago/lnd:/root/.lnd"
@ -192,7 +192,7 @@ load_spec_lnd() {
load_spec_mempool-api() {
reset_spec
SPEC_NAME="mempool-api"
SPEC_IMAGE="${MEMPOOL_BACKEND_IMAGE:-docker.io/mempool/backend:v3.0.0}"
SPEC_IMAGE="${MEMPOOL_BACKEND_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="8999:8999"
SPEC_VOLUMES="/var/lib/archipelago/mempool:/data"
@ -209,7 +209,7 @@ load_spec_mempool-api() {
load_spec_archy-mempool-web() {
reset_spec
SPEC_NAME="archy-mempool-web"
SPEC_IMAGE="${MEMPOOL_WEB_IMAGE:-docker.io/mempool/frontend:v3.0.0}"
SPEC_IMAGE="${MEMPOOL_WEB_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="4080:8080"
SPEC_MEMORY="$(mem_limit archy-mempool-web)"
@ -223,7 +223,7 @@ load_spec_archy-mempool-web() {
load_spec_archy-nbxplorer() {
reset_spec
SPEC_NAME="archy-nbxplorer"
SPEC_IMAGE="${NBXPLORER_IMAGE:-docker.io/nicolasdorier/nbxplorer:2.5.13}"
SPEC_IMAGE="${NBXPLORER_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="32838:32838"
SPEC_VOLUMES="/var/lib/archipelago/nbxplorer:/data"
@ -239,7 +239,7 @@ load_spec_archy-nbxplorer() {
load_spec_btcpay-server() {
reset_spec
SPEC_NAME="btcpay-server"
SPEC_IMAGE="${BTCPAY_IMAGE:-docker.io/btcpayserver/btcpayserver:1.13.7}"
SPEC_IMAGE="${BTCPAY_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="23000:49392"
SPEC_VOLUMES="/var/lib/archipelago/btcpay:/datadir"
@ -254,7 +254,7 @@ load_spec_btcpay-server() {
load_spec_fedimint() {
reset_spec
SPEC_NAME="fedimint"
SPEC_IMAGE="${FEDIMINT_IMAGE:-docker.io/fedimint/fedimintd:v0.5.1}"
SPEC_IMAGE="${FEDIMINT_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="8173:8173 8174:8174 8175:8175"
SPEC_VOLUMES="/var/lib/archipelago/fedimint:/data"
@ -269,7 +269,7 @@ load_spec_fedimint() {
load_spec_fedimint-gateway() {
reset_spec
SPEC_NAME="fedimint-gateway"
SPEC_IMAGE="${FEDIMINT_GATEWAY_IMAGE:-docker.io/fedimint/gatewayd:v0.5.1}"
SPEC_IMAGE="${FEDIMINT_GATEWAY_IMAGE}"
SPEC_NETWORK="archy-net"
SPEC_PORTS="8176:8176"
SPEC_VOLUMES="/var/lib/archipelago/fedimint-gateway:/data"
@ -293,7 +293,7 @@ load_spec_fedimint-gateway() {
load_spec_immich_server() {
reset_spec
SPEC_NAME="immich_server"
SPEC_IMAGE="ghcr.io/immich-app/immich-server:release"
SPEC_IMAGE="${IMMICH_SERVER_IMAGE}"
SPEC_NETWORK="bridge"
SPEC_PORTS="2283:2283"
SPEC_VOLUMES="/var/lib/archipelago/immich:/usr/src/app/upload"
@ -311,7 +311,7 @@ load_spec_immich_server() {
load_spec_homeassistant() {
reset_spec
SPEC_NAME="homeassistant"
SPEC_IMAGE="${HOMEASSISTANT_IMAGE:-ghcr.io/home-assistant/home-assistant:2024.12}"
SPEC_IMAGE="${HOMEASSISTANT_IMAGE}"
SPEC_PORTS="8123:8123"
SPEC_VOLUMES="/var/lib/archipelago/home-assistant:/config"
SPEC_MEMORY="$(mem_limit homeassistant)"
@ -325,7 +325,7 @@ load_spec_homeassistant() {
load_spec_grafana() {
reset_spec
SPEC_NAME="grafana"
SPEC_IMAGE="${GRAFANA_IMAGE:-docker.io/grafana/grafana:11.4.0}"
SPEC_IMAGE="${GRAFANA_IMAGE}"
SPEC_PORTS="3000:3000"
SPEC_VOLUMES="/var/lib/archipelago/grafana:/var/lib/grafana"
SPEC_MEMORY="$(mem_limit grafana)"
@ -342,7 +342,7 @@ load_spec_grafana() {
load_spec_uptime-kuma() {
reset_spec
SPEC_NAME="uptime-kuma"
SPEC_IMAGE="${UPTIME_KUMA_IMAGE:-docker.io/louislam/uptime-kuma:1}"
SPEC_IMAGE="${UPTIME_KUMA_IMAGE}"
SPEC_PORTS="3001:3001"
SPEC_VOLUMES="/var/lib/archipelago/uptime-kuma:/app/data"
SPEC_MEMORY="$(mem_limit uptime-kuma)"
@ -356,7 +356,7 @@ load_spec_uptime-kuma() {
load_spec_jellyfin() {
reset_spec
SPEC_NAME="jellyfin"
SPEC_IMAGE="${JELLYFIN_IMAGE:-docker.io/jellyfin/jellyfin:10.10.3}"
SPEC_IMAGE="${JELLYFIN_IMAGE}"
SPEC_PORTS="8096:8096"
SPEC_VOLUMES="/var/lib/archipelago/jellyfin/config:/config /var/lib/archipelago/jellyfin/cache:/cache"
SPEC_MEMORY="$(mem_limit jellyfin)"
@ -369,7 +369,7 @@ load_spec_jellyfin() {
load_spec_photoprism() {
reset_spec
SPEC_NAME="photoprism"
SPEC_IMAGE="${PHOTOPRISM_IMAGE:-docker.io/photoprism/photoprism:240915}"
SPEC_IMAGE="${PHOTOPRISM_IMAGE}"
SPEC_PORTS="2342:2342"
SPEC_VOLUMES="/var/lib/archipelago/photoprism:/photoprism/storage"
SPEC_MEMORY="$(mem_limit photoprism)"
@ -383,7 +383,7 @@ load_spec_photoprism() {
load_spec_vaultwarden() {
reset_spec
SPEC_NAME="vaultwarden"
SPEC_IMAGE="${VAULTWARDEN_IMAGE:-docker.io/vaultwarden/server:1.32.5}"
SPEC_IMAGE="${VAULTWARDEN_IMAGE}"
SPEC_PORTS="8082:80"
SPEC_VOLUMES="/var/lib/archipelago/vaultwarden:/data"
SPEC_MEMORY="$(mem_limit vaultwarden)"
@ -396,7 +396,7 @@ load_spec_vaultwarden() {
load_spec_nextcloud() {
reset_spec
SPEC_NAME="nextcloud"
SPEC_IMAGE="${NEXTCLOUD_IMAGE:-docker.io/library/nextcloud:29}"
SPEC_IMAGE="${NEXTCLOUD_IMAGE}"
SPEC_PORTS="8085:80"
SPEC_VOLUMES="/var/lib/archipelago/nextcloud:/var/www/html"
SPEC_MEMORY="$(mem_limit nextcloud)"
@ -409,7 +409,7 @@ load_spec_nextcloud() {
load_spec_searxng() {
reset_spec
SPEC_NAME="searxng"
SPEC_IMAGE="${SEARXNG_IMAGE:-docker.io/searxng/searxng:2026.3.20-6c7e9c197}"
SPEC_IMAGE="${SEARXNG_IMAGE}"
SPEC_PORTS="8888:8080"
SPEC_MEMORY="$(mem_limit searxng)"
SPEC_HEALTH_CMD="curl -sf http://localhost:8080/ || exit 1"
@ -422,7 +422,7 @@ load_spec_searxng() {
load_spec_onlyoffice() {
reset_spec
SPEC_NAME="onlyoffice"
SPEC_IMAGE="${ONLYOFFICE_IMAGE:-docker.io/onlyoffice/documentserver:8.2}"
SPEC_IMAGE="${ONLYOFFICE_IMAGE}"
SPEC_PORTS="9980:80"
SPEC_MEMORY="$(mem_limit onlyoffice)"
SPEC_HEALTH_CMD="curl -sf http://localhost:80/ || exit 1"
@ -433,7 +433,7 @@ load_spec_onlyoffice() {
load_spec_filebrowser() {
reset_spec
SPEC_NAME="filebrowser"
SPEC_IMAGE="${FILEBROWSER_IMAGE:-docker.io/filebrowser/filebrowser:v2}"
SPEC_IMAGE="${FILEBROWSER_IMAGE}"
SPEC_PORTS="8083:80"
SPEC_VOLUMES="/var/lib/archipelago/filebrowser:/srv"
SPEC_MEMORY="$(mem_limit filebrowser)"
@ -446,7 +446,7 @@ load_spec_filebrowser() {
load_spec_nginx-proxy-manager() {
reset_spec
SPEC_NAME="nginx-proxy-manager"
SPEC_IMAGE="${NPM_IMAGE:-docker.io/jc21/nginx-proxy-manager:2}"
SPEC_IMAGE="${NPM_IMAGE}"
SPEC_PORTS="81:81 8084:80 8443:443"
SPEC_VOLUMES="/var/lib/archipelago/nginx-proxy-manager/data:/data /var/lib/archipelago/nginx-proxy-manager/letsencrypt:/etc/letsencrypt"
SPEC_MEMORY="$(mem_limit nginx-proxy-manager)"
@ -459,7 +459,7 @@ load_spec_nginx-proxy-manager() {
load_spec_portainer() {
reset_spec
SPEC_NAME="portainer"
SPEC_IMAGE="${PORTAINER_IMAGE:-docker.io/portainer/portainer-ce:2.21.5}"
SPEC_IMAGE="${PORTAINER_IMAGE}"
SPEC_PORTS="9000:9000"
SPEC_VOLUMES="/var/lib/archipelago/portainer:/data /run/user/1000/podman/podman.sock:/var/run/docker.sock"
SPEC_MEMORY="$(mem_limit portainer)"
@ -471,7 +471,7 @@ load_spec_portainer() {
load_spec_ollama() {
reset_spec
SPEC_NAME="ollama"
SPEC_IMAGE="${OLLAMA_IMAGE:-docker.io/ollama/ollama:0.5.4}"
SPEC_IMAGE="${OLLAMA_IMAGE}"
SPEC_PORTS="11434:11434"
SPEC_VOLUMES="/var/lib/archipelago/ollama:/root/.ollama"
SPEC_MEMORY="$(mem_limit ollama)"

View File

@ -52,7 +52,7 @@ podman run -d \
--label "com.archipelago.icon=/assets/img/app-icons/bitcoin-knots.webp" \
--label "com.archipelago.port=8332" \
--label "com.archipelago.repo=https://github.com/bitcoinknots/bitcoin" \
"${BITCOIN_KNOTS_IMAGE:-docker.io/bitcoinknots/bitcoin:v28.1}" \
"${BITCOIN_KNOTS_IMAGE}" \
-server=1 \
-txindex=1 \
-rpcallowip=127.0.0.1/32 -rpcallowip=10.88.0.0/16 \
@ -74,7 +74,7 @@ mkdir -p "$BUILD_DIR"
# Create Dockerfile
cat > "$BUILD_DIR/Dockerfile" << 'EOF'
FROM docker.io/library/nginx:alpine
FROM ${NGINX_ALPINE_IMAGE:-80.71.235.15:3000/archipelago/nginx:1.29.6-alpine}
# Copy the static UI
COPY index.html /usr/share/nginx/html/

View File

@ -446,7 +446,7 @@ if [ "$BOTH" = true ]; then
if [ "$RO" = "true" ]; then
$DOCKER stop filebrowser 2>/dev/null; $DOCKER rm filebrowser 2>/dev/null
sudo mkdir -p /var/lib/archipelago/filebrowser
$DOCKER run -d --name filebrowser --restart=unless-stopped --user 0:0 -p 8083:80 -v /var/lib/archipelago/filebrowser:/srv docker.io/filebrowser/filebrowser:v2.27.0 2>/dev/null
$DOCKER run -d --name filebrowser --restart=unless-stopped --user 0:0 -p 8083:80 -v /var/lib/archipelago/filebrowser:/srv "$FILEBROWSER_IMAGE" 2>/dev/null
fi
fi
' 2>/dev/null || true
@ -848,7 +848,7 @@ PYEOF
$DOCKER stop filebrowser 2>/dev/null
$DOCKER rm filebrowser 2>/dev/null
sudo mkdir -p /var/lib/archipelago/filebrowser
$DOCKER run -d --name filebrowser --restart=unless-stopped --user 0:0 -p 8083:80 -v /var/lib/archipelago/filebrowser:/srv docker.io/filebrowser/filebrowser:v2.27.0 2>&1 | tail -1
$DOCKER run -d --name filebrowser --restart=unless-stopped --user 0:0 -p 8083:80 -v /var/lib/archipelago/filebrowser:/srv "$FILEBROWSER_IMAGE" 2>&1 | tail -1
echo " FileBrowser recreated"
else
echo " FileBrowser OK"
@ -856,7 +856,7 @@ PYEOF
else
echo " Creating FileBrowser..."
sudo mkdir -p /var/lib/archipelago/filebrowser
$DOCKER run -d --name filebrowser --restart=unless-stopped --user 0:0 -p 8083:80 -v /var/lib/archipelago/filebrowser:/srv docker.io/filebrowser/filebrowser:v2.27.0 2>&1 | tail -1
$DOCKER run -d --name filebrowser --restart=unless-stopped --user 0:0 -p 8083:80 -v /var/lib/archipelago/filebrowser:/srv "$FILEBROWSER_IMAGE" 2>&1 | tail -1
echo " FileBrowser created"
fi
' 2>/dev/null || true
@ -1063,7 +1063,7 @@ MANIFEST_EOF
--security-opt no-new-privileges:true \
-p 8332:8332 -p 8333:8333 \
-v /var/lib/archipelago/bitcoin:/home/bitcoin/.bitcoin \
${BITCOIN_KNOTS_IMAGE:-docker.io/bitcoinknots/bitcoin:v28.1} \
${BITCOIN_KNOTS_IMAGE} \
-server=1 \$BTC_EXTRA_ARGS \
-rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 \
-dbcache=\$BTC_DBCACHE
@ -1096,7 +1096,7 @@ MANIFEST_EOF
-e MYSQL_USER=mempool \
-e MYSQL_PASSWORD=$MEMPOOL_DB_PASS \
-e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASS \
docker.io/mariadb:10.11
"$MARIADB_IMAGE"
sleep 3
fi
MYSQL_CNT=\$(\$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'mysql-mempool|archy-mempool-db' | head -1)
@ -1124,7 +1124,7 @@ MANIFEST_EOF
-e COIN=Bitcoin \
-e DB_DIRECTORY=/data \
-e SERVICES=tcp://:50001,rpc://0.0.0.0:8000 \
docker.io/lukechilds/electrumx:v1.18.0
"$ELECTRUMX_IMAGE"
fi
fi
# Create/recreate mempool-api (backend on 8999) - required for mempool to work
@ -1152,7 +1152,7 @@ MANIFEST_EOF
-e DATABASE_DATABASE=mempool \
-e DATABASE_USERNAME=mempool \
-e DATABASE_PASSWORD=$MEMPOOL_DB_PASS \
docker.io/mempool/backend:v2.5.0
"$MEMPOOL_BACKEND_IMAGE"
fi
# Recreate mempool frontend - handle both 'mempool' and 'mempool-web' (frontend was on wrong port 8999)
for c in \$(\$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -E '^mempool\$|mempool-web|archy-mempool-web'); do
@ -1167,7 +1167,7 @@ MANIFEST_EOF
-p 4080:8080 \
-e FRONTEND_HTTP_PORT=8080 \
-e BACKEND_MAINNET_HTTP_HOST=mempool-api \
docker.io/mempool/frontend:v2.5.0
"$MEMPOOL_WEB_IMAGE"
fi
" 2>&1 | sed 's/^/ /' || true
@ -1191,7 +1191,7 @@ MANIFEST_EOF
-e POSTGRES_DB=btcpay \
-e POSTGRES_USER=btcpay \
-e POSTGRES_PASSWORD=$BTCPAY_DB_PASS \
docker.io/postgres:15-alpine
"$BTCPAY_POSTGRES_IMAGE"
sleep 3
fi
# Create NBXplorer database in PostgreSQL (NBXplorer needs its own DB)
@ -1215,7 +1215,7 @@ MANIFEST_EOF
-e NBXPLORER_BTCRPCUSER=$BITCOIN_RPC_USER \
-e NBXPLORER_BTCRPCPASSWORD=$BITCOIN_RPC_PASS \
-e NBXPLORER_POSTGRES='User ID=btcpay;Password=$BTCPAY_DB_PASS;Host=archy-btcpay-db;Port=5432;Database=nbxplorer;Include Error Detail=true' \
docker.io/nicolasdorier/nbxplorer:2.6.0
"$NBXPLORER_IMAGE"
sleep 5
fi
fi
@ -1244,7 +1244,7 @@ MANIFEST_EOF
-e BTCPAY_BTCRPCUSER=archipelago \
-e BTCPAY_BTCRPCPASSWORD=$BITCOIN_RPC_PASS \
-e BTCPAY_POSTGRES='User ID=btcpay;Password=$BTCPAY_DB_PASS;Host=archy-btcpay-db;Port=5432;Database=btcpay;Include Error Detail=true' \
docker.io/btcpayserver/btcpayserver:1.13.5
"$BTCPAY_IMAGE"
fi
" 2>&1 | sed 's/^/ /' || true
@ -1268,12 +1268,12 @@ MANIFEST_EOF
\$DOCKER run -d --name immich_postgres --restart unless-stopped --network immich-net \
-v /var/lib/archipelago/immich-db:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD=$IMMICH_DB_PASS -e POSTGRES_USER=postgres -e POSTGRES_DB=immich \
ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0 2>/dev/null || true
"$IMMICH_POSTGRES_IMAGE" 2>/dev/null || true
sleep 5
fi
if ! \$DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q immich_redis; then
\$DOCKER run -d --name immich_redis --restart unless-stopped --network immich-net \
docker.io/valkey/valkey:7-alpine 2>/dev/null || true
"$VALKEY_IMAGE" 2>/dev/null || true
sleep 2
fi
if ! \$DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q immich_server; then
@ -1282,7 +1282,7 @@ MANIFEST_EOF
-e DB_HOSTNAME=immich_postgres -e DB_USERNAME=postgres -e DB_PASSWORD=$IMMICH_DB_PASS \
-e DB_DATABASE_NAME=immich -e REDIS_HOSTNAME=immich_redis \
-e UPLOAD_LOCATION=/usr/src/app/upload \
ghcr.io/immich-app/immich-server:release 2>/dev/null || true
"$IMMICH_SERVER_IMAGE" 2>/dev/null || true
fi
echo ' Immich stack created (may take 1-2 min to become ready)'
else
@ -1442,7 +1442,7 @@ print("torrc generated with %d services" % (enabled or 7))
-e FM_P2P_URL=fedimint://$TARGET_IP:8173 \
-e FM_API_URL=ws://$TARGET_IP:8174 \
-e FM_BITCOIND_URL=http://$TARGET_IP:8332 \
docker.io/fedimint/fedimintd:v0.10.0
"$FEDIMINT_IMAGE"
break
done
@ -1453,7 +1453,7 @@ print("torrc generated with %d services" % (enabled or 7))
sudo mkdir -p /var/lib/archipelago/fedimint-gateway
LND_CERT=/var/lib/archipelago/lnd/tls.cert
LND_MACAROON=/var/lib/archipelago/lnd/data/chain/bitcoin/mainnet/admin.macaroon
GW_COMMON=\"-p 8176:8176 -v /var/lib/archipelago/fedimint-gateway:/data docker.io/fedimint/gatewayd:v0.10.0 gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash '$FEDI_HASH' --network bitcoin --bitcoind-url http://$TARGET_IP:8332 --bitcoind-username $BITCOIN_RPC_USER --bitcoind-password $BITCOIN_RPC_PASS\"
GW_COMMON=\"-p 8176:8176 -v /var/lib/archipelago/fedimint-gateway:/data "$FEDIMINT_GATEWAY_IMAGE" gatewayd --data-dir /data --listen 0.0.0.0:8176 --bcrypt-password-hash '$FEDI_HASH' --network bitcoin --bitcoind-url http://$TARGET_IP:8332 --bitcoind-username $BITCOIN_RPC_USER --bitcoind-password $BITCOIN_RPC_PASS\"
if \$DOCKER ps --format '{{.Names}}' | grep -q '^lnd\$' && sudo test -f \$LND_CERT && sudo test -f \$LND_MACAROON; then
echo ' LND detected — using lnd mode'
\$DOCKER run -d --name fedimint-gateway --restart unless-stopped \
@ -1463,7 +1463,7 @@ print("torrc generated with %d services" % (enabled or 7))
-v /var/lib/archipelago/fedimint-gateway:/data \
-v /var/lib/archipelago/lnd/tls.cert:/lnd/tls.cert:ro \
-v /var/lib/archipelago/lnd/data/chain/bitcoin/mainnet/admin.macaroon:/lnd/admin.macaroon:ro \
docker.io/fedimint/gatewayd:v0.10.0 \
"$FEDIMINT_GATEWAY_IMAGE" \
gatewayd --data-dir /data --listen 0.0.0.0:8176 \
--bcrypt-password-hash '$FEDI_HASH' \
--network bitcoin --bitcoind-url http://$TARGET_IP:8332 \
@ -1476,7 +1476,7 @@ print("torrc generated with %d services" % (enabled or 7))
--security-opt no-new-privileges:true \
-p 8176:8176 -p 9737:9737 \
-v /var/lib/archipelago/fedimint-gateway:/data \
docker.io/fedimint/gatewayd:v0.10.0 \
"$FEDIMINT_GATEWAY_IMAGE" \
gatewayd --data-dir /data --listen 0.0.0.0:8176 \
--bcrypt-password-hash '$FEDI_HASH' \
--network bitcoin --bitcoind-url http://$TARGET_IP:8332 \
@ -1553,7 +1553,7 @@ LNDCONF
--security-opt no-new-privileges:true \
-p 9735:9735 -p 10009:10009 -p 8080:8080 \
-v /var/lib/archipelago/lnd:/root/.lnd \
docker.io/lightninglabs/lnd:v0.18.4-beta
"$LND_IMAGE"
echo " LND created"
fi
else
@ -1577,7 +1577,7 @@ LNDCONF
--security-opt no-new-privileges:true \
-p 8123:8123 -v /var/lib/archipelago/home-assistant:/config \
-e TZ=UTC \
docker.io/homeassistant/home-assistant:2024.1
"$HOMEASSISTANT_IMAGE"
fi
else
echo " Home Assistant already running"
@ -1601,7 +1601,7 @@ LNDCONF
--security-opt no-new-privileges:true \
-p 3000:3000 -v /var/lib/archipelago/grafana:/var/lib/grafana \
-e GF_PATHS_DATA=/var/lib/grafana -e GF_USERS_ALLOW_SIGN_UP=false \
docker.io/grafana/grafana:10.2.0
"$GRAFANA_IMAGE"
fi
else
echo " Grafana already running"
@ -1624,7 +1624,7 @@ LNDCONF
-p 8096:8096 \
-v /var/lib/archipelago/jellyfin/config:/config \
-v /var/lib/archipelago/jellyfin/cache:/cache \
docker.io/jellyfin/jellyfin:10.8.13
"$JELLYFIN_IMAGE"
fi
else
echo " Jellyfin already running"
@ -1646,7 +1646,7 @@ LNDCONF
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
-p 8082:80 -v /var/lib/archipelago/vaultwarden:/data \
docker.io/vaultwarden/server:1.30.0-alpine
"$VAULTWARDEN_IMAGE"
fi
else
echo " Vaultwarden already running"
@ -1666,7 +1666,7 @@ LNDCONF
$DOCKER run -d --name searxng --restart unless-stopped \
--cap-drop ALL --security-opt no-new-privileges:true \
-p 8888:8080 \
${SEARXNG_IMAGE:-docker.io/searxng/searxng:2024.11.17}
${SEARXNG_IMAGE}
fi
else
echo " SearXNG already running"

View File

@ -8,50 +8,13 @@
# No set -e: each section continues even if one fails (idempotent, best-effort).
#
# Image versions: sourced from /opt/archipelago/image-versions.sh (single source of truth).
# All container image references MUST use the $*_IMAGE variables defined there.
# NOTE: Many container creation lines below still use hardcoded versions instead of
# the $*_IMAGE variables. These must be migrated to use the variables for consistency.
# See the version mismatch list in the planned refactor below.
# All container image references use the $*_IMAGE variables defined there.
# Images pull from the Archipelago app registry (80.71.235.15:3000/archipelago/).
#
# --- PLANNED REFACTOR (post-beta) ---
# This script is ~995 lines and should be split into a modular library.
# Proposed structure:
# scripts/
# first-boot-containers.sh — Main orchestrator (prereqs, sequencing, summary)
# lib/
# container-prereqs.sh — Swap setup, rootless podman config, UID mapping (~120 lines)
# container-secrets.sh — RPC auth, DB passwords, bitcoin.conf generation (~80 lines)
# container-helpers.sh — mem_limit(), wait_for_container(), track_container() (~60 lines)
# tier1-databases.sh — Tier 1: Bitcoin Knots, MariaDB, Postgres, ElectrumX (~200 lines)
# tier2-services.sh — Tier 2: LND, Mempool, BTCPay, Fedimint (~200 lines)
# tier3-apps.sh — Tier 3: Home Assistant, Grafana, Jellyfin, etc. (~250 lines)
# tier3-stacks.sh — Tier 3: Multi-container stacks (Immich, Penpot, Nostr) (~100 lines)
# custom-ui.sh — Custom UI containers (bitcoin-ui, lnd-ui, electrs-ui) (~60 lines)
# Each lib/ script exports functions; main script sources them and calls in sequence.
# DO NOT split until tested on the build server — this is critical infrastructure.
#
# KNOWN VERSION MISMATCHES (hardcoded vs image-versions.sh):
# - MariaDB: hardcoded 10.11, pinned 11.4
# - ElectrumX: hardcoded v1.18.0, pinned v1.16.0
# - Mempool backend/frontend: hardcoded v2.5.0, pinned v3.0.0
# - Postgres (BTCPay): hardcoded 15-alpine, pinned 16
# - NBXplorer: hardcoded 2.6.0, pinned 2.5.13
# - BTCPay: hardcoded 1.13.5, pinned 1.14.5
# - LND: hardcoded v0.18.4-beta, pinned v0.18.5-beta
# - Fedimint: hardcoded v0.10.0, pinned v0.5.1
# - Home Assistant: hardcoded 2024.1, pinned 2024.12
# - Grafana: hardcoded 10.2.0, pinned 11.4.0
# - Jellyfin: hardcoded 10.8.13, pinned 10.10.3
# - Vaultwarden: hardcoded 1.30.0-alpine, pinned 1.32.5
# - Nextcloud: hardcoded 28, pinned 30
# - OnlyOffice: hardcoded 7.5.1, pinned 8.2
# - FileBrowser: hardcoded v2.27.0, pinned v2
# - Portainer: hardcoded 2.19.4, pinned 2.21.5
# - Tailscale: hardcoded :stable, pinned v1.78.3
# - Immich: hardcoded :release, pinned v1.123.0
# Fix these by replacing hardcoded values with ${VAR:-fallback} pattern.
# ---
#
LOG="/var/log/archipelago-first-boot.log"
DOCKER=podman
command -v podman >/dev/null 2>&1 || DOCKER=docker
@ -317,7 +280,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -qE 'bitcoin-knots|arch
--security-opt no-new-privileges:true \
-p 8332:8332 -p 8333:8333 \
-v /var/lib/archipelago/bitcoin:/home/bitcoin/.bitcoin \
"${BITCOIN_KNOTS_IMAGE:-docker.io/bitcoinknots/bitcoin:28.1}" \
"${BITCOIN_KNOTS_IMAGE}" \
-server=1 $BTC_EXTRA_ARGS \
-rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 \
-proxy=host.containers.internal:9050 -listen=1 -bind=0.0.0.0:8333 \
@ -358,7 +321,7 @@ if ! $DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qE 'archy-mempool-d
-v /var/lib/archipelago/mysql-mempool:/var/lib/mysql \
-e MYSQL_DATABASE=mempool -e MYSQL_USER=mempool -e "MYSQL_PASSWORD=$MEMPOOL_DB_PASS" \
-e "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASS" \
docker.io/mariadb:10.11 2>>"$LOG" || true
"$MARIADB_IMAGE" 2>>"$LOG" || true
wait_for_container "Mempool MariaDB" "echo 'SELECT 1' | $DOCKER exec -i archy-mempool-db mariadb -uroot --password=\"$MYSQL_ROOT_PASS\"" 30
fi
MYSQL_CNT=$($DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'mysql-mempool|archy-mempool-db' | head -1)
@ -379,7 +342,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q electrumx; then
-e "DAEMON_URL=http://$BITCOIN_RPC_USER:$BITCOIN_RPC_PASS@bitcoin-knots:8332/" \
-e COIN=Bitcoin -e DB_DIRECTORY=/data \
-e SERVICES=tcp://:50001,rpc://0.0.0.0:8000 \
docker.io/lukechilds/electrumx:v1.18.0 2>>"$LOG" || true
"$ELECTRUMX_IMAGE" 2>>"$LOG" || true
fi
fi
track_container "electrumx"
@ -396,7 +359,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q mempool-api; then
-e "CORE_RPC_USERNAME=$BITCOIN_RPC_USER" -e "CORE_RPC_PASSWORD=$BITCOIN_RPC_PASS" \
-e DATABASE_ENABLED=true -e DATABASE_HOST="$MYSQL_CNT" -e DATABASE_DATABASE=mempool \
-e DATABASE_USERNAME=mempool -e "DATABASE_PASSWORD=$MEMPOOL_DB_PASS" \
docker.io/mempool/backend:v2.5.0 2>>"$LOG" || true
"$MEMPOOL_BACKEND_IMAGE" 2>>"$LOG" || true
fi
track_container "mempool-api"
@ -406,7 +369,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -qE 'archy-mempool-web|
--health-cmd="curl -sf http://localhost:8080/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit archy-mempool-web) --network archy-net \
-p 4080:8080 -e FRONTEND_HTTP_PORT=8080 -e BACKEND_MAINNET_HTTP_HOST=mempool-api \
docker.io/mempool/frontend:v2.5.0 2>>"$LOG" || true
"$MEMPOOL_WEB_IMAGE" 2>>"$LOG" || true
fi
track_container "archy-mempool-web"
@ -440,7 +403,7 @@ if ! $DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qE 'archy-btcpay-db
--memory=$(mem_limit archy-btcpay-db) --network archy-net \
-v /var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data \
-e POSTGRES_DB=btcpay -e POSTGRES_USER=btcpay -e "POSTGRES_PASSWORD=$BTCPAY_DB_PASS" \
docker.io/postgres:15-alpine 2>>"$LOG" || true
"$BTCPAY_POSTGRES_IMAGE" 2>>"$LOG" || true
wait_for_container "BTCPay PostgreSQL" "$DOCKER exec archy-btcpay-db pg_isready -U postgres" 30
fi
track_container "archy-btcpay-db"
@ -464,7 +427,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q archy-nbxplorer; the
-e NBXPLORER_BIND=0.0.0.0:32838 -e NBXPLORER_BTCRPCURL=http://bitcoin-knots:8332 \
-e "NBXPLORER_BTCRPCUSER=$BITCOIN_RPC_USER" -e "NBXPLORER_BTCRPCPASSWORD=$BITCOIN_RPC_PASS" \
-e NBXPLORER_POSTGRES='User ID=btcpay;Password=$BTCPAY_DB_PASS;Host=archy-btcpay-db;Port=5432;Database=nbxplorer;Include Error Detail=true' \
docker.io/nicolasdorier/nbxplorer:2.6.0 2>>"$LOG" && sleep 5 || true
"$NBXPLORER_IMAGE" 2>>"$LOG" && sleep 5 || true
fi
fi
track_container "archy-nbxplorer"
@ -484,7 +447,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q btcpay-server; then
-e BTCPAY_BTCRPCURL=http://bitcoin-knots:8332 \
-e "BTCPAY_BTCRPCUSER=$BITCOIN_RPC_USER" -e "BTCPAY_BTCRPCPASSWORD=$BITCOIN_RPC_PASS" \
-e BTCPAY_POSTGRES='User ID=btcpay;Password=$BTCPAY_DB_PASS;Host=archy-btcpay-db;Port=5432;Database=btcpay;Include Error Detail=true' \
docker.io/btcpayserver/btcpayserver:1.13.5 2>>"$LOG" || true
"$BTCPAY_IMAGE" 2>>"$LOG" || true
fi
track_container "btcpay-server"
@ -532,7 +495,7 @@ LNDCONF
--security-opt no-new-privileges:true \
-p 9735:9735 -p 10009:10009 -p 8080:8080 \
-v /var/lib/archipelago/lnd:/root/.lnd \
docker.io/lightninglabs/lnd:v0.18.4-beta 2>>"$LOG" || true
"$LND_IMAGE" 2>>"$LOG" || true
fi
track_container "lnd"
@ -552,7 +515,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q fedimint; then
-e FM_BIND_API=0.0.0.0:8174 -e FM_BIND_UI=0.0.0.0:8175 \
-e FM_P2P_URL=fedimint://"$TARGET_IP":8173 -e FM_API_URL=ws://"$TARGET_IP":8174 \
-e FM_BITCOIND_URL=http://"$TARGET_IP":8332 \
docker.io/fedimint/fedimintd:v0.10.0 2>>"$LOG" || true
"$FEDIMINT_IMAGE" 2>>"$LOG" || true
fi
track_container "fedimint"
@ -574,7 +537,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q fedimint-gateway; th
-v /var/lib/archipelago/fedimint-gateway:/data \
-v "$LND_CERT":/lnd/tls.cert:ro \
-v "$LND_MACAROON":/lnd/admin.macaroon:ro \
docker.io/fedimint/gatewayd:v0.10.0 \
"$FEDIMINT_GATEWAY_IMAGE" \
gatewayd --data-dir /data --listen 0.0.0.0:8176 \
--bcrypt-password-hash "$FEDI_HASH" \
--network bitcoin --bitcoind-url http://"$TARGET_IP":8332 \
@ -589,7 +552,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q fedimint-gateway; th
--security-opt no-new-privileges:true \
-p 8176:8176 -p 9737:9737 \
-v /var/lib/archipelago/fedimint-gateway:/data \
docker.io/fedimint/gatewayd:v0.10.0 \
"$FEDIMINT_GATEWAY_IMAGE" \
gatewayd --data-dir /data --listen 0.0.0.0:8176 \
--bcrypt-password-hash "$FEDI_HASH" \
--network bitcoin --bitcoind-url http://"$TARGET_IP":8332 \
@ -618,7 +581,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -qE 'homeassistant|home
--security-opt no-new-privileges:true \
-p 8123:8123 -v /var/lib/archipelago/home-assistant:/config \
-e TZ=UTC \
docker.io/homeassistant/home-assistant:2024.1 2>>"$LOG" || true
"$HOMEASSISTANT_IMAGE" 2>>"$LOG" || true
fi
track_container "homeassistant"
@ -635,7 +598,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q grafana; then
--read-only --tmpfs /tmp:rw,noexec,nosuid,size=256m --tmpfs /run:rw,noexec,nosuid,size=64m \
-p 3000:3000 -v /var/lib/archipelago/grafana:/var/lib/grafana \
-e GF_PATHS_DATA=/var/lib/grafana -e GF_USERS_ALLOW_SIGN_UP=false \
docker.io/grafana/grafana:10.2.0 2>>"$LOG" || true
"$GRAFANA_IMAGE" 2>>"$LOG" || true
fi
track_container "grafana"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q uptime-kuma; then
@ -648,7 +611,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q uptime-kuma; then
--security-opt no-new-privileges:true \
-p 3001:3001 -v /var/lib/archipelago/uptime-kuma:/app/data \
-e TZ=UTC \
docker.io/louislam/uptime-kuma:1 2>>"$LOG" || true
"$UPTIME_KUMA_IMAGE" 2>>"$LOG" || true
fi
track_container "uptime-kuma"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q jellyfin; then
@ -661,7 +624,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q jellyfin; then
-p 8096:8096 \
-v /var/lib/archipelago/jellyfin/config:/config \
-v /var/lib/archipelago/jellyfin/cache:/cache \
docker.io/jellyfin/jellyfin:10.8.13 2>>"$LOG" || true
"$JELLYFIN_IMAGE" 2>>"$LOG" || true
fi
track_container "jellyfin"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q photoprism; then
@ -674,7 +637,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q photoprism; then
--security-opt no-new-privileges:true \
-p 2342:2342 -v /var/lib/archipelago/photoprism:/photoprism/storage \
-e PHOTOPRISM_ADMIN_PASSWORD=archipelago -e PHOTOPRISM_DEFAULT_LOCALE=en \
"${PHOTOPRISM_IMAGE:-docker.io/photoprism/photoprism:240915}" 2>>"$LOG" || true
"${PHOTOPRISM_IMAGE}" 2>>"$LOG" || true
fi
track_container "photoprism"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q ollama; then
@ -686,7 +649,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q ollama; then
--cap-drop ALL --security-opt no-new-privileges:true \
--read-only --tmpfs /tmp:rw,noexec,nosuid,size=256m --tmpfs /run:rw,noexec,nosuid,size=64m \
-p 11434:11434 -v /var/lib/archipelago/ollama:/root/.ollama \
"${OLLAMA_IMAGE:-docker.io/ollama/ollama:0.5.4}" 2>>"$LOG" || true
"${OLLAMA_IMAGE}" 2>>"$LOG" || true
fi
track_container "ollama"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q vaultwarden; then
@ -698,7 +661,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q vaultwarden; then
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
-p 8082:80 -v /var/lib/archipelago/vaultwarden:/data \
docker.io/vaultwarden/server:1.30.0-alpine 2>>"$LOG" || true
"$VAULTWARDEN_IMAGE" 2>>"$LOG" || true
fi
track_container "vaultwarden"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q nextcloud; then
@ -710,7 +673,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q nextcloud; then
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 8085:80 -v /var/lib/archipelago/nextcloud:/var/www/html \
docker.io/library/nextcloud:28 2>>"$LOG" || true
"$NEXTCLOUD_IMAGE" 2>>"$LOG" || true
fi
track_container "nextcloud"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q searxng; then
@ -721,7 +684,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q searxng; then
--cap-drop ALL --security-opt no-new-privileges:true \
--read-only --tmpfs /tmp:rw,noexec,nosuid,size=256m --tmpfs /run:rw,noexec,nosuid,size=64m \
-p 8888:8080 \
"${SEARXNG_IMAGE:-docker.io/searxng/searxng:2024.11.17}" 2>>"$LOG" || true
"${SEARXNG_IMAGE}" 2>>"$LOG" || true
fi
track_container "searxng"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q onlyoffice; then
@ -732,7 +695,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q onlyoffice; then
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 9980:80 \
docker.io/onlyoffice/documentserver:7.5.1 2>>"$LOG" || true
"$ONLYOFFICE_IMAGE" 2>>"$LOG" || true
fi
track_container "onlyoffice"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q filebrowser; then
@ -742,7 +705,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q filebrowser; then
--health-cmd="curl -sf http://localhost:80/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit filebrowser) \
-p 8083:80 -v /var/lib/archipelago/filebrowser:/srv \
docker.io/filebrowser/filebrowser:v2.27.0 2>>"$LOG" || true
"$FILEBROWSER_IMAGE" 2>>"$LOG" || true
fi
track_container "filebrowser"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q nginx-proxy-manager; then
@ -756,7 +719,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q nginx-proxy-manager;
-p 81:81 -p 8084:80 -p 8443:443 \
-v /var/lib/archipelago/nginx-proxy-manager/data:/data \
-v /var/lib/archipelago/nginx-proxy-manager/letsencrypt:/etc/letsencrypt \
"${NPM_IMAGE:-docker.io/jc21/nginx-proxy-manager:2}" 2>>"$LOG" || true
"${NPM_IMAGE}" 2>>"$LOG" || true
fi
track_container "nginx-proxy-manager"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q portainer; then
@ -770,7 +733,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q portainer; then
-p 9000:9000 \
-v /var/lib/archipelago/portainer:/data \
-v /var/run/podman/podman.sock:/var/run/docker.sock \
docker.io/portainer/portainer-ce:2.19.4 2>>"$LOG" || true
"$PORTAINER_IMAGE" 2>>"$LOG" || true
fi
track_container "portainer"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q tailscale; then
@ -789,7 +752,7 @@ if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q tailscale; then
--tmpfs /tmp \
-v /var/lib/archipelago/tailscale:/var/lib/tailscale \
-e TS_STATE_DIR=/var/lib/tailscale \
docker.io/tailscale/tailscale:stable \
"$TAILSCALE_IMAGE" \
sh -c 'tailscale web --listen 0.0.0.0:8240 & exec tailscaled' 2>>"$LOG" || true
fi
track_container "tailscale"
@ -805,7 +768,7 @@ if $DOCKER images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q 'nos
--health-cmd="curl -sf http://localhost:8080/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit nostr-rs-relay) \
-p 7047:7047 -v /var/lib/archipelago/nostr-rs-relay:/data \
"${NOSTR_RS_RELAY_IMAGE:-docker.io/scsibug/nostr-rs-relay:0.9.0}" 2>>"$LOG" || true
"${NOSTR_RS_RELAY_IMAGE}" 2>>"$LOG" || true
fi
fi
if $DOCKER images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q 'strfry'; then
@ -816,7 +779,7 @@ if $DOCKER images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q 'str
--health-cmd="curl -sf http://localhost:7777/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit strfry) \
-p 7777:7777 -v /var/lib/archipelago/strfry:/data \
"${STRFRY_IMAGE:-docker.io/pluja/strfry:1.0.4}" 2>>"$LOG" || true
"${STRFRY_IMAGE}" 2>>"$LOG" || true
fi
fi

View File

@ -28,7 +28,7 @@ fi
# Verify correct images are available
echo "Verifying images..."
for img in "${INDEEDHUB_REDIS_IMAGE:-docker.io/library/redis:7-alpine}" "${MINIO_IMAGE:-docker.io/minio/minio:RELEASE.2024-11-07T00-52-20Z}" "${INDEEDHUB_POSTGRES_IMAGE:-docker.io/library/postgres:16-alpine}" "${NOSTR_RS_RELAY_IMAGE:-docker.io/scsibug/nostr-rs-relay:0.9.0}" "${SEARXNG_IMAGE:-docker.io/searxng/searxng:2024.11.17}" "localhost/indeedhub:local" "localhost/indeedhub-build_api:local" "localhost/indeedhub-build_ffmpeg-worker:local"; do
for img in "${INDEEDHUB_REDIS_IMAGE}" "${MINIO_IMAGE}" "${INDEEDHUB_POSTGRES_IMAGE}" "${NOSTR_RS_RELAY_IMAGE}" "${SEARXNG_IMAGE}" "localhost/indeedhub:local" "localhost/indeedhub-build_api:local" "localhost/indeedhub-build_ffmpeg-worker:local"; do
if ! podman image exists "$img" 2>/dev/null; then
echo "ERROR: Missing image $img"
exit 1
@ -63,7 +63,7 @@ podman run -d --name indeedhub-postgres \
-e POSTGRES_USER=indeedhub \
-e POSTGRES_PASSWORD=indeehhub-archy-2026 \
-e POSTGRES_DB=indeedhub \
docker.io/library/postgres:16-alpine
"$INDEEDHUB_POSTGRES_IMAGE"
# Wait for postgres to be ready
echo "Waiting for postgres..."
@ -81,7 +81,7 @@ podman run -d --name indeedhub-redis \
--restart unless-stopped \
--network "$NETWORK" --network-alias redis \
-v indeedhub-redis-data:/data \
docker.io/library/redis:7-alpine \
"$INDEEDHUB_REDIS_IMAGE" \
redis-server --appendonly yes
# 3. MinIO
@ -92,7 +92,7 @@ podman run -d --name indeedhub-minio \
-v indeedhub-minio-data:/data \
-e MINIO_ROOT_USER=indeeadmin \
-e MINIO_ROOT_PASSWORD=indeeadmin2026 \
"${MINIO_IMAGE:-docker.io/minio/minio:RELEASE.2024-11-07T00-52-20Z}" \
"${MINIO_IMAGE}" \
server /data --console-address ":9001"
# 4. Nostr Relay
@ -101,7 +101,7 @@ podman run -d --name indeedhub-relay \
--restart unless-stopped \
--network "$NETWORK" --network-alias relay \
-v indeedhub-relay-data:/usr/src/app/db \
"${NOSTR_RS_RELAY_IMAGE:-docker.io/scsibug/nostr-rs-relay:0.9.0}"
"${NOSTR_RS_RELAY_IMAGE}"
# 5. API
echo "Creating api..."
@ -227,7 +227,7 @@ echo "Creating searxng..."
podman run -d --name searxng \
--restart unless-stopped \
-p 8888:8080 \
"${SEARXNG_IMAGE:-docker.io/searxng/searxng:2024.11.17}"
"${SEARXNG_IMAGE}"
echo ""
echo "=== Verifying container status ==="

View File

@ -5,64 +5,77 @@
# Usage: source /opt/archipelago/image-versions.sh 2>/dev/null || true
# source "$(dirname "$0")/image-versions.sh" 2>/dev/null || true
# Archipelago app registry
ARCHY_REGISTRY="80.71.235.15:3000/archipelago"
# Bitcoin stack
BITCOIN_KNOTS_IMAGE="docker.io/bitcoinknots/bitcoin:28.1"
LND_IMAGE="docker.io/lightninglabs/lnd:v0.18.5-beta"
ELECTRUMX_IMAGE="docker.io/lukechilds/electrumx:v1.18.0"
BITCOIN_KNOTS_IMAGE="$ARCHY_REGISTRY/bitcoin-knots:28.1"
LND_IMAGE="$ARCHY_REGISTRY/lnd:v0.18.5-beta"
ELECTRUMX_IMAGE="$ARCHY_REGISTRY/electrumx:v1.18.0"
# Mempool stack
MEMPOOL_BACKEND_IMAGE="docker.io/mempool/backend:v3.0.0"
MEMPOOL_WEB_IMAGE="docker.io/mempool/frontend:v3.0.0"
MARIADB_IMAGE="docker.io/library/mariadb:11.4.10"
MEMPOOL_BACKEND_IMAGE="$ARCHY_REGISTRY/mempool-backend:v3.0.0"
MEMPOOL_WEB_IMAGE="$ARCHY_REGISTRY/mempool-frontend:v3.0.0"
MARIADB_IMAGE="$ARCHY_REGISTRY/mariadb:11.4.10"
# BTCPay
BTCPAY_IMAGE="docker.io/btcpayserver/btcpayserver:1.13.7"
NBXPLORER_IMAGE="docker.io/nicolasdorier/nbxplorer:2.6.0"
POSTGRES_IMAGE="docker.io/library/postgres:15.17"
BTCPAY_POSTGRES_IMAGE="docker.io/library/postgres:15.17"
BTCPAY_IMAGE="$ARCHY_REGISTRY/btcpayserver:1.13.7"
NBXPLORER_IMAGE="$ARCHY_REGISTRY/nbxplorer:2.6.0"
POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:15.17"
BTCPAY_POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:15.17"
# Apps
HOMEASSISTANT_IMAGE="ghcr.io/home-assistant/home-assistant:2024.12.5"
GRAFANA_IMAGE="docker.io/grafana/grafana:11.4.0"
UPTIME_KUMA_IMAGE="docker.io/louislam/uptime-kuma:1.23.17"
JELLYFIN_IMAGE="docker.io/jellyfin/jellyfin:10.10.3"
PHOTOPRISM_IMAGE="docker.io/photoprism/photoprism:240915"
OLLAMA_IMAGE="docker.io/ollama/ollama:0.5.4"
VAULTWARDEN_IMAGE="docker.io/vaultwarden/server:1.32.5"
NEXTCLOUD_IMAGE="docker.io/library/nextcloud:29.0.16"
SEARXNG_IMAGE="docker.io/searxng/searxng:2026.3.20-6c7e9c197"
ONLYOFFICE_IMAGE="docker.io/onlyoffice/documentserver:8.2.3.1"
FILEBROWSER_IMAGE="docker.io/filebrowser/filebrowser:v2.27.0"
NPM_IMAGE="docker.io/jc21/nginx-proxy-manager:2.14.0"
PORTAINER_IMAGE="docker.io/portainer/portainer-ce:2.21.5"
HOMEASSISTANT_IMAGE="$ARCHY_REGISTRY/home-assistant:2024.12.5"
GRAFANA_IMAGE="$ARCHY_REGISTRY/grafana:11.4.0"
UPTIME_KUMA_IMAGE="$ARCHY_REGISTRY/uptime-kuma:1.23.17"
JELLYFIN_IMAGE="$ARCHY_REGISTRY/jellyfin:10.10.3"
PHOTOPRISM_IMAGE="$ARCHY_REGISTRY/photoprism:240915"
OLLAMA_IMAGE="$ARCHY_REGISTRY/ollama:0.5.4"
VAULTWARDEN_IMAGE="$ARCHY_REGISTRY/vaultwarden:1.32.5"
NEXTCLOUD_IMAGE="$ARCHY_REGISTRY/nextcloud:29.0.16"
SEARXNG_IMAGE="$ARCHY_REGISTRY/searxng:2026.3.20-6c7e9c197"
ONLYOFFICE_IMAGE="$ARCHY_REGISTRY/onlyoffice:8.2.3.1"
FILEBROWSER_IMAGE="$ARCHY_REGISTRY/filebrowser:v2.27.0"
NPM_IMAGE="$ARCHY_REGISTRY/nginx-proxy-manager:2.14.0"
PORTAINER_IMAGE="$ARCHY_REGISTRY/portainer:2.21.5"
# Networking
TAILSCALE_IMAGE="docker.io/tailscale/tailscale:v1.78.3"
ALPINE_TOR_IMAGE="docker.io/andrius/alpine-tor:0.4.8.13"
ADGUARDHOME_IMAGE="docker.io/adguard/adguardhome:v0.107.55"
TAILSCALE_IMAGE="$ARCHY_REGISTRY/tailscale:v1.78.3"
ALPINE_TOR_IMAGE="$ARCHY_REGISTRY/alpine-tor:0.4.8.13"
ADGUARDHOME_IMAGE="$ARCHY_REGISTRY/adguardhome:v0.107.55"
# Fedimint
FEDIMINT_IMAGE="docker.io/fedimint/fedimintd:v0.10.0"
FEDIMINT_GATEWAY_IMAGE="docker.io/fedimint/gatewayd:v0.10.0"
FEDIMINT_IMAGE="$ARCHY_REGISTRY/fedimintd:v0.10.0"
FEDIMINT_GATEWAY_IMAGE="$ARCHY_REGISTRY/gatewayd:v0.10.0"
# Media
REDIS_IMAGE="docker.io/library/redis:7.4.8"
REDIS_IMAGE="$ARCHY_REGISTRY/redis:7.4.8"
# Valkey (general purpose)
VALKEY_IMAGE="docker.io/valkey/valkey:8.1.6"
VALKEY_IMAGE="$ARCHY_REGISTRY/valkey:8.1.6"
# Nostr
NOSTR_RS_RELAY_IMAGE="docker.io/scsibug/nostr-rs-relay:0.9.0"
STRFRY_IMAGE="docker.io/pluja/strfry:1.0.4"
NOSTR_RS_RELAY_IMAGE="$ARCHY_REGISTRY/nostr-rs-relay:0.9.0"
STRFRY_IMAGE="$ARCHY_REGISTRY/strfry:1.0.4"
# IndeedHub stack (local builds use :local tag, not :latest)
MINIO_IMAGE="docker.io/minio/minio:RELEASE.2024-11-07T00-52-20Z"
INDEEDHUB_POSTGRES_IMAGE="docker.io/library/postgres:16.13-alpine"
INDEEDHUB_REDIS_IMAGE="docker.io/library/redis:7.4.8-alpine"
MINIO_IMAGE="$ARCHY_REGISTRY/minio:RELEASE.2024-11-07T00-52-20Z"
INDEEDHUB_POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:16.13-alpine"
INDEEDHUB_REDIS_IMAGE="$ARCHY_REGISTRY/redis:7.4.8-alpine"
# DWN (Decentralized Web Node)
DWN_SERVER_IMAGE="ghcr.io/tbd54566975/dwn-server:main@sha256:665cb00f45ffbf0d6324915b593503927654ebf13b7b71440a5ffe26edb3c48e"
DWN_SERVER_IMAGE="$ARCHY_REGISTRY/dwn-server:main"
# Immich stack
IMMICH_POSTGRES_IMAGE="$ARCHY_REGISTRY/immich-postgres:14-vectorchord0.4.3-pgvectors0.2.0"
IMMICH_SERVER_IMAGE="$ARCHY_REGISTRY/immich-server:release"
# Penpot stack
PENPOT_POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:15"
PENPOT_VALKEY_IMAGE="$ARCHY_REGISTRY/valkey:8.1"
PENPOT_BACKEND_IMAGE="$ARCHY_REGISTRY/penpot-backend:2.4"
PENPOT_EXPORTER_IMAGE="$ARCHY_REGISTRY/penpot-exporter:2.4"
PENPOT_FRONTEND_IMAGE="$ARCHY_REGISTRY/penpot-frontend:2.4"
# Base images
NGINX_ALPINE_IMAGE="docker.io/library/nginx:1.29.6-alpine"
NGINX_ALPINE_IMAGE="$ARCHY_REGISTRY/nginx:1.29.6-alpine"

View File

@ -86,7 +86,7 @@ else
# Check trusted registry
TRUSTED=false
for reg in "docker.io" "ghcr.io" "quay.io" "registry.hub.docker.com"; do
for reg in "docker.io" "ghcr.io" "quay.io" "registry.hub.docker.com" "80.71.235.15:3000"; do
if echo "$IMAGE" | grep -q "$reg"; then
TRUSTED=true
break