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. /// Trusted Docker registries. Only images from these sources are allowed.
#[allow(dead_code)] #[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. /// 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"). /// 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, Some(r) => r,
None => return false, 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. /// Per-app Linux capabilities needed beyond the default cap-drop=ALL.

View File

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

View File

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

View File

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

View File

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

View File

@ -198,7 +198,7 @@ fix_searxng() {
-v searxng-cache:/var/cache/searxng:rw \ -v searxng-cache:/var/cache/searxng:rw \
-p "${host_port}:8080" \ -p "${host_port}:8080" \
--memory=512m \ --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)" log "SearXNG recreated (no readonly, no cap-drop ALL)"
return 0 return 0

View File

@ -82,7 +82,7 @@ reset_spec() {
load_spec_archy-mempool-db() { load_spec_archy-mempool-db() {
reset_spec reset_spec
SPEC_NAME="archy-mempool-db" SPEC_NAME="archy-mempool-db"
SPEC_IMAGE="${MARIADB_IMAGE:-docker.io/library/mariadb:11.4}" SPEC_IMAGE="${MARIADB_IMAGE}"
SPEC_NETWORK="archy-net" SPEC_NETWORK="archy-net"
SPEC_MEMORY="$(mem_limit archy-mempool-db)" SPEC_MEMORY="$(mem_limit archy-mempool-db)"
SPEC_VOLUMES="/var/lib/archipelago/mysql-mempool:/var/lib/mysql" SPEC_VOLUMES="/var/lib/archipelago/mysql-mempool:/var/lib/mysql"
@ -97,7 +97,7 @@ load_spec_archy-mempool-db() {
load_spec_archy-btcpay-db() { load_spec_archy-btcpay-db() {
reset_spec reset_spec
SPEC_NAME="archy-btcpay-db" 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_NETWORK="archy-net"
SPEC_MEMORY="$(mem_limit archy-btcpay-db)" SPEC_MEMORY="$(mem_limit archy-btcpay-db)"
SPEC_VOLUMES="/var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data" SPEC_VOLUMES="/var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data"
@ -112,7 +112,7 @@ load_spec_archy-btcpay-db() {
load_spec_immich_postgres() { load_spec_immich_postgres() {
reset_spec reset_spec
SPEC_NAME="immich_postgres" 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_NETWORK="bridge"
SPEC_MEMORY="$(mem_limit immich_postgres)" SPEC_MEMORY="$(mem_limit immich_postgres)"
SPEC_VOLUMES="/var/lib/archipelago/immich-db:/var/lib/postgresql/data" SPEC_VOLUMES="/var/lib/archipelago/immich-db:/var/lib/postgresql/data"
@ -127,7 +127,7 @@ load_spec_immich_postgres() {
load_spec_immich_redis() { load_spec_immich_redis() {
reset_spec reset_spec
SPEC_NAME="immich_redis" SPEC_NAME="immich_redis"
SPEC_IMAGE="${VALKEY_IMAGE:-docker.io/valkey/valkey:8}" SPEC_IMAGE="${VALKEY_IMAGE}"
SPEC_NETWORK="bridge" SPEC_NETWORK="bridge"
SPEC_MEMORY="$(mem_limit immich_redis)" SPEC_MEMORY="$(mem_limit immich_redis)"
SPEC_TIER="0" SPEC_TIER="0"
@ -140,7 +140,7 @@ load_spec_immich_redis() {
load_spec_bitcoin-knots() { load_spec_bitcoin-knots() {
reset_spec reset_spec
SPEC_NAME="bitcoin-knots" 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_NETWORK="archy-net"
SPEC_PORTS="8332:8332 8333:8333" SPEC_PORTS="8332:8332 8333:8333"
SPEC_VOLUMES="/var/lib/archipelago/bitcoin:/home/bitcoin/.bitcoin" SPEC_VOLUMES="/var/lib/archipelago/bitcoin:/home/bitcoin/.bitcoin"
@ -160,7 +160,7 @@ load_spec_bitcoin-knots() {
load_spec_electrumx() { load_spec_electrumx() {
reset_spec reset_spec
SPEC_NAME="electrumx" SPEC_NAME="electrumx"
SPEC_IMAGE="docker.io/lukechilds/electrumx:v1.16.0" SPEC_IMAGE="${ELECTRUMX_IMAGE}"
SPEC_NETWORK="archy-net" SPEC_NETWORK="archy-net"
SPEC_PORTS="50001:50001" SPEC_PORTS="50001:50001"
SPEC_VOLUMES="/var/lib/archipelago/electrumx:/data" SPEC_VOLUMES="/var/lib/archipelago/electrumx:/data"
@ -178,7 +178,7 @@ load_spec_electrumx() {
load_spec_lnd() { load_spec_lnd() {
reset_spec reset_spec
SPEC_NAME="lnd" SPEC_NAME="lnd"
SPEC_IMAGE="${LND_IMAGE:-docker.io/lightninglabs/lnd:v0.18.5-beta}" SPEC_IMAGE="${LND_IMAGE}"
SPEC_NETWORK="archy-net" SPEC_NETWORK="archy-net"
SPEC_PORTS="9735:9735 10009:10009 8080:8080" SPEC_PORTS="9735:9735 10009:10009 8080:8080"
SPEC_VOLUMES="/var/lib/archipelago/lnd:/root/.lnd" SPEC_VOLUMES="/var/lib/archipelago/lnd:/root/.lnd"
@ -192,7 +192,7 @@ load_spec_lnd() {
load_spec_mempool-api() { load_spec_mempool-api() {
reset_spec reset_spec
SPEC_NAME="mempool-api" 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_NETWORK="archy-net"
SPEC_PORTS="8999:8999" SPEC_PORTS="8999:8999"
SPEC_VOLUMES="/var/lib/archipelago/mempool:/data" SPEC_VOLUMES="/var/lib/archipelago/mempool:/data"
@ -209,7 +209,7 @@ load_spec_mempool-api() {
load_spec_archy-mempool-web() { load_spec_archy-mempool-web() {
reset_spec reset_spec
SPEC_NAME="archy-mempool-web" 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_NETWORK="archy-net"
SPEC_PORTS="4080:8080" SPEC_PORTS="4080:8080"
SPEC_MEMORY="$(mem_limit archy-mempool-web)" SPEC_MEMORY="$(mem_limit archy-mempool-web)"
@ -223,7 +223,7 @@ load_spec_archy-mempool-web() {
load_spec_archy-nbxplorer() { load_spec_archy-nbxplorer() {
reset_spec reset_spec
SPEC_NAME="archy-nbxplorer" SPEC_NAME="archy-nbxplorer"
SPEC_IMAGE="${NBXPLORER_IMAGE:-docker.io/nicolasdorier/nbxplorer:2.5.13}" SPEC_IMAGE="${NBXPLORER_IMAGE}"
SPEC_NETWORK="archy-net" SPEC_NETWORK="archy-net"
SPEC_PORTS="32838:32838" SPEC_PORTS="32838:32838"
SPEC_VOLUMES="/var/lib/archipelago/nbxplorer:/data" SPEC_VOLUMES="/var/lib/archipelago/nbxplorer:/data"
@ -239,7 +239,7 @@ load_spec_archy-nbxplorer() {
load_spec_btcpay-server() { load_spec_btcpay-server() {
reset_spec reset_spec
SPEC_NAME="btcpay-server" SPEC_NAME="btcpay-server"
SPEC_IMAGE="${BTCPAY_IMAGE:-docker.io/btcpayserver/btcpayserver:1.13.7}" SPEC_IMAGE="${BTCPAY_IMAGE}"
SPEC_NETWORK="archy-net" SPEC_NETWORK="archy-net"
SPEC_PORTS="23000:49392" SPEC_PORTS="23000:49392"
SPEC_VOLUMES="/var/lib/archipelago/btcpay:/datadir" SPEC_VOLUMES="/var/lib/archipelago/btcpay:/datadir"
@ -254,7 +254,7 @@ load_spec_btcpay-server() {
load_spec_fedimint() { load_spec_fedimint() {
reset_spec reset_spec
SPEC_NAME="fedimint" SPEC_NAME="fedimint"
SPEC_IMAGE="${FEDIMINT_IMAGE:-docker.io/fedimint/fedimintd:v0.5.1}" SPEC_IMAGE="${FEDIMINT_IMAGE}"
SPEC_NETWORK="archy-net" SPEC_NETWORK="archy-net"
SPEC_PORTS="8173:8173 8174:8174 8175:8175" SPEC_PORTS="8173:8173 8174:8174 8175:8175"
SPEC_VOLUMES="/var/lib/archipelago/fedimint:/data" SPEC_VOLUMES="/var/lib/archipelago/fedimint:/data"
@ -269,7 +269,7 @@ load_spec_fedimint() {
load_spec_fedimint-gateway() { load_spec_fedimint-gateway() {
reset_spec reset_spec
SPEC_NAME="fedimint-gateway" 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_NETWORK="archy-net"
SPEC_PORTS="8176:8176" SPEC_PORTS="8176:8176"
SPEC_VOLUMES="/var/lib/archipelago/fedimint-gateway:/data" SPEC_VOLUMES="/var/lib/archipelago/fedimint-gateway:/data"
@ -293,7 +293,7 @@ load_spec_fedimint-gateway() {
load_spec_immich_server() { load_spec_immich_server() {
reset_spec reset_spec
SPEC_NAME="immich_server" SPEC_NAME="immich_server"
SPEC_IMAGE="ghcr.io/immich-app/immich-server:release" SPEC_IMAGE="${IMMICH_SERVER_IMAGE}"
SPEC_NETWORK="bridge" SPEC_NETWORK="bridge"
SPEC_PORTS="2283:2283" SPEC_PORTS="2283:2283"
SPEC_VOLUMES="/var/lib/archipelago/immich:/usr/src/app/upload" SPEC_VOLUMES="/var/lib/archipelago/immich:/usr/src/app/upload"
@ -311,7 +311,7 @@ load_spec_immich_server() {
load_spec_homeassistant() { load_spec_homeassistant() {
reset_spec reset_spec
SPEC_NAME="homeassistant" SPEC_NAME="homeassistant"
SPEC_IMAGE="${HOMEASSISTANT_IMAGE:-ghcr.io/home-assistant/home-assistant:2024.12}" SPEC_IMAGE="${HOMEASSISTANT_IMAGE}"
SPEC_PORTS="8123:8123" SPEC_PORTS="8123:8123"
SPEC_VOLUMES="/var/lib/archipelago/home-assistant:/config" SPEC_VOLUMES="/var/lib/archipelago/home-assistant:/config"
SPEC_MEMORY="$(mem_limit homeassistant)" SPEC_MEMORY="$(mem_limit homeassistant)"
@ -325,7 +325,7 @@ load_spec_homeassistant() {
load_spec_grafana() { load_spec_grafana() {
reset_spec reset_spec
SPEC_NAME="grafana" SPEC_NAME="grafana"
SPEC_IMAGE="${GRAFANA_IMAGE:-docker.io/grafana/grafana:11.4.0}" SPEC_IMAGE="${GRAFANA_IMAGE}"
SPEC_PORTS="3000:3000" SPEC_PORTS="3000:3000"
SPEC_VOLUMES="/var/lib/archipelago/grafana:/var/lib/grafana" SPEC_VOLUMES="/var/lib/archipelago/grafana:/var/lib/grafana"
SPEC_MEMORY="$(mem_limit grafana)" SPEC_MEMORY="$(mem_limit grafana)"
@ -342,7 +342,7 @@ load_spec_grafana() {
load_spec_uptime-kuma() { load_spec_uptime-kuma() {
reset_spec reset_spec
SPEC_NAME="uptime-kuma" 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_PORTS="3001:3001"
SPEC_VOLUMES="/var/lib/archipelago/uptime-kuma:/app/data" SPEC_VOLUMES="/var/lib/archipelago/uptime-kuma:/app/data"
SPEC_MEMORY="$(mem_limit uptime-kuma)" SPEC_MEMORY="$(mem_limit uptime-kuma)"
@ -356,7 +356,7 @@ load_spec_uptime-kuma() {
load_spec_jellyfin() { load_spec_jellyfin() {
reset_spec reset_spec
SPEC_NAME="jellyfin" SPEC_NAME="jellyfin"
SPEC_IMAGE="${JELLYFIN_IMAGE:-docker.io/jellyfin/jellyfin:10.10.3}" SPEC_IMAGE="${JELLYFIN_IMAGE}"
SPEC_PORTS="8096:8096" SPEC_PORTS="8096:8096"
SPEC_VOLUMES="/var/lib/archipelago/jellyfin/config:/config /var/lib/archipelago/jellyfin/cache:/cache" SPEC_VOLUMES="/var/lib/archipelago/jellyfin/config:/config /var/lib/archipelago/jellyfin/cache:/cache"
SPEC_MEMORY="$(mem_limit jellyfin)" SPEC_MEMORY="$(mem_limit jellyfin)"
@ -369,7 +369,7 @@ load_spec_jellyfin() {
load_spec_photoprism() { load_spec_photoprism() {
reset_spec reset_spec
SPEC_NAME="photoprism" SPEC_NAME="photoprism"
SPEC_IMAGE="${PHOTOPRISM_IMAGE:-docker.io/photoprism/photoprism:240915}" SPEC_IMAGE="${PHOTOPRISM_IMAGE}"
SPEC_PORTS="2342:2342" SPEC_PORTS="2342:2342"
SPEC_VOLUMES="/var/lib/archipelago/photoprism:/photoprism/storage" SPEC_VOLUMES="/var/lib/archipelago/photoprism:/photoprism/storage"
SPEC_MEMORY="$(mem_limit photoprism)" SPEC_MEMORY="$(mem_limit photoprism)"
@ -383,7 +383,7 @@ load_spec_photoprism() {
load_spec_vaultwarden() { load_spec_vaultwarden() {
reset_spec reset_spec
SPEC_NAME="vaultwarden" SPEC_NAME="vaultwarden"
SPEC_IMAGE="${VAULTWARDEN_IMAGE:-docker.io/vaultwarden/server:1.32.5}" SPEC_IMAGE="${VAULTWARDEN_IMAGE}"
SPEC_PORTS="8082:80" SPEC_PORTS="8082:80"
SPEC_VOLUMES="/var/lib/archipelago/vaultwarden:/data" SPEC_VOLUMES="/var/lib/archipelago/vaultwarden:/data"
SPEC_MEMORY="$(mem_limit vaultwarden)" SPEC_MEMORY="$(mem_limit vaultwarden)"
@ -396,7 +396,7 @@ load_spec_vaultwarden() {
load_spec_nextcloud() { load_spec_nextcloud() {
reset_spec reset_spec
SPEC_NAME="nextcloud" SPEC_NAME="nextcloud"
SPEC_IMAGE="${NEXTCLOUD_IMAGE:-docker.io/library/nextcloud:29}" SPEC_IMAGE="${NEXTCLOUD_IMAGE}"
SPEC_PORTS="8085:80" SPEC_PORTS="8085:80"
SPEC_VOLUMES="/var/lib/archipelago/nextcloud:/var/www/html" SPEC_VOLUMES="/var/lib/archipelago/nextcloud:/var/www/html"
SPEC_MEMORY="$(mem_limit nextcloud)" SPEC_MEMORY="$(mem_limit nextcloud)"
@ -409,7 +409,7 @@ load_spec_nextcloud() {
load_spec_searxng() { load_spec_searxng() {
reset_spec reset_spec
SPEC_NAME="searxng" SPEC_NAME="searxng"
SPEC_IMAGE="${SEARXNG_IMAGE:-docker.io/searxng/searxng:2026.3.20-6c7e9c197}" SPEC_IMAGE="${SEARXNG_IMAGE}"
SPEC_PORTS="8888:8080" SPEC_PORTS="8888:8080"
SPEC_MEMORY="$(mem_limit searxng)" SPEC_MEMORY="$(mem_limit searxng)"
SPEC_HEALTH_CMD="curl -sf http://localhost:8080/ || exit 1" SPEC_HEALTH_CMD="curl -sf http://localhost:8080/ || exit 1"
@ -422,7 +422,7 @@ load_spec_searxng() {
load_spec_onlyoffice() { load_spec_onlyoffice() {
reset_spec reset_spec
SPEC_NAME="onlyoffice" SPEC_NAME="onlyoffice"
SPEC_IMAGE="${ONLYOFFICE_IMAGE:-docker.io/onlyoffice/documentserver:8.2}" SPEC_IMAGE="${ONLYOFFICE_IMAGE}"
SPEC_PORTS="9980:80" SPEC_PORTS="9980:80"
SPEC_MEMORY="$(mem_limit onlyoffice)" SPEC_MEMORY="$(mem_limit onlyoffice)"
SPEC_HEALTH_CMD="curl -sf http://localhost:80/ || exit 1" SPEC_HEALTH_CMD="curl -sf http://localhost:80/ || exit 1"
@ -433,7 +433,7 @@ load_spec_onlyoffice() {
load_spec_filebrowser() { load_spec_filebrowser() {
reset_spec reset_spec
SPEC_NAME="filebrowser" SPEC_NAME="filebrowser"
SPEC_IMAGE="${FILEBROWSER_IMAGE:-docker.io/filebrowser/filebrowser:v2}" SPEC_IMAGE="${FILEBROWSER_IMAGE}"
SPEC_PORTS="8083:80" SPEC_PORTS="8083:80"
SPEC_VOLUMES="/var/lib/archipelago/filebrowser:/srv" SPEC_VOLUMES="/var/lib/archipelago/filebrowser:/srv"
SPEC_MEMORY="$(mem_limit filebrowser)" SPEC_MEMORY="$(mem_limit filebrowser)"
@ -446,7 +446,7 @@ load_spec_filebrowser() {
load_spec_nginx-proxy-manager() { load_spec_nginx-proxy-manager() {
reset_spec reset_spec
SPEC_NAME="nginx-proxy-manager" 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_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_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)" SPEC_MEMORY="$(mem_limit nginx-proxy-manager)"
@ -459,7 +459,7 @@ load_spec_nginx-proxy-manager() {
load_spec_portainer() { load_spec_portainer() {
reset_spec reset_spec
SPEC_NAME="portainer" SPEC_NAME="portainer"
SPEC_IMAGE="${PORTAINER_IMAGE:-docker.io/portainer/portainer-ce:2.21.5}" SPEC_IMAGE="${PORTAINER_IMAGE}"
SPEC_PORTS="9000:9000" SPEC_PORTS="9000:9000"
SPEC_VOLUMES="/var/lib/archipelago/portainer:/data /run/user/1000/podman/podman.sock:/var/run/docker.sock" SPEC_VOLUMES="/var/lib/archipelago/portainer:/data /run/user/1000/podman/podman.sock:/var/run/docker.sock"
SPEC_MEMORY="$(mem_limit portainer)" SPEC_MEMORY="$(mem_limit portainer)"
@ -471,7 +471,7 @@ load_spec_portainer() {
load_spec_ollama() { load_spec_ollama() {
reset_spec reset_spec
SPEC_NAME="ollama" SPEC_NAME="ollama"
SPEC_IMAGE="${OLLAMA_IMAGE:-docker.io/ollama/ollama:0.5.4}" SPEC_IMAGE="${OLLAMA_IMAGE}"
SPEC_PORTS="11434:11434" SPEC_PORTS="11434:11434"
SPEC_VOLUMES="/var/lib/archipelago/ollama:/root/.ollama" SPEC_VOLUMES="/var/lib/archipelago/ollama:/root/.ollama"
SPEC_MEMORY="$(mem_limit 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.icon=/assets/img/app-icons/bitcoin-knots.webp" \
--label "com.archipelago.port=8332" \ --label "com.archipelago.port=8332" \
--label "com.archipelago.repo=https://github.com/bitcoinknots/bitcoin" \ --label "com.archipelago.repo=https://github.com/bitcoinknots/bitcoin" \
"${BITCOIN_KNOTS_IMAGE:-docker.io/bitcoinknots/bitcoin:v28.1}" \ "${BITCOIN_KNOTS_IMAGE}" \
-server=1 \ -server=1 \
-txindex=1 \ -txindex=1 \
-rpcallowip=127.0.0.1/32 -rpcallowip=10.88.0.0/16 \ -rpcallowip=127.0.0.1/32 -rpcallowip=10.88.0.0/16 \
@ -74,7 +74,7 @@ mkdir -p "$BUILD_DIR"
# Create Dockerfile # Create Dockerfile
cat > "$BUILD_DIR/Dockerfile" << 'EOF' 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 the static UI
COPY index.html /usr/share/nginx/html/ COPY index.html /usr/share/nginx/html/

View File

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

View File

@ -8,50 +8,13 @@
# No set -e: each section continues even if one fails (idempotent, best-effort). # 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). # Image versions: sourced from /opt/archipelago/image-versions.sh (single source of truth).
# All container image references MUST use the $*_IMAGE variables defined there. # All container image references use the $*_IMAGE variables defined there.
# NOTE: Many container creation lines below still use hardcoded versions instead of # Images pull from the Archipelago app registry (80.71.235.15:3000/archipelago/).
# the $*_IMAGE variables. These must be migrated to use the variables for consistency.
# See the version mismatch list in the planned refactor below.
# #
# --- 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.
# 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. # 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" LOG="/var/log/archipelago-first-boot.log"
DOCKER=podman DOCKER=podman
command -v podman >/dev/null 2>&1 || DOCKER=docker 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 \ --security-opt no-new-privileges:true \
-p 8332:8332 -p 8333:8333 \ -p 8332:8332 -p 8333:8333 \
-v /var/lib/archipelago/bitcoin:/home/bitcoin/.bitcoin \ -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 \ -server=1 $BTC_EXTRA_ARGS \
-rpcallowip=0.0.0.0/0 -rpcbind=0.0.0.0:8332 \ -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 \ -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 \ -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_DATABASE=mempool -e MYSQL_USER=mempool -e "MYSQL_PASSWORD=$MEMPOOL_DB_PASS" \
-e "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_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 wait_for_container "Mempool MariaDB" "echo 'SELECT 1' | $DOCKER exec -i archy-mempool-db mariadb -uroot --password=\"$MYSQL_ROOT_PASS\"" 30
fi fi
MYSQL_CNT=$($DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'mysql-mempool|archy-mempool-db' | head -1) 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 "DAEMON_URL=http://$BITCOIN_RPC_USER:$BITCOIN_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 \
docker.io/lukechilds/electrumx:v1.18.0 2>>"$LOG" || true "$ELECTRUMX_IMAGE" 2>>"$LOG" || true
fi fi
fi fi
track_container "electrumx" 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 "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_ENABLED=true -e DATABASE_HOST="$MYSQL_CNT" -e DATABASE_DATABASE=mempool \
-e DATABASE_USERNAME=mempool -e "DATABASE_PASSWORD=$MEMPOOL_DB_PASS" \ -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 fi
track_container "mempool-api" 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 \ --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 \ --memory=$(mem_limit archy-mempool-web) --network archy-net \
-p 4080:8080 -e FRONTEND_HTTP_PORT=8080 -e BACKEND_MAINNET_HTTP_HOST=mempool-api \ -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 fi
track_container "archy-mempool-web" 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 \ --memory=$(mem_limit archy-btcpay-db) --network archy-net \
-v /var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data \ -v /var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data \
-e POSTGRES_DB=btcpay -e POSTGRES_USER=btcpay -e "POSTGRES_PASSWORD=$BTCPAY_DB_PASS" \ -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 wait_for_container "BTCPay PostgreSQL" "$DOCKER exec archy-btcpay-db pg_isready -U postgres" 30
fi fi
track_container "archy-btcpay-db" 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_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_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' \ -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
fi fi
track_container "archy-nbxplorer" 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_BTCRPCURL=http://bitcoin-knots:8332 \
-e "BTCPAY_BTCRPCUSER=$BITCOIN_RPC_USER" -e "BTCPAY_BTCRPCPASSWORD=$BITCOIN_RPC_PASS" \ -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' \ -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 fi
track_container "btcpay-server" track_container "btcpay-server"
@ -532,7 +495,7 @@ LNDCONF
--security-opt no-new-privileges:true \ --security-opt no-new-privileges:true \
-p 9735:9735 -p 10009:10009 -p 8080:8080 \ -p 9735:9735 -p 10009:10009 -p 8080:8080 \
-v /var/lib/archipelago/lnd:/root/.lnd \ -v /var/lib/archipelago/lnd:/root/.lnd \
docker.io/lightninglabs/lnd:v0.18.4-beta 2>>"$LOG" || true "$LND_IMAGE" 2>>"$LOG" || true
fi fi
track_container "lnd" 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_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_P2P_URL=fedimint://"$TARGET_IP":8173 -e FM_API_URL=ws://"$TARGET_IP":8174 \
-e FM_BITCOIND_URL=http://"$TARGET_IP":8332 \ -e FM_BITCOIND_URL=http://"$TARGET_IP":8332 \
docker.io/fedimint/fedimintd:v0.10.0 2>>"$LOG" || true "$FEDIMINT_IMAGE" 2>>"$LOG" || true
fi fi
track_container "fedimint" 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 /var/lib/archipelago/fedimint-gateway:/data \
-v "$LND_CERT":/lnd/tls.cert:ro \ -v "$LND_CERT":/lnd/tls.cert:ro \
-v "$LND_MACAROON":/lnd/admin.macaroon: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 \ gatewayd --data-dir /data --listen 0.0.0.0:8176 \
--bcrypt-password-hash "$FEDI_HASH" \ --bcrypt-password-hash "$FEDI_HASH" \
--network bitcoin --bitcoind-url http://"$TARGET_IP":8332 \ --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 \ --security-opt no-new-privileges:true \
-p 8176:8176 -p 9737:9737 \ -p 8176:8176 -p 9737:9737 \
-v /var/lib/archipelago/fedimint-gateway:/data \ -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 \ gatewayd --data-dir /data --listen 0.0.0.0:8176 \
--bcrypt-password-hash "$FEDI_HASH" \ --bcrypt-password-hash "$FEDI_HASH" \
--network bitcoin --bitcoind-url http://"$TARGET_IP":8332 \ --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 \ --security-opt no-new-privileges:true \
-p 8123:8123 -v /var/lib/archipelago/home-assistant:/config \ -p 8123:8123 -v /var/lib/archipelago/home-assistant:/config \
-e TZ=UTC \ -e TZ=UTC \
docker.io/homeassistant/home-assistant:2024.1 2>>"$LOG" || true "$HOMEASSISTANT_IMAGE" 2>>"$LOG" || true
fi fi
track_container "homeassistant" 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 \ --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 \ -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 \ -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 fi
track_container "grafana" track_container "grafana"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q uptime-kuma; then 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 \ --security-opt no-new-privileges:true \
-p 3001:3001 -v /var/lib/archipelago/uptime-kuma:/app/data \ -p 3001:3001 -v /var/lib/archipelago/uptime-kuma:/app/data \
-e TZ=UTC \ -e TZ=UTC \
docker.io/louislam/uptime-kuma:1 2>>"$LOG" || true "$UPTIME_KUMA_IMAGE" 2>>"$LOG" || true
fi fi
track_container "uptime-kuma" track_container "uptime-kuma"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q jellyfin; then 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 \ -p 8096:8096 \
-v /var/lib/archipelago/jellyfin/config:/config \ -v /var/lib/archipelago/jellyfin/config:/config \
-v /var/lib/archipelago/jellyfin/cache:/cache \ -v /var/lib/archipelago/jellyfin/cache:/cache \
docker.io/jellyfin/jellyfin:10.8.13 2>>"$LOG" || true "$JELLYFIN_IMAGE" 2>>"$LOG" || true
fi fi
track_container "jellyfin" track_container "jellyfin"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q photoprism; then 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 \ --security-opt no-new-privileges:true \
-p 2342:2342 -v /var/lib/archipelago/photoprism:/photoprism/storage \ -p 2342:2342 -v /var/lib/archipelago/photoprism:/photoprism/storage \
-e PHOTOPRISM_ADMIN_PASSWORD=archipelago -e PHOTOPRISM_DEFAULT_LOCALE=en \ -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 fi
track_container "photoprism" track_container "photoprism"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q ollama; then 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 \ --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 \ --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 \ -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 fi
track_container "ollama" track_container "ollama"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q vaultwarden; then 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 \ --cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \ --security-opt no-new-privileges:true \
-p 8082:80 -v /var/lib/archipelago/vaultwarden:/data \ -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 fi
track_container "vaultwarden" track_container "vaultwarden"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q nextcloud; then 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 \ --cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \ --security-opt no-new-privileges:true \
-p 8085:80 -v /var/lib/archipelago/nextcloud:/var/www/html \ -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 fi
track_container "nextcloud" track_container "nextcloud"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q searxng; then 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 \ --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 \ --read-only --tmpfs /tmp:rw,noexec,nosuid,size=256m --tmpfs /run:rw,noexec,nosuid,size=64m \
-p 8888:8080 \ -p 8888:8080 \
"${SEARXNG_IMAGE:-docker.io/searxng/searxng:2024.11.17}" 2>>"$LOG" || true "${SEARXNG_IMAGE}" 2>>"$LOG" || true
fi fi
track_container "searxng" track_container "searxng"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q onlyoffice; then 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 \ --cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \ --security-opt no-new-privileges:true \
-p 9980:80 \ -p 9980:80 \
docker.io/onlyoffice/documentserver:7.5.1 2>>"$LOG" || true "$ONLYOFFICE_IMAGE" 2>>"$LOG" || true
fi fi
track_container "onlyoffice" track_container "onlyoffice"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q filebrowser; then 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 \ --health-cmd="curl -sf http://localhost:80/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit filebrowser) \ --memory=$(mem_limit filebrowser) \
-p 8083:80 -v /var/lib/archipelago/filebrowser:/srv \ -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 fi
track_container "filebrowser" track_container "filebrowser"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q nginx-proxy-manager; then 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 \ -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/data:/data \
-v /var/lib/archipelago/nginx-proxy-manager/letsencrypt:/etc/letsencrypt \ -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 fi
track_container "nginx-proxy-manager" track_container "nginx-proxy-manager"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q portainer; then 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 \ -p 9000:9000 \
-v /var/lib/archipelago/portainer:/data \ -v /var/lib/archipelago/portainer:/data \
-v /var/run/podman/podman.sock:/var/run/docker.sock \ -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 fi
track_container "portainer" track_container "portainer"
if ! $DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q tailscale; then 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 \ --tmpfs /tmp \
-v /var/lib/archipelago/tailscale:/var/lib/tailscale \ -v /var/lib/archipelago/tailscale:/var/lib/tailscale \
-e TS_STATE_DIR=/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 sh -c 'tailscale web --listen 0.0.0.0:8240 & exec tailscaled' 2>>"$LOG" || true
fi fi
track_container "tailscale" 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 \ --health-cmd="curl -sf http://localhost:8080/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit nostr-rs-relay) \ --memory=$(mem_limit nostr-rs-relay) \
-p 7047:7047 -v /var/lib/archipelago/nostr-rs-relay:/data \ -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
fi fi
if $DOCKER images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q 'strfry'; then 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 \ --health-cmd="curl -sf http://localhost:7777/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--memory=$(mem_limit strfry) \ --memory=$(mem_limit strfry) \
-p 7777:7777 -v /var/lib/archipelago/strfry:/data \ -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
fi fi

View File

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

View File

@ -5,64 +5,77 @@
# 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
# Archipelago app registry
ARCHY_REGISTRY="80.71.235.15:3000/archipelago"
# Bitcoin stack # Bitcoin stack
BITCOIN_KNOTS_IMAGE="docker.io/bitcoinknots/bitcoin:28.1" BITCOIN_KNOTS_IMAGE="$ARCHY_REGISTRY/bitcoin-knots:28.1"
LND_IMAGE="docker.io/lightninglabs/lnd:v0.18.5-beta" LND_IMAGE="$ARCHY_REGISTRY/lnd:v0.18.5-beta"
ELECTRUMX_IMAGE="docker.io/lukechilds/electrumx:v1.18.0" ELECTRUMX_IMAGE="$ARCHY_REGISTRY/electrumx:v1.18.0"
# Mempool stack # Mempool stack
MEMPOOL_BACKEND_IMAGE="docker.io/mempool/backend:v3.0.0" MEMPOOL_BACKEND_IMAGE="$ARCHY_REGISTRY/mempool-backend:v3.0.0"
MEMPOOL_WEB_IMAGE="docker.io/mempool/frontend:v3.0.0" MEMPOOL_WEB_IMAGE="$ARCHY_REGISTRY/mempool-frontend:v3.0.0"
MARIADB_IMAGE="docker.io/library/mariadb:11.4.10" MARIADB_IMAGE="$ARCHY_REGISTRY/mariadb:11.4.10"
# BTCPay # BTCPay
BTCPAY_IMAGE="docker.io/btcpayserver/btcpayserver:1.13.7" BTCPAY_IMAGE="$ARCHY_REGISTRY/btcpayserver:1.13.7"
NBXPLORER_IMAGE="docker.io/nicolasdorier/nbxplorer:2.6.0" NBXPLORER_IMAGE="$ARCHY_REGISTRY/nbxplorer:2.6.0"
POSTGRES_IMAGE="docker.io/library/postgres:15.17" POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:15.17"
BTCPAY_POSTGRES_IMAGE="docker.io/library/postgres:15.17" BTCPAY_POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:15.17"
# Apps # Apps
HOMEASSISTANT_IMAGE="ghcr.io/home-assistant/home-assistant:2024.12.5" HOMEASSISTANT_IMAGE="$ARCHY_REGISTRY/home-assistant:2024.12.5"
GRAFANA_IMAGE="docker.io/grafana/grafana:11.4.0" GRAFANA_IMAGE="$ARCHY_REGISTRY/grafana:11.4.0"
UPTIME_KUMA_IMAGE="docker.io/louislam/uptime-kuma:1.23.17" UPTIME_KUMA_IMAGE="$ARCHY_REGISTRY/uptime-kuma:1.23.17"
JELLYFIN_IMAGE="docker.io/jellyfin/jellyfin:10.10.3" JELLYFIN_IMAGE="$ARCHY_REGISTRY/jellyfin:10.10.3"
PHOTOPRISM_IMAGE="docker.io/photoprism/photoprism:240915" PHOTOPRISM_IMAGE="$ARCHY_REGISTRY/photoprism:240915"
OLLAMA_IMAGE="docker.io/ollama/ollama:0.5.4" OLLAMA_IMAGE="$ARCHY_REGISTRY/ollama:0.5.4"
VAULTWARDEN_IMAGE="docker.io/vaultwarden/server:1.32.5" VAULTWARDEN_IMAGE="$ARCHY_REGISTRY/vaultwarden:1.32.5"
NEXTCLOUD_IMAGE="docker.io/library/nextcloud:29.0.16" NEXTCLOUD_IMAGE="$ARCHY_REGISTRY/nextcloud:29.0.16"
SEARXNG_IMAGE="docker.io/searxng/searxng:2026.3.20-6c7e9c197" SEARXNG_IMAGE="$ARCHY_REGISTRY/searxng:2026.3.20-6c7e9c197"
ONLYOFFICE_IMAGE="docker.io/onlyoffice/documentserver:8.2.3.1" ONLYOFFICE_IMAGE="$ARCHY_REGISTRY/onlyoffice:8.2.3.1"
FILEBROWSER_IMAGE="docker.io/filebrowser/filebrowser:v2.27.0" FILEBROWSER_IMAGE="$ARCHY_REGISTRY/filebrowser:v2.27.0"
NPM_IMAGE="docker.io/jc21/nginx-proxy-manager:2.14.0" NPM_IMAGE="$ARCHY_REGISTRY/nginx-proxy-manager:2.14.0"
PORTAINER_IMAGE="docker.io/portainer/portainer-ce:2.21.5" PORTAINER_IMAGE="$ARCHY_REGISTRY/portainer:2.21.5"
# Networking # Networking
TAILSCALE_IMAGE="docker.io/tailscale/tailscale:v1.78.3" TAILSCALE_IMAGE="$ARCHY_REGISTRY/tailscale:v1.78.3"
ALPINE_TOR_IMAGE="docker.io/andrius/alpine-tor:0.4.8.13" ALPINE_TOR_IMAGE="$ARCHY_REGISTRY/alpine-tor:0.4.8.13"
ADGUARDHOME_IMAGE="docker.io/adguard/adguardhome:v0.107.55" ADGUARDHOME_IMAGE="$ARCHY_REGISTRY/adguardhome:v0.107.55"
# Fedimint # Fedimint
FEDIMINT_IMAGE="docker.io/fedimint/fedimintd:v0.10.0" FEDIMINT_IMAGE="$ARCHY_REGISTRY/fedimintd:v0.10.0"
FEDIMINT_GATEWAY_IMAGE="docker.io/fedimint/gatewayd:v0.10.0" FEDIMINT_GATEWAY_IMAGE="$ARCHY_REGISTRY/gatewayd:v0.10.0"
# Media # Media
REDIS_IMAGE="docker.io/library/redis:7.4.8" REDIS_IMAGE="$ARCHY_REGISTRY/redis:7.4.8"
# Valkey (general purpose) # Valkey (general purpose)
VALKEY_IMAGE="docker.io/valkey/valkey:8.1.6" VALKEY_IMAGE="$ARCHY_REGISTRY/valkey:8.1.6"
# Nostr # Nostr
NOSTR_RS_RELAY_IMAGE="docker.io/scsibug/nostr-rs-relay:0.9.0" NOSTR_RS_RELAY_IMAGE="$ARCHY_REGISTRY/nostr-rs-relay:0.9.0"
STRFRY_IMAGE="docker.io/pluja/strfry:1.0.4" STRFRY_IMAGE="$ARCHY_REGISTRY/strfry:1.0.4"
# IndeedHub stack (local builds use :local tag, not :latest) # IndeedHub stack (local builds use :local tag, not :latest)
MINIO_IMAGE="docker.io/minio/minio:RELEASE.2024-11-07T00-52-20Z" MINIO_IMAGE="$ARCHY_REGISTRY/minio:RELEASE.2024-11-07T00-52-20Z"
INDEEDHUB_POSTGRES_IMAGE="docker.io/library/postgres:16.13-alpine" INDEEDHUB_POSTGRES_IMAGE="$ARCHY_REGISTRY/postgres:16.13-alpine"
INDEEDHUB_REDIS_IMAGE="docker.io/library/redis:7.4.8-alpine" INDEEDHUB_REDIS_IMAGE="$ARCHY_REGISTRY/redis:7.4.8-alpine"
# DWN (Decentralized Web Node) # 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 # 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 # Check trusted registry
TRUSTED=false 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 if echo "$IMAGE" | grep -q "$reg"; then
TRUSTED=true TRUSTED=true
break break