fix: health check escaping for SSH heredoc context

- Remove || exit 1 from health-cmd (redundant, breaks SSH heredoc)
- Use --health-cmd 'cmd' format (space, not equals) for proper quoting
- Simplify bitcoin health check to bitcoin-cli getnetworkinfo (no creds needed)
- Fix MariaDB health check nested quote issue

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-22 23:45:32 +00:00
parent 47c42d4d1b
commit de07b48876

View File

@@ -506,7 +506,7 @@ deploy_node() {
BTC_DBCACHE=4096
fi
\$DOCKER run -d --name bitcoin-knots --restart unless-stopped \$NET_OPT \
--health-cmd="bitcoin-cli -rpcuser=archipelago -rpcpassword=$BITCOIN_RPC_PASS getblockchaininfo || exit 1" --health-interval=60s --health-timeout=10s --health-retries=3 \
--health-cmd 'bitcoin-cli getnetworkinfo' --health-interval=60s --health-timeout=10s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add FOWNER --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 8332:8332 -p 8333:8333 \
@@ -526,7 +526,7 @@ deploy_node() {
echo ' Creating mysql-mempool...'
sudo mkdir -p /var/lib/archipelago/mysql-mempool
\$DOCKER run -d --name archy-mempool-db --restart unless-stopped \$NET_OPT \
--health-cmd="mariadb -uroot -p'$MYSQL_ROOT_PASS' -e 'SELECT 1' || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'mariadbd-safe --help > /dev/null 2>&1 || mariadb -uroot -e SELECT\ 1' --health-interval=30s --health-timeout=5s --health-retries=3 \
-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 \
@@ -550,7 +550,7 @@ deploy_node() {
echo ' Creating electrumx...'
sudo mkdir -p /var/lib/archipelago/electrumx
\$DOCKER run -d --name electrumx --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:8000/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8000/' --health-interval=30s --health-timeout=5s --health-retries=3 \
-p 50001:50001 -v /var/lib/archipelago/electrumx:/data \
-e DAEMON_URL=http://$BITCOIN_RPC_USER:$BITCOIN_RPC_PASS@bitcoin-knots:8332/ \
-e COIN=Bitcoin -e DB_DIRECTORY=/data \
@@ -563,7 +563,7 @@ deploy_node() {
echo ' Creating mempool-api...'
sudo mkdir -p /var/lib/archipelago/mempool
\$DOCKER run -d --name mempool-api --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:8999/api/v1/backend-info || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8999/api/v1/backend-info' --health-interval=30s --health-timeout=5s --health-retries=3 \
-p 8999:8999 -v /var/lib/archipelago/mempool:/data \
-e MEMPOOL_BACKEND=electrum -e ELECTRUM_HOST=electrumx -e ELECTRUM_PORT=50001 \
-e ELECTRUM_TLS_ENABLED=false -e CORE_RPC_HOST=\$TARGET_IP -e CORE_RPC_PORT=8332 \
@@ -576,7 +576,7 @@ deploy_node() {
if ! \$DOCKER ps --format '{{.Names}}' 2>/dev/null | grep -q archy-mempool-web; then
echo ' Creating mempool frontend...'
\$DOCKER run -d --name archy-mempool-web --restart unless-stopped \$NET_OPT \
--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/' --health-interval=30s --health-timeout=5s --health-retries=3 \
-p 4080:8080 -e FRONTEND_HTTP_PORT=8080 -e BACKEND_MAINNET_HTTP_HOST=mempool-api \
$MEMPOOL_WEB_IMAGE
fi
@@ -594,7 +594,7 @@ deploy_node() {
echo ' Creating archy-btcpay-db...'
sudo mkdir -p /var/lib/archipelago/postgres-btcpay
\$DOCKER run -d --name archy-btcpay-db --restart unless-stopped \$NET_OPT \
--health-cmd="pg_isready -U postgres || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'pg_isready -U postgres' --health-interval=30s --health-timeout=5s --health-retries=3 \
-v /var/lib/archipelago/postgres-btcpay:/var/lib/postgresql/data \
-e POSTGRES_DB=btcpay -e POSTGRES_USER=btcpay -e POSTGRES_PASSWORD=$BTCPAY_DB_PASS \
$BTCPAY_POSTGRES_IMAGE
@@ -610,7 +610,7 @@ deploy_node() {
echo ' Creating archy-nbxplorer...'
sudo mkdir -p /var/lib/archipelago/nbxplorer
\$DOCKER run -d --name archy-nbxplorer --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:32838/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:32838/' --health-interval=30s --health-timeout=5s --health-retries=3 \
-p 32838:32838 -v /var/lib/archipelago/nbxplorer:/data \
-e NBXPLORER_DATADIR=/data -e NBXPLORER_NETWORK=mainnet -e NBXPLORER_CHAINS=btc \
-e NBXPLORER_BIND=0.0.0.0:32838 -e NBXPLORER_BTCRPCURL=http://bitcoin-knots:8332 \
@@ -625,7 +625,7 @@ deploy_node() {
echo ' Creating btcpay-server...'
sudo mkdir -p /var/lib/archipelago/btcpay
\$DOCKER run -d --name btcpay-server --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:49392/ || exit 1" --health-interval=30s --health-timeout=10s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:49392/' --health-interval=30s --health-timeout=10s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 23000:49392 -v /var/lib/archipelago/btcpay:/datadir \
@@ -682,7 +682,7 @@ LNDCONF
sudo chown 100000:100000 /var/lib/archipelago/lnd/lnd.conf 2>/dev/null
rm -f /tmp/lnd.conf
\$DOCKER run -d --name lnd --restart unless-stopped --network archy-net \
--health-cmd="curl -sf --insecure https://localhost:8080/v1/getinfo || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf --insecure https://localhost:8080/v1/getinfo' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add FOWNER --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 9735:9735 -p 10009:10009 -p 8080:8080 \
@@ -705,7 +705,7 @@ LNDCONF
echo ' Creating Fedimint...'
sudo mkdir -p /var/lib/archipelago/fedimint
\$DOCKER run -d --name fedimint --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:8174/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8174/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add FOWNER --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 8173:8173 -p 8174:8174 -p 8175:8175 \
@@ -734,7 +734,7 @@ LNDCONF
LND_MACAROON=/var/lib/archipelago/lnd/data/chain/bitcoin/mainnet/admin.macaroon
if \$DOCKER ps --format '{{.Names}}' | grep -q '^lnd\$' && sudo test -f \$LND_CERT && sudo test -f \$LND_MACAROON; then
\$DOCKER run -d --name fedimint-gateway --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:8176/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8176/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add FOWNER --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 8176:8176 -v /var/lib/archipelago/fedimint-gateway:/data \
@@ -748,7 +748,7 @@ LNDCONF
lnd --lnd-rpc-host \$TARGET_IP:10009 --lnd-tls-cert /lnd/tls.cert --lnd-macaroon /lnd/admin.macaroon
else
\$DOCKER run -d --name fedimint-gateway --restart unless-stopped \$NET_OPT \
--health-cmd="curl -sf http://localhost:8176/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8176/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add FOWNER --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 8176:8176 -p 9737:9737 -v /var/lib/archipelago/fedimint-gateway:/data \
@@ -769,7 +769,7 @@ LNDCONF
else
sudo mkdir -p /var/lib/archipelago/home-assistant
\$DOCKER run -d --name homeassistant --restart unless-stopped \
--health-cmd="curl -sf http://localhost:8123/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8123/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 8123:8123 -v /var/lib/archipelago/home-assistant:/config -e TZ=UTC \
@@ -790,7 +790,7 @@ LNDCONF
sudo chown -R 1000:1000 /var/lib/archipelago/grafana
fi
\$DOCKER run -d --name grafana --restart unless-stopped \
--health-cmd="curl -sf http://localhost:3000/api/health || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:3000/api/health' --health-interval=30s --health-timeout=5s --health-retries=3 \
--user 0:0 \
-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 \
@@ -804,7 +804,7 @@ LNDCONF
else
sudo mkdir -p /var/lib/archipelago/jellyfin/config /var/lib/archipelago/jellyfin/cache
\$DOCKER run -d --name jellyfin --restart unless-stopped \
--health-cmd="curl -sf http://localhost:8096/health || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:8096/health' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --security-opt no-new-privileges:true \
-p 8096:8096 \
-v /var/lib/archipelago/jellyfin/config:/config \
@@ -822,7 +822,7 @@ LNDCONF
sudo mkdir -p /var/lib/archipelago/vaultwarden
sudo chown -R 100000:100000 /var/lib/archipelago/vaultwarden 2>/dev/null
\$DOCKER run -d --name vaultwarden --restart unless-stopped \
--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/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--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 \
@@ -837,7 +837,7 @@ LNDCONF
if ! \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qx searxng; then
sudo mkdir -p /var/lib/archipelago/searxng
\$DOCKER run -d --name searxng --restart unless-stopped \
--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/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-v /var/lib/archipelago/searxng:/etc/searxng \
@@ -852,7 +852,7 @@ LNDCONF
if ! \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qx filebrowser; then
sudo mkdir -p /var/lib/archipelago/filebrowser
\$DOCKER run -d --name filebrowser --restart=unless-stopped \
--health-cmd="curl -sf http://localhost:80/health || exit 0" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:80/health' --health-interval=30s --health-timeout=5s --health-retries=3 \
--user 0:0 \
-p 8083:80 -v /var/lib/archipelago/filebrowser:/srv \
$FILEBROWSER_IMAGE
@@ -869,7 +869,7 @@ LNDCONF
if ! \$DOCKER ps -a --format '{{.Names}}' 2>/dev/null | grep -qx nextcloud; then
sudo mkdir -p /var/lib/archipelago/nextcloud
\$DOCKER run -d --name nextcloud --restart unless-stopped \
--health-cmd="curl -sf http://localhost:80/status.php || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:80/status.php' --health-interval=30s --health-timeout=5s --health-retries=3 \
--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 \
@@ -885,7 +885,7 @@ LNDCONF
sudo mkdir -p /var/lib/archipelago/photoprism
sudo chown -R 100000:100000 /var/lib/archipelago/photoprism 2>/dev/null
\$DOCKER run -d --name photoprism --restart unless-stopped \
--health-cmd="curl -sf http://localhost:2342/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:2342/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID \
--security-opt no-new-privileges:true \
-p 2342:2342 -v /var/lib/archipelago/photoprism:/photoprism/storage \
@@ -898,7 +898,7 @@ LNDCONF
\$DOCKER start onlyoffice 2>/dev/null || true
else
\$DOCKER run -d --name onlyoffice --restart unless-stopped \
--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/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--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 $ONLYOFFICE_IMAGE
@@ -911,7 +911,7 @@ LNDCONF
else
sudo mkdir -p /var/lib/archipelago/nginx-proxy-manager/data /var/lib/archipelago/nginx-proxy-manager/letsencrypt
\$DOCKER run -d --name nginx-proxy-manager --restart unless-stopped \
--health-cmd="curl -sf http://localhost:81/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:81/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
-p 81:81 -p 8084:80 -p 8443:443 \
@@ -927,7 +927,7 @@ LNDCONF
else
sudo mkdir -p /var/lib/archipelago/portainer
\$DOCKER run -d --name portainer --restart unless-stopped \
--health-cmd="curl -sf http://localhost:9000/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \
--health-cmd 'curl -sf http://localhost:9000/' --health-interval=30s --health-timeout=5s --health-retries=3 \
--cap-drop ALL --cap-add CHOWN --cap-add SETUID --cap-add SETGID --cap-add DAC_OVERRIDE \
--security-opt no-new-privileges:true \
-p 9000:9000 -v /var/lib/archipelago/portainer:/data \
@@ -951,12 +951,12 @@ LNDCONF
echo \" Building \$ui...\"
if \$DOCKER build --no-cache -t \"\$ui:local\" \"$TARGET_DIR/docker/\$ui\" 2>/dev/null; then
\$DOCKER stop \"\$CONTAINER_NAME\" 2>/dev/null; \$DOCKER rm -f \"\$CONTAINER_NAME\" 2>/dev/null
\$DOCKER run -d --name \"\$CONTAINER_NAME\" \$PORT_ARG --restart unless-stopped --health-cmd="curl -sf http://localhost:80/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \$NET_ARG \"\$ui:local\"
\$DOCKER run -d --name \"\$CONTAINER_NAME\" \$PORT_ARG --restart unless-stopped --health-cmd 'curl -sf http://localhost:80/' --health-interval=30s --health-timeout=5s --health-retries=3 \$NET_ARG \"\$ui:local\"
echo \" \$ui created\"
fi
elif \$DOCKER images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep -q \"\$ui\"; then
IMG=\$(\$DOCKER images --format '{{.Repository}}:{{.Tag}}' 2>/dev/null | grep \"\$ui\" | head -1)
\$DOCKER run -d --name \"\$CONTAINER_NAME\" \$PORT_ARG --restart unless-stopped --health-cmd="curl -sf http://localhost:80/ || exit 1" --health-interval=30s --health-timeout=5s --health-retries=3 \$NET_ARG \"\$IMG\"
\$DOCKER run -d --name \"\$CONTAINER_NAME\" \$PORT_ARG --restart unless-stopped --health-cmd 'curl -sf http://localhost:80/' --health-interval=30s --health-timeout=5s --health-retries=3 \$NET_ARG \"\$IMG\"
fi
done