dyndns-docker/CLAUDE.md

4.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Docker-based Dynamic DNS client for Hetzner DNS (and 50+ other providers) using qmcgaw/ddns-updater - a universal, production-ready DDNS solution with web UI.

Core Components:

  • docker-compose.yml: Service configuration using qmcgaw/ddns-updater image
  • data/config.json: DDNS configuration (domains, tokens, providers)
  • config.json.example: Configuration template for Hetzner setup

Development Commands

Docker Operations

Start the service:

docker-compose up -d

View logs:

docker-compose logs -f

Restart service:

docker-compose restart

Stop service:

docker-compose down

Check status:

docker-compose ps

Configuration Management

Create initial config:

mkdir -p data
cp config.json.example data/config.json
# Edit data/config.json with your credentials

Validate config JSON:

cat data/config.json | jq .

Get Hetzner Zone ID via API:

curl -H "Auth-API-Token: YOUR_TOKEN" https://dns.hetzner.com/api/v1/zones

Web UI

Access Web UI: Open browser to http://localhost:8000

The Web UI shows:

  • Current IP status
  • Last update timestamp
  • Update history
  • Errors and warnings
  • Per-domain status

Architecture

Application Flow

  1. Initialization: Load configuration from data/config.json
  2. Main Loop:
    • Get current public IP (IPv4/IPv6)
    • Compare with DNS records for each configured domain
    • Update DNS if IP has changed
    • Wait for configured period (default: 5 minutes)
    • Repeat

Configuration Structure

Configuration is in JSON format at data/config.json:

{
  "settings": [
    {
      "provider": "hetzner",
      "zone_identifier": "zone_id",
      "domain": "example.com",
      "host": "@",
      "ttl": 60,
      "token": "api_token",
      "ip_version": "ipv4"
    }
  ]
}

Key Parameters:

  • provider: DNS provider name (hetzner, cloudflare, duckdns, etc.)
  • zone_identifier: Hetzner DNS Zone ID
  • domain: Base domain name
  • host: Subdomain or @ for root
  • ttl: Time-to-live in seconds
  • token: Hetzner API token with DNS edit permissions
  • ip_version: ipv4, ipv6, or ipv4 or ipv6

Multi-Domain Support

Add multiple entries in the settings array to manage multiple domains or subdomains.

Environment Variables

Optional variables in .env:

  • PERIOD: Update check interval (default: 5m)
  • LOG_LEVEL: Logging verbosity (debug, info, warning, error)

Versioning Strategy

This project uses a simplified versioning scheme:

  • 0.1: Large changes (new features, breaking changes)
  • 0.0.1: Small changes (bugfixes, minor improvements)
  • 1.x: Major releases (only by explicit instruction)

When making changes:

  1. Update CHANGELOG.md with the change description
  2. Increment version according to change size
  3. Work in feature branches, merge to main when ready

Key Files

  • docker-compose.yml: Service definition using qmcgaw/ddns-updater
  • config.json.example: Template for Hetzner configuration
  • data/config.json: Active configuration (not in git)
  • .env.example: Optional environment variables template
  • CHANGELOG.md: Version history

Security Notes

  • API token is sensitive - never commit data/config.json or .env
  • Container runs with minimal privileges
  • Only ports 8000 (web UI) exposed
  • Use HTTPS reverse proxy for production deployments
  • API token should have minimal required permissions (DNS read/write only)

Troubleshooting

View Web UI status:

# Open http://localhost:8000 in browser

Check container logs:

docker-compose logs --tail=50 -f

Validate configuration:

# Check JSON syntax
cat data/config.json | jq .

Test API connectivity:

# List zones
curl -H "Auth-API-Token: YOUR_TOKEN" https://dns.hetzner.com/api/v1/zones

# List records for a zone
curl -H "Auth-API-Token: YOUR_TOKEN" "https://dns.hetzner.com/api/v1/records?zone_id=ZONE_ID"

Debug mode: Set LOG_LEVEL=debug in .env and restart container.

Container won't start:

  • Check docker-compose logs
  • Verify data/config.json exists and is valid JSON
  • Check port 8000 is not in use

Provider Migration

To switch from Hetzner to another provider:

  1. Check supported providers
  2. Update provider field in data/config.json
  3. Adjust provider-specific fields
  4. Restart: docker-compose restart

No code changes needed - just configuration!

Upstream Documentation