From 02471b28ba84ed94e264a4f96bc55fbd36560c33 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Mon, 30 Mar 2026 11:39:23 +0400 Subject: [PATCH] =?UTF-8?q?feat:=20start-voip.sh=20=E2=80=94=20update=20DN?= =?UTF-8?q?S=20locally=20+=20start=20Docker=20stack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Removed dns-updater Docker sidecar (curl not available in alpine) - scripts/start-voip.sh: updates DNS then docker compose up - update-dns.sh: supports --once flag, runs locally with curl - All CF API calls forced to IPv4 (-4 flag) Co-Authored-By: Claude Opus 4.6 (1M context) --- warzone/deploy/docker/docker-compose.yml | 11 ----- warzone/deploy/docker/update-dns.sh | 60 ++++++++++++------------ warzone/scripts/start-voip.sh | 35 ++++++++++++++ 3 files changed, 65 insertions(+), 41 deletions(-) create mode 100755 warzone/scripts/start-voip.sh diff --git a/warzone/deploy/docker/docker-compose.yml b/warzone/deploy/docker/docker-compose.yml index b1c095a..7ccaa1a 100644 --- a/warzone/deploy/docker/docker-compose.yml +++ b/warzone/deploy/docker/docker-compose.yml @@ -82,17 +82,6 @@ services: networks: - backend - # ─── Dynamic DNS updater (keeps A + AAAA current) ─── - dns-updater: - image: python:3-alpine - restart: unless-stopped - volumes: - - ./update-dns.sh:/update-dns.sh:ro - secrets: - - cf_api_token - entrypoint: ["/bin/sh", "-c", "apk add --no-cache curl > /dev/null 2>&1 && /bin/sh /update-dns.sh"] - environment: - DNS_UPDATE_INTERVAL: "300" # 5 minutes secrets: cf_api_token: diff --git a/warzone/deploy/docker/update-dns.sh b/warzone/deploy/docker/update-dns.sh index 569cedf..f9adc8b 100755 --- a/warzone/deploy/docker/update-dns.sh +++ b/warzone/deploy/docker/update-dns.sh @@ -1,43 +1,48 @@ -#!/bin/sh +#!/bin/bash # Updates voip.manko.yoga DNS records with current public IPs. -# Runs once on startup, then every 5 minutes. -# Reads CF token from /run/secrets/cf_api_token or CF_API_TOKEN env. +# Usage: +# ./update-dns.sh Loop every 5 minutes +# ./update-dns.sh --once Run once and exit +# +# Reads CF_API_TOKEN env var or deploy/docker/cf_api_token.txt DOMAIN="voip.manko.yoga" ZONE="manko.yoga" INTERVAL="${DNS_UPDATE_INTERVAL:-300}" get_token() { - if [ -f /run/secrets/cf_api_token ]; then + if [ -n "${CF_API_TOKEN:-}" ]; then + echo "$CF_API_TOKEN" + elif [ -f /run/secrets/cf_api_token ]; then cat /run/secrets/cf_api_token | tr -d '\n' else - echo "$CF_API_TOKEN" + echo "ERROR: no CF token" >&2 + exit 1 fi } get_zone_id() { - curl -s "https://api.cloudflare.com/client/v4/zones?name=$ZONE" \ + curl -4 -s "https://api.cloudflare.com/client/v4/zones?name=$ZONE" \ -H "Authorization: Bearer $(get_token)" | \ python3 -c "import sys,json; print(json.load(sys.stdin)['result'][0]['id'])" 2>/dev/null } get_public_ipv4() { curl -4 -s --connect-timeout 5 https://api.ipify.org 2>/dev/null || \ - curl -4 -s --connect-timeout 5 https://ifconfig.me 2>/dev/null + curl -4 -s --connect-timeout 5 https://ifconfig.me 2>/dev/null || echo "" } get_public_ipv6() { curl -6 -s --connect-timeout 5 https://api6.ipify.org 2>/dev/null || \ - curl -6 -s --connect-timeout 5 https://ifconfig.co 2>/dev/null + curl -6 -s --connect-timeout 5 https://ifconfig.co 2>/dev/null || echo "" } upsert_record() { local zone_id="$1" type="$2" content="$3" token token=$(get_token) - # Check existing local existing - existing=$(curl -s "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?name=$DOMAIN&type=$type" \ + existing=$(curl -4 -s "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?name=$DOMAIN&type=$type" \ -H "Authorization: Bearer $token") local rec_id current @@ -50,13 +55,13 @@ upsert_record() { fi if [ -n "$rec_id" ]; then - curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$rec_id" \ + curl -4 -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$rec_id" \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ --data "{\"type\":\"$type\",\"name\":\"$DOMAIN\",\"content\":\"$content\",\"ttl\":120,\"proxied\":false}" > /dev/null echo " $type: $current -> $content (updated)" else - curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records" \ + curl -4 -s -X POST "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records" \ -H "Authorization: Bearer $token" \ -H "Content-Type: application/json" \ --data "{\"type\":\"$type\",\"name\":\"$DOMAIN\",\"content\":\"$content\",\"ttl\":120,\"proxied\":false}" > /dev/null @@ -65,34 +70,29 @@ upsert_record() { } update() { - echo "[$(date -u +%H:%M:%S)] Checking DNS for $DOMAIN..." + echo "[$(date -u +%H:%M:%S)] Updating DNS for $DOMAIN..." local zone_id zone_id=$(get_zone_id) if [ -z "$zone_id" ]; then echo " ERROR: cannot get zone ID" - return + return 1 fi local ipv4 ipv6 ipv4=$(get_public_ipv4) ipv6=$(get_public_ipv6) - if [ -n "$ipv4" ]; then - upsert_record "$zone_id" "A" "$ipv4" - else - echo " A: no IPv4 detected" - fi - - if [ -n "$ipv6" ]; then - upsert_record "$zone_id" "AAAA" "$ipv6" - else - echo " AAAA: no IPv6 detected" - fi + [ -n "$ipv4" ] && upsert_record "$zone_id" "A" "$ipv4" || echo " A: no IPv4" + [ -n "$ipv6" ] && upsert_record "$zone_id" "AAAA" "$ipv6" || echo " AAAA: no IPv6" } -# Run immediately, then loop -update -while true; do - sleep "$INTERVAL" +# Main +if [ "${1:-}" = "--once" ]; then update -done +else + update + while true; do + sleep "$INTERVAL" + update + done +fi diff --git a/warzone/scripts/start-voip.sh b/warzone/scripts/start-voip.sh new file mode 100755 index 0000000..97da304 --- /dev/null +++ b/warzone/scripts/start-voip.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -euo pipefail + +# Start featherChat Docker stack + update DNS. +# Usage: ./scripts/start-voip.sh + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" +DOCKER_DIR="$PROJECT_DIR/deploy/docker" +DNS_SCRIPT="$DOCKER_DIR/update-dns.sh" +CF_TOKEN_FILE="$DOCKER_DIR/cf_api_token.txt" + +# Check CF token +if [ ! -f "$CF_TOKEN_FILE" ]; then + echo "ERROR: $CF_TOKEN_FILE not found" + echo " echo 'YOUR_CF_TOKEN' > $CF_TOKEN_FILE" + exit 1 +fi + +export CF_API_TOKEN=$(cat "$CF_TOKEN_FILE" | tr -d '\n') + +# Update DNS first +echo "=== Updating DNS ===" +bash "$DNS_SCRIPT" --once + +# Start Docker stack +echo "" +echo "=== Starting Docker stack ===" +cd "$DOCKER_DIR" +docker compose up -d + +echo "" +echo "=== Running ===" +echo "URL: https://voip.manko.yoga" +echo "Logs: docker compose -f $DOCKER_DIR/docker-compose.yml logs -f"