Dynamic DNS management from your terminal. Manage domains, tokens, API keys, and DNS updates with style.
ApertoDNS is a free Dynamic DNS service that lets you point a subdomain to your dynamic IP address. Perfect for home servers, IoT devices, game servers, NAS systems, and remote access.
| Feature | ApertoDNS | Dyn (Oracle) | No-IP | DuckDNS |
|---|---|---|---|---|
| Free plan | Yes | No ($55/yr) | Yes | Yes |
| Free subdomains | Unlimited | 0 | 1 | 5 |
| API Keys with scopes | Yes | No | No | No |
| CLI tool | Yes | No | No | No |
| Docker images | Yes | No | No | No |
| IPv6 support | Yes | Paid | Paid | Yes |
| No forced renewal | Yes | N/A | 30 days | Yes |
| DynDNS2 compatible | Yes | Yes | Yes | No |
| Webhooks | Yes | No | No | No |
| Team sharing | Yes | No | No | No |
| Open Source | Yes | No | No | No |
- Easy Setup - Login or register directly from CLI
- Multiple Domains - Manage unlimited subdomains
- API Keys - Create and manage API keys with granular scopes
- Auto Updates - Set up cron or daemon mode for automatic IP updates
- Interactive Mode - Beautiful terminal UI with menus
- JSON Output - Machine-readable output for scripting
- IPv4 & IPv6 - Full dual-stack support
- Real-time Stats - View usage statistics and logs
- Router/NAS Compatible - Works with Synology, QNAP, and DynDNS2-compatible routers
- Docker Images - Official apertodns/cli and apertodns/updater images
- Node.js 18.0.0 or higher
- An ApertoDNS account (register free)
# npm
npm install -g apertodns
# yarn
yarn global add apertodns
# pnpm
pnpm add -g apertodnsOr use without installing:
npx apertodns --help# 1. Setup (login or register)
apertodns --setup
# 2. View your dashboard
apertodns --dashboard
# 3. List your domains
apertodns --domains
# 4. Force DNS update
apertodns --force| Command | Description |
|---|---|
--dashboard |
Complete dashboard with all info |
--domains |
List all your domains |
--tokens |
List all your tokens |
--stats |
Statistics and metrics |
--logs |
Recent activity logs |
--my-ip |
Show your current public IP |
| Command | Description |
|---|---|
--add-domain <name> |
Create a new subdomain |
--delete-domain |
Delete a domain (interactive) |
--test <domain> |
Test DNS resolution |
update <domain> |
Update a specific domain's IP (use with --api-key) |
| Command | Description |
|---|---|
--txt-set <host> <name> <value> |
Set a TXT record |
--txt-delete <host> <name> |
Delete a TXT record |
Perfect for Let's Encrypt DNS-01 challenges:
# Set TXT record for certificate validation
apertodns --txt-set example.apertodns.com _acme-challenge "validation-token"
# Delete TXT record after certificate issuance
apertodns --txt-delete example.apertodns.com _acme-challenge
# Use with API key for automation
apertodns --api-key apertodns_live_xxx... --txt-set example.apertodns.com _acme-challenge "token" --json| Command | Description |
|---|---|
--enable <id> |
Enable a token |
--disable <id> |
Disable a token |
--toggle <id> |
Toggle token state |
--verify |
Verify token validity |
| Command | Description |
|---|---|
--api-keys |
List all API keys |
--create-api-key <name> |
Create new API key |
--delete-api-key <id> |
Delete an API key |
--scopes |
Show available scopes |
--api-key <key> |
Use API key for authentication |
| Command | Description |
|---|---|
--setup |
Guided setup (login/register) |
--status |
Show current status and IP |
--config |
Edit configuration |
--logout |
Remove local configuration |
--force |
Force DNS update now |
| Command | Description |
|---|---|
--update |
Standalone DynDNS2 update (no config required) |
--domain <fqdn> |
Domain to update (with --update) |
--token <token> |
Token for authentication (with --update) |
--ip <address> |
Custom IP address (optional, auto-detected if omitted) |
| Command | Description |
|---|---|
--daemon |
Start daemon mode (continuous updates) |
--interval <sec> |
Update interval (default: 300s) |
| Option | Description |
|---|---|
--cron |
Silent mode for cron jobs |
--quiet |
Hide banner |
--json |
JSON output (machine-readable) |
-v, --version |
Show version |
-h, --help |
Show help |
Run apertodns without arguments for an interactive menu with all options.
apertodnsYou can authenticate in 3 ways:
- Interactive Login - Run
apertodns --setup(saves JWT to ~/.config/apertodns/) - API Key - Use
--api-key <key>for single operations - Environment Variable - Set
APERTODNS_API_KEY
All commands support --json flag for machine-readable output:
# Get domains as JSON
apertodns --domains --json
# Get your IP as JSON
apertodns --my-ip --json
# Combine with API key for scripting
apertodns --api-key apertodns_live_xxx... --domains --jsonRun continuously to keep your DNS updated:
# Default interval (5 minutes)
apertodns --daemon
# Custom interval (60 seconds)
apertodns --daemon --interval 60Update DNS without any saved configuration - perfect for scripts and one-off updates:
# Auto-detect IP and update
apertodns --update --domain myserver.apertodns.com --token YOUR_TOKEN
# Specify custom IP
apertodns --update --domain myserver.apertodns.com --token YOUR_TOKEN --ip 203.0.113.42Run without installing Node.js:
# Run CLI via Docker
docker run --rm apertodns/cli --help
# Interactive setup (persisted config)
docker run -it -v apertodns_config:/root/.config/apertodns apertodns/cli --setup
# List domains
docker run -v apertodns_config:/root/.config/apertodns apertodns/cli --domains
# Standalone update (no config needed)
docker run --rm apertodns/cli --update --domain myhost.apertodns.com --token YOUR_TOKENFor continuous updates, use the dedicated updater image:
docker run -d \
--name apertodns-updater \
--restart unless-stopped \
-e TOKEN=your_token \
-e DOMAINS=myhost.apertodns.com \
apertodns/updaterSee Docker Hub for more options.
Set up automatic IP updates with cron:
# Update every 5 minutes
*/5 * * * * /usr/local/bin/apertodns --cron >> /var/log/apertodns.log 2>&1
# Or every minute for faster updates
* * * * * /usr/local/bin/apertodns --cronFind your apertodns path with: which apertodns
ApertoDNS is compatible with routers that support DynDNS2 protocol:
Server: api.apertodns.com
Protocol: DynDNS2
Path: /nic/update
Username: your-token
Password: your-token
Hostname: yourdomain.apertodns.com
- Routers: ASUS, TP-Link, Netgear, Ubiquiti, pfSense, OPNsense, DD-WRT, OpenWRT
- NAS: Synology DSM, QNAP QTS, TrueNAS
- Other: Any device supporting DynDNS2/DynDNS protocol
Configuration is stored in platform-specific locations:
- Linux:
~/.config/apertodns/or~/.apertodns/ - macOS:
~/.config/apertodns/ - Windows:
%APPDATA%\apertodns\
"Unable to detect IP address"
- Check your internet connection
- Try a different IP detection service: the CLI automatically tries multiple fallbacks
- If behind a corporate proxy, the detected IP may be the proxy's IP
"Authentication failed"
- Run
apertodns --logoutthenapertodns --setupto re-authenticate - If using API key, verify it has the required scopes
- Check if the token/API key is still active in your dashboard
"DNS not updating"
- Use
apertodns --forceto force an immediate update - Check
apertodns --statusto see current IP vs DNS IP - DNS propagation can take up to 5 minutes
IPv6 not working
- IPv6 requires your ISP and network to support it
- Use
apertodns --my-ip --jsonto check if IPv6 is detected - Some networks only provide IPv4
Permission denied on Linux
- If installed globally, you may need sudo:
sudo npm install -g apertodns - Or use a Node version manager (nvm) to avoid permission issues
Daemon mode exits unexpectedly
- Check logs in
/var/log/apertodns.logif using cron - Ensure stable internet connection
- Consider using a process manager like PM2 or systemd
# Show all commands
apertodns --help
# Check current status
apertodns --status
# Verify authentication
apertodns --verify- Credentials are stored locally, never transmitted except to ApertoDNS servers
- API keys support granular scopes for least-privilege access
- All API communication uses HTTPS
- No cross-account data access - strict user isolation
# Quick status check
apertodns --status
# Test DNS propagation
apertodns --test myserver.apertodns.com
# Create domain and get token
apertodns --add-domain newserver.apertodns.com
# List domains as JSON
apertodns --domains --json
# Use API key for automation
APERTODNS_API_KEY=apertodns_live_xxx... apertodns --domains --json- Website: apertodns.com
- Dashboard: apertodns.com/dashboard
- Documentation: apertodns.com/docs
- Issues: GitHub Issues
Need help?
- Open an issue on GitHub
- Email: support@apertodns.com
MIT - Aperto Network