From 4bca945f3ca638045a5a5b1599913911f24ae951 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Tue, 7 Jul 2026 04:59:44 -0600 Subject: [PATCH] fix: exclude Docker-created interfaces from swarm advertise address detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The install script's get_private_ip() fallback picked the first RFC1918 address from `ip addr show`, which matches the docker0 bridge (172.17.0.1) when Docker is already installed — an address other swarm nodes can never reach. Exclude docker0/br-*/veth* interfaces so a real host/VPN interface wins, and fall back to the public IP when no private interface exists (e.g. servers with only a public IP). Verified end-to-end in Ubuntu 24.04 and Debian 13 containers (Docker pre-installed, WireGuard-like interface, public IP on eth0), plus the detection logic on Debian 12, AlmaLinux 9, Fedora 44 and openSUSE Leap 15.6. Fixes #153 Co-Authored-By: Claude Fable 5 --- .../docs/content/docs/core/troubleshooting.mdx | 4 ++-- apps/website/public/install.sh | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/apps/docs/content/docs/core/troubleshooting.mdx b/apps/docs/content/docs/core/troubleshooting.mdx index e12b4cd..90c5d9f 100644 --- a/apps/docs/content/docs/core/troubleshooting.mdx +++ b/apps/docs/content/docs/core/troubleshooting.mdx @@ -536,8 +536,8 @@ docker service create \ First, get the private IP of your server for the ADVERTISE_ADDR: ```bash -# Get the private IP of your server -ip addr show | grep -E "inet (192\.168\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.)" | head -n1 | awk '{print $2}' | cut -d/ -f1 +# Get the private IP of your server (excludes Docker-created interfaces like docker0) +ip -o -4 addr show scope global | awk '$2 !~ /^(docker|br-|veth)/ {print $4}' | cut -d/ -f1 | grep -E "^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)" | head -n1 ``` Copy the IP address from the output and use it in the command below. diff --git a/apps/website/public/install.sh b/apps/website/public/install.sh index 90c2e4a..5046a2a 100644 --- a/apps/website/public/install.sh +++ b/apps/website/public/install.sh @@ -196,15 +196,27 @@ install_dokploy() { } get_private_ip() { - ip addr show | grep -E "inet (192\.168\.|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.)" | head -n1 | awk '{print $2}' | cut -d/ -f1 + # Pick the first private (RFC1918) IP from a real interface. Docker-created + # interfaces (docker0, br-*, veth*) are excluded: their IPs (e.g. 172.17.0.1) + # are host-local and never reachable from other swarm nodes. + ip -o -4 addr show scope global \ + | awk '$2 !~ /^(docker|br-|veth)/ {print $4}' \ + | cut -d/ -f1 \ + | grep -E "^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.)" \ + | head -n1 } advertise_addr="${ADVERTISE_ADDR:-$(get_private_ip)}" + # Servers with only a public IP have no private interface: fall back to the public IP if [ -z "$advertise_addr" ]; then - echo "ERROR: We couldn't find a private IP address." + advertise_addr=$(get_ip) + fi + + if [ -z "$advertise_addr" ]; then + echo "ERROR: We couldn't detect your server IP address." echo "Please set the ADVERTISE_ADDR environment variable manually." - echo "Example: export ADVERTISE_ADDR=192.168.1.100" + echo "Example: curl -sSL https://dokploy.com/install.sh | sudo ADVERTISE_ADDR=192.168.1.100 sh" exit 1 fi echo "Using advertise address: $advertise_addr"