This is the Go implementation of the NextDNS IP Updater, providing static binaries for easy deployment without Docker.
- Static binaries with no external dependencies
- Cross-platform support (Linux x64, ARM64, macOS ARM64)
- DNS failure resilience with exponential backoff
- HTTP health server for Kubernetes probes (
/health,/ready,/metrics) - Structured JSON logging
- Configurable update intervals
- Graceful shutdown on SIGTERM/SIGINT
- Automatic builds via GitHub Actions
The Go version now exposes HTTP health endpoints on port 8080 for monitoring and Kubernetes integration:
-
GET /health- Liveness check- Returns 200 OK if the service is healthy
- Returns 503 if no successful updates in 2x the configured interval (indicates stuck state)
- Includes metrics: uptime, update count, error count, last success time
-
GET /ready- Readiness check- Returns 200 OK only after the first successful NextDNS update
- Returns 503 during startup or if the service has never successfully updated
- Used by Kubernetes to determine when the pod is ready to serve
-
GET /metrics- Prometheus metrics- Exposes metrics in Prometheus text format
- Metrics include:
nextdns_updates_total,nextdns_errors_total,nextdns_ready,nextdns_healthy,nextdns_uptime_seconds
Testing health endpoints locally:
curl http://localhost:8080/health
curl http://localhost:8080/ready
curl http://localhost:8080/metricsThe service now includes robust DNS failure handling:
- Startup DNS check: Waits for DNS to be ready before starting updates
- Exponential backoff: Retries DNS lookups with increasing delays (1s → 2s → 4s → ... → 60s)
- Never exits on failure: Keeps retrying indefinitely until DNS works
- Fast recovery: Detects when DNS is restored and resumes normal operation
This makes the service safe to deploy in Kubernetes environments where CoreDNS may not be immediately available during cluster boot (especially in WSL or VM environments).
Download the latest pre-built binaries from the GitHub Releases page.
Available binaries:
nextdns-ip-updater-linux-amd64- Linux x64 static binarynextdns-ip-updater-darwin-arm64- macOS ARM64 static binary
Each release includes:
- Raw binaries
- Compressed tar.gz archives
- SHA256 checksums for verification
- Download the appropriate binary for your platform from the releases page
- Make it executable:
chmod +x nextdns-ip-updater-linux-amd64 # or nextdns-ip-updater-darwin-arm64 - Optionally, move it to a directory in your PATH:
sudo mv nextdns-ip-updater-linux-amd64 /usr/local/bin/nextdns-ip-updater
Configuration is done through environment variables:
NEXTDNS_ENDPOINT: The NextDNS endpoint URL to update (required)- Format:
https://link-ip.nextdns.io/YOUR_ID/YOUR_EXT_ID
- Format:
UPDATE_INTERVAL_SECONDS: Time between updates in seconds (default: 300 seconds / 5 minutes)HEALTH_SERVER_PORT: Port for health endpoints (default: 8080, optional)
export NEXTDNS_ENDPOINT="https://link-ip.nextdns.io/YOUR_ID/YOUR_EXT_ID"
export UPDATE_INTERVAL_SECONDS=300
./nextdns-ip-updater-linux-amd64Create a systemd service file /etc/systemd/system/nextdns-ip-updater.service:
[Unit]
Description=NextDNS IP Updater
After=network.target
[Service]
Type=simple
User=nobody
Group=nobody
Environment=NEXTDNS_ENDPOINT=https://link-ip.nextdns.io/YOUR_ID/YOUR_EXT_ID
Environment=UPDATE_INTERVAL_SECONDS=300
ExecStart=/usr/local/bin/nextdns-ip-updater
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetThen enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable nextdns-ip-updater
sudo systemctl start nextdns-ip-updaterCreate a plist file ~/Library/LaunchAgents/com.nextdns.ip-updater.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.nextdns.ip-updater</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/nextdns-ip-updater</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>NEXTDNS_ENDPOINT</key>
<string>https://link-ip.nextdns.io/YOUR_ID/YOUR_EXT_ID</string>
<key>UPDATE_INTERVAL_SECONDS</key>
<string>300</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/nextdns-ip-updater.log</string>
<key>StandardErrorPath</key>
<string>/tmp/nextdns-ip-updater.log</string>
</dict>
</plist>Then load the service:
launchctl load ~/Library/LaunchAgents/com.nextdns.ip-updater.plist
launchctl start com.nextdns.ip-updaterIf you want to build the binaries yourself:
- Install Go 1.23 or later
- Clone this repository
- Build for your platform:
make build
- Or build for all supported platforms:
make build-all
For development work, see DEVELOPMENT.md for a comprehensive guide.
Quick development commands:
make dev-test # Format, vet, test, and build
make test # Run unit tests
make release-artifacts # Create release-ready artifacts
./test-go-binary.sh # Test with mock serverThe application outputs structured JSON logs to stdout. Example:
{"level":"info","msg":"Starting NextDNS IP updater","endpoint":"https://link-ip.nextdns.io/xxx/yyy","interval_seconds":300,"version":"v0.1.1","build_time":"2025-07-05T16:42:52Z","time":"2025-07-05T16:42:52Z"}
{"level":"info","msg":"Successfully updated NextDNS","endpoint":"https://link-ip.nextdns.io/xxx/yyy","time":"2025-07-05T16:42:52Z"}
{"level":"info","msg":"Update cycle completed","success":true,"time":"2025-07-05T16:42:52Z"}To verify the integrity of downloaded binaries, use the provided SHA256 checksums:
# Download the binary and its checksum
wget https://github.com/nilbot/update-local-wan-ip-nextdns/releases/download/v0.1.1/nextdns-ip-updater-linux-amd64
wget https://github.com/nilbot/update-local-wan-ip-nextdns/releases/download/v0.1.1/nextdns-ip-updater-linux-amd64.sha256
# Verify the checksum
sha256sum -c nextdns-ip-updater-linux-amd64.sha256