-
Notifications
You must be signed in to change notification settings - Fork 0
DDNS
Dynamic DNS updater with multi-provider support and external IP monitoring. Automatically detects your public IP address changes and updates DNS records across multiple DDNS providers.
| Property | Value |
|---|---|
| Port | 3217 |
| Category | networking |
| Multi-App |
source_account_id (UUID) |
| Min nself | 0.4.8 |
nself plugin run ddns init
nself plugin run ddns server- Multi-Provider Support - Works with DuckDNS, Cloudflare, No-IP, and Dynu
- Automatic IP Detection - Monitors external IP changes automatically
- Update Scheduling - Configurable check intervals (default: 5 minutes)
- Update History - Tracks all DNS update attempts with success/failure status
- Provider Flexibility - Easy to add new DDNS providers
- Reliable Updates - Retry logic and error handling for network failures
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
| Variable | Default | Description |
|---|---|---|
DDNS_PLUGIN_PORT |
3217 |
Server port |
DDNS_PROVIDER |
- | DNS provider name (duckdns, cloudflare, noip, dynu) |
DDNS_DOMAIN |
- | Domain/hostname to update |
DDNS_TOKEN |
- | Provider API token/key |
DDNS_CHECK_INTERVAL |
300 |
IP check interval in seconds (5 minutes) |
DDNS_CLOUDFLARE_API_KEY |
- | Cloudflare API key (if using Cloudflare provider) |
DDNS_CLOUDFLARE_ZONE_ID |
- | Cloudflare zone ID (if using Cloudflare provider) |
| Provider | Type | Configuration Required |
|---|---|---|
duckdns |
Free DDNS |
DDNS_DOMAIN, DDNS_TOKEN
|
cloudflare |
DNS Service |
DDNS_DOMAIN, DDNS_CLOUDFLARE_API_KEY, DDNS_CLOUDFLARE_ZONE_ID
|
noip |
Free/Paid DDNS |
DDNS_DOMAIN, DDNS_TOKEN
|
dynu |
Free DDNS |
DDNS_DOMAIN, DDNS_TOKEN
|
# Install plugin
nself plugin install ddns
# Initialize database
nself plugin run ddns init
# Start server
nself plugin run ddns server| Command | Description |
|---|---|
init |
Initialize database schema (2 tables) |
server |
Start the HTTP API server (-p/--port) |
status |
Show current IP address and domain status |
update |
Force an immediate DNS update |
providers |
List available DNS providers |
history |
Show DNS update history (--limit) |
stats |
Show DDNS statistics (total updates, success rate, last update) |
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/ready |
Readiness check (DB) |
| Method | Path | Description |
|---|---|---|
GET |
/api/ddns/status |
Get current IP and configured domains |
POST |
/api/ddns/update |
Force DNS update (body: provider?, domain?, ip?) |
GET |
/api/ddns/providers |
List available providers with configuration status |
GET |
/api/ddns/history |
Get update history (query: limit?, offset?, provider?, status?) |
GET |
/api/ddns/config |
Get current configuration |
PUT |
/api/ddns/config |
Update configuration (body: provider?, domain?, token?, check_interval?) |
| Event | Description |
|---|---|
ddns.ip.detected |
External IP address detected |
ddns.ip.changed |
IP address changed from previous value |
ddns.update.started |
DNS update initiated |
ddns.update.success |
DNS update succeeded |
ddns.update.failed |
DNS update failed |
ddns.config.updated |
Configuration changed |
Stores DDNS provider configuration.
| Column | Type | Description |
|---|---|---|
id |
UUID (PK) |
Configuration ID |
source_account_id |
VARCHAR(128) |
Multi-app isolation |
provider |
VARCHAR(50) |
Provider name (duckdns, cloudflare, etc.) |
domain |
VARCHAR(255) |
Domain/hostname to update |
token_encrypted |
TEXT |
Encrypted API token/key |
check_interval_seconds |
INTEGER |
IP check interval |
last_known_ip |
VARCHAR(45) |
Last detected IP address |
last_update_at |
TIMESTAMPTZ |
Last successful update timestamp |
is_enabled |
BOOLEAN |
Whether this config is active |
metadata |
JSONB |
Provider-specific configuration |
created_at |
TIMESTAMPTZ |
Creation timestamp |
updated_at |
TIMESTAMPTZ |
Last update |
Tracks all DNS update attempts.
| Column | Type | Description |
|---|---|---|
id |
UUID (PK) |
Log entry ID |
source_account_id |
VARCHAR(128) |
Multi-app isolation |
config_id |
UUID (FK) |
References np_ddns_config
|
provider |
VARCHAR(50) |
Provider name |
domain |
VARCHAR(255) |
Domain updated |
old_ip |
VARCHAR(45) |
Previous IP address |
new_ip |
VARCHAR(45) |
New IP address |
status |
VARCHAR(20) |
success, failed, skipped
|
error_message |
TEXT |
Error details if failed |
response_time_ms |
INTEGER |
Provider response time |
created_at |
TIMESTAMPTZ |
Update attempt timestamp |
# Configure environment
export DDNS_PROVIDER=duckdns
export DDNS_DOMAIN=myhost.duckdns.org
export DDNS_TOKEN=your-duckdns-token
export DDNS_CHECK_INTERVAL=300
# Initialize and start
nself plugin run ddns init
nself plugin run ddns server# Configure environment
export DDNS_PROVIDER=cloudflare
export DDNS_DOMAIN=home.example.com
export DDNS_CLOUDFLARE_API_KEY=your-cloudflare-api-key
export DDNS_CLOUDFLARE_ZONE_ID=your-zone-id
export DDNS_CHECK_INTERVAL=600
# Initialize and start
nself plugin run ddns init
nself plugin run ddns server# Check current status
curl http://localhost:3217/api/ddns/status
# Force immediate update
curl -X POST http://localhost:3217/api/ddns/update
# View update history
curl http://localhost:3217/api/ddns/history?limit=10
# Get provider list
curl http://localhost:3217/api/ddns/providers# Check current status
nself plugin run ddns status
# Force update
nself plugin run ddns update
# View update history (last 20)
nself plugin run ddns history --limit 20
# Show statistics
nself plugin run ddns stats- IP Detection - Plugin periodically checks your external IP using public IP detection services
- Change Detection - Compares current IP with last known IP from database
- DNS Update - When IP changes, calls the provider's API to update DNS record
- Logging - Records all update attempts with status, timing, and error details
-
Scheduling - Runs check cycle every
DDNS_CHECK_INTERVALseconds
[Timer Tick] → [Detect External IP] → [Compare with Last Known IP]
↓
[IP Changed?]
↓
[Call Provider API] → [Update DNS Record]
↓
[Log Update Result] → [Store New IP]
- Create account at duckdns.org
- Create a subdomain (e.g.,
myhost.duckdns.org) - Copy your token from the DuckDNS dashboard
- Configure plugin:
DDNS_PROVIDER=duckdns DDNS_DOMAIN=myhost.duckdns.org DDNS_TOKEN=your-token-here
- Log in to Cloudflare dashboard
- Get your API key from profile settings
- Find your Zone ID for the domain
- Configure plugin:
DDNS_PROVIDER=cloudflare DDNS_DOMAIN=home.example.com DDNS_CLOUDFLARE_API_KEY=your-api-key DDNS_CLOUDFLARE_ZONE_ID=your-zone-id
- Create account at noip.com
- Create a hostname
- Generate an update token
- Configure plugin:
DDNS_PROVIDER=noip DDNS_DOMAIN=myhost.ddns.net DDNS_TOKEN=your-token
- Create account at dynu.com
- Create a DDNS hostname
- Get API credentials
- Configure plugin:
DDNS_PROVIDER=dynu DDNS_DOMAIN=myhost.dynu.net DDNS_TOKEN=your-token
"Provider not configured" -- Verify DDNS_PROVIDER is set to a supported provider (duckdns, cloudflare, noip, dynu).
"Token not found" -- Ensure the appropriate token environment variable is set. DuckDNS/No-IP/Dynu use DDNS_TOKEN, Cloudflare uses DDNS_CLOUDFLARE_API_KEY.
"Update failed" in logs -- Check the error_message in the update log table. Common issues: invalid token, domain not found, rate limiting, network errors.
IP not updating -- Verify DDNS_CHECK_INTERVAL is set (default 300 seconds). Check server logs for errors. Ensure your network allows outbound HTTPS to the provider API.
Updates too frequent -- Increase DDNS_CHECK_INTERVAL. Default is 300 seconds (5 minutes). Most providers recommend 5-10 minute intervals.
Cloudflare updates not working -- Verify both DDNS_CLOUDFLARE_API_KEY and DDNS_CLOUDFLARE_ZONE_ID are set correctly. The zone ID can be found in the Cloudflare dashboard for your domain.
Multiple domains -- Currently one configuration per account. For multiple domains, configure separate accounts or manually call the API with different domains using POST /api/ddns/update.
- API tokens are encrypted at rest in the database
- Use environment variables for secrets, never hardcode tokens
- Cloudflare API keys should have minimal permissions (Zone:DNS:Edit only)
- Monitor update logs for suspicious activity
- Consider using Cloudflare API tokens (more secure than global API keys)
- Minimal resource usage (IP checks are lightweight HTTP requests)
- Database writes only on IP changes or configuration updates
- Configurable check intervals to balance responsiveness vs. API quota usage
- Provider response times typically 100-500ms
Add to your .env.dev:
# Enable DDNS plugin
DDNS_PLUGIN_ENABLED=true
DDNS_PLUGIN_PORT=3217
# Configure provider
DDNS_PROVIDER=duckdns
DDNS_DOMAIN=myhost.duckdns.org
DDNS_TOKEN=your-token
DDNS_CHECK_INTERVAL=300# Check every minute (fast, for testing)
DDNS_CHECK_INTERVAL=60
# Check every 10 minutes (recommended for most use cases)
DDNS_CHECK_INTERVAL=600
# Check every hour (for stable IPs)
DDNS_CHECK_INTERVAL=3600While the plugin configuration supports one provider at a time, you can use the API to manually update multiple providers:
# Update DuckDNS
curl -X POST http://localhost:3217/api/ddns/update \
-H "Content-Type: application/json" \
-d '{"provider":"duckdns","domain":"myhost.duckdns.org"}'
# Update Cloudflare
curl -X POST http://localhost:3217/api/ddns/update \
-H "Content-Type: application/json" \
-d '{"provider":"cloudflare","domain":"home.example.com"}'- Commands
- File Processing Commands
- GitHub Commands
- ID.me Commands
- Jobs Commands
- Notifications Commands
- Realtime Commands
- Shopify Commands
- Stripe Commands
View All: Home (or see the full alphabetical list below — 129/129 synced with registry.json)
- Access-Controls
- Admin-Api
- AI-CLI
- AI-Studio
- Alerts
- Analytics
- API
- Audit
- Audit-Analytics
- Audit-Log
- Auth-Enterprise
- Backup
- BYOK
- CDC
- CDN
- CI
- Claw-CLI
- Cloudflare
- Compliance
- Content-Acquisition
- Content-Progress
- Content-Safety
- Costs
- CRDT
- Cron
- DDNS
- Devices
- DLQ
- Documents
- Dogfood
- Donorbox
- DR
- E2EE
- Encryption
- Entitlements
- Event-Bus
- Family-Ancestry
- Family-FamilySearch
- Family-GEDCOM
- Family-MyHeritage
- Family-WikiTree
- Feature-Flags
- Federation
- File-Processing
- Flags
- Forgejo
- Functions-V8
- Game-Metadata
- Gateway
- Gauth
- GDPR
- Geocoding
- GitHub
- GitHub-Runner
- HIPAA
- Home
- IDme
- Infra
- Invitations
- Job-Queue
- Jobs
- K8s
- Link-Preview
- Maintenance
- MDNS
- Media-Processing
- Meetings
- MLflow
- Model
- Monitor
- Monitoring
- Notifications
- Notify
- nSelf-Cloud
- nSelf-Eval-Gate
- nSelf-Geo
- nSelf-Image
- nSelf-PDF
- nSelf-Scan
- nSelf-Sync
- nSelf-Vault
- Object-Storage
- Observability
- Ollama
- Payments
- PayPal
- Pentest
- Pentest-Kit
- Plugin-ClawDE
- Plugin-Gauth
- Plugin-LLM-Gateway
- Plugin-PTY
- Plugin-Retrieval
- Podcast
- Post
- Push
- Queue
- Region
- Release
- Retro-Gaming
- Rom-Discovery
- Search
- Sentry-CLI
- Shared-Utils
- Shopify
- SIEM
- SMS
- Soak
- Sports
- Storage
- Storage-Transform
- Stripe
- Subtitle-Manager
- Tenant
- Tenant-Controller
- TMDB
- Tokens
- Torrent-Manager
- Transactional-Email
- VPN
- WAF
- Warehouse
- Watchdog
- Web3
- Webhooks
- Workflows
Related