A Python-based Dynamic DNS updater for Cloudflare that automatically updates your DNS records with your current public IP address. Perfect for home servers, self-hosted services, or any situation where you need to keep DNS records synchronized with a changing IP address.
- π Automatic IP Detection: Fetches your current public IPv4 and IPv6 addresses
- π― Smart Updates: Only updates DNS records when IP addresses actually change
- ποΈ Multi-Zone Support: Manage DNS records across multiple Cloudflare zones
- β‘ Efficient Operations: Creates missing records and updates existing ones intelligently
- π Continuous Monitoring: Run once or continuously with configurable intervals
- π‘οΈ Error Resilience: Automatic retry logic with graceful error handling
- Python 3.13+
- Cloudflare account with API access Cloudflare Dashboard
- Domain(s) managed by Cloudflare
-
Clone the repository:
git clone CloudFlare-DDNS cd cloudflare-ddns -
Install dependencies:
# Using uv (recommended) uv sync # Or using pip pip install -r requirements.txt
-
Configure your settings:
cp config.json.example config.json
-
Edit
config.jsonwith your Cloudflare API key and DNS records:{ "api_key": "your_cloudflare_api_token", "update_interval_minutes": 10, "ddns_records": { "your_zone_id": [ { "type": "A", "name": "home.example.com", "proxy": false }, { "type": "AAAA", "name": "home.example.com", "proxy": false } ] } }
python main.pyRuns every 10 minutes (or as configured in config.json)
python main.py --oncePerforms a single update and exits
python main.py --interval 30Runs continuously with 30-minute intervals
{
"api_key": "your_cloudflare_api_token",
"update_interval_minutes": 10,
"ddns_records": {
"zone_id_1": [
{
"type": "A",
"name": "subdomain.example.com",
"proxy": false,
"ttl": 300,
"comment": "Home server A record",
"tags": ["ddns", "home"]
}
],
"zone_id_2": [
{
"type": "AAAA",
"name": "ipv6.example.com",
"proxy": true
}
]
}
}| Field | Type | Required | Description |
|---|---|---|---|
api_key |
string | β | Cloudflare API token with DNS edit permissions |
update_interval_minutes |
number | β | Update interval in minutes (default: 10) |
ddns_records |
object | β | DNS records organized by zone ID |
| Field | Type | Required | Description |
|---|---|---|---|
type |
string | β | Record type: "A" or "AAAA" |
name |
string | β | Full domain name (e.g., "home.example.com") |
proxy |
boolean | β | Enable Cloudflare proxy (default: false) |
ttl |
number | β | TTL in seconds (default: auto) |
comment |
string | β | Record comment for documentation |
tags |
array | β | Array of tags for organization |
- Go to Cloudflare Dashboard
- Click "Create Token"
- Use "Edit zone DNS" template or create custom token with:
- Permissions:
Zone:DNS:Edit - Zone Resources: Include specific zones or all zones
- Permissions:
- Copy the generated token to your
config.json
cloudflare-ddns/
βββ main.py # Main application entry point
βββ ddns.py # DNS record management functions
βββ get_ip.py # IP address detection utilities
βββ settings.py # Configuration and Pydantic models
βββ config.json # Configuration file (create from example)
βββ pyproject.toml # Project dependencies and metadata
βββ uv.lock # Dependency lock file
βββ README.md # This file
main.py: Application entry point with CLI argument parsing and update loopddns.py: Core DNS operations (create, update, list records)get_ip.py: IP address detection from external servicessettings.py: Configuration loading and Pydantic data modelsconfig.json: User configuration file
The codebase uses modern Python practices:
- Async/await for non-blocking operations
- Pydantic models for data validation
- Type hints throughout for better IDE support
- Modular design for easy extension
API Token Errors:
- Verify your API token has
Zone:DNS:Editpermissions - Check that the token includes access to your zones
- Ensure the token hasn't expired
Zone ID Not Found:
- Find your Zone ID in Cloudflare Dashboard β [Your Domain] β Overview β API section (Scroll Down)
- Verify the Zone ID matches exactly in
config.json
DNS Record Not Updating:
- Check that the record name matches exactly (including subdomain)
- Verify record type (
Afor IPv4,AAAAfor IPv6) - Ensure your IP address detection is working
Network Issues:
- The tool uses ipify.org for IP detection
- Check your internet connection and firewall settings
Run with Python's verbose output to see detailed information:
python -v main.py --onceCloudflare DDNS Updater Starting...
==================================================
Mode: Continuous updates every 10 minutes
Press Ctrl+C to stop the updater
Update #1
Time: 2025-08-06 14:30:00
Fetching your public IP address...
Your public IPv4 is: 203.0.113.1, IPv6 is: 2001:db8::1
Updating DNS records...
Updating records for zone ID: 13dfc6deb849d252c89be61630e9a5f8
Existing records: 2, New records: 0
β Record home.example.com (A) already has the correct IP address
β» Updating record home.example.com (AAAA) to new IP address...
β No new records to create for zone ID: 13dfc6deb849d252c89be61630e9a5f8
DNS update completed successfully!
Waiting 10 minutes until next update...
==================================================
This project is open source. Feel free to use, modify, and distribute according to your needs.
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
Made with β€οΈ for the self-hosting community