3.7 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 the Hetzner DNS Console. It automatically detects IP changes and updates DNS records via the Hetzner DNS API.
Core Components:
dyndns.py: Main Python application that handles IP detection and DNS updatesDockerfile: Container configuration for the applicationdocker-compose.yml: Docker Compose setup for easy deployment
Development Commands
Docker Operations
Build the container:
docker-compose build
Start the service:
docker-compose up -d
View logs:
docker-compose logs -f
Restart service:
docker-compose restart
Stop service:
docker-compose down
Rebuild after code changes:
docker-compose up -d --build
Local Development
Run Python script directly (requires Python 3.11+):
# Install dependencies
pip install -r requirements.txt
# Set environment variables or use .env file
export HETZNER_API_TOKEN="your_token"
export DOMAIN="example.com"
export RECORD_NAME="@"
# Run script
python dyndns.py
Test IP detection without updating DNS:
from dyndns import HetznerDynDNS
client = HetznerDynDNS(api_token, domain, record_name)
current_ip = client.get_current_ip()
print(f"Current IP: {current_ip}")
Architecture
Application Flow
- Initialization: Load configuration from environment variables
- Zone Lookup: Auto-detect Hetzner DNS Zone ID if not provided
- Main Loop:
- Get current public IP (via api.ipify.org)
- Fetch existing DNS record from Hetzner API
- Compare IPs and update if changed
- Wait for configured interval (default: 5 minutes)
- Repeat
Hetzner DNS API Integration
The application uses Hetzner's DNS API v1 (https://dns.hetzner.com/api/v1):
- Authentication: Via
Auth-API-Tokenheader - GET /zones: Find zone ID for domain
- GET /records: List DNS records for zone
- POST /records: Create new DNS record
- PUT /records/{id}: Update existing DNS record
Configuration
All configuration is via environment variables (see .env.example):
- Required:
HETZNER_API_TOKEN,DOMAIN - Optional:
RECORD_NAME(default: @),RECORD_TYPE(default: A),CHECK_INTERVAL(default: 300),LOG_LEVEL(default: INFO)
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:
- Update
CHANGELOG.mdwith the change description - Increment version according to change size
- Work in feature branches, merge to main when ready
Key Files
dyndns.py: Core application logic (250+ lines)requirements.txt: Python dependenciesDockerfile: Multi-stage build with non-root userdocker-compose.yml: Service configuration with restart policy.env.example: Configuration templateCHANGELOG.md: Version history
Security Notes
- API token is sensitive - never commit
.envfile - Container runs as non-root user (UID 1000)
- Minimal Python slim image for reduced attack surface
- API token should have minimal required permissions (DNS read/write only)
Troubleshooting
Check if container is running:
docker-compose ps
View recent logs:
docker-compose logs --tail=50
Test API connectivity:
# From host
curl -H "Auth-API-Token: YOUR_TOKEN" https://dns.hetzner.com/api/v1/zones
Debug mode:
Set LOG_LEVEL=DEBUG in .env and restart container.