An ultra-lightweight DNS server that runs anywhere - from Docker containers to Kubernetes pods to Linux services. Perfect for internal networks and ISVs distributing self-hosted applications, it provides custom domain resolution and service discovery without databases or external dependencies.
- Environment variable-based configuration (Support .env file)
- Support for A, CNAME, MX, and TXT records
- Docker service name resolution
- Optional TTL configuration (default: 60 seconds)
- Lightweight and fast
- Configurable port
Download the latest release from the releases page.
Release assets include scripts for installing/uninstalling NanoDNS as a system service:
# Make scripts executable
chmod +x install.sh uninstall.sh
# Install service
sudo ./install.sh
# View status and logs
systemctl status nanodns
journalctl -u nanodns -f
# Edit configuration
sudo nano /etc/nanodns/nanodns.env
# Uninstall service
sudo ./uninstall.sh
If you see the warning "Apple could not verify this app", run these commands:
# Remove quarantine attribute
xattr -d com.apple.quarantine nanodns-darwin-arm64
# Make executable
chmod +x nanodns-darwin-arm64
# Run the binary
./nanodns-darwin-arm64
Variable | Description | Default |
---|---|---|
DNS_PORT | UDP port for DNS server | 10053 |
DNS_RELAY_SERVERS | Comma-separated upstream DNS servers | 8.8.8.8:53,1.1.1.1:53 |
DNS_DEFAULT_TTL | Default TTL | 60 |
LOG_DIR | Log file directory path | /tmp/log/nanodns |
SERVICE_LOG | Service log filename | service.log |
ACTION_LOG | Action log filename | actions.log |
MAX_LOG_SIZE | Max log file size before rotation (in bytes) | 1048576 |
MAX_LOG_BACKUPS | Max log file backups before rotation | 5 |
Variable | Description |
---|---|
A_xxx | A Record Details |
CNAME_xxx | CNAME Record Details |
MX_xxx | MX Record Details |
TXT_xxx | TXT Record Details |
NanoDNS follows this resolution order:
- Check configured local records first
- If no local record found and relay is enabled, forward to upstream DNS servers
- Return first successful response from relay servers
All records use the |
character as a separator. The general format is:
RECORD_TYPE_NUMBER=domain|value[|ttl]
A_REC1=domain|ip|ttl
A_REC2=domain|service:servicename|ttl
Example:
A_REC1=app.example.com|10.10.0.1|300
A_REC2=api.example.com|service:webapp
CNAME_REC1=domain|target|ttl
Example:
CNAME_REC1=www.example.com|app.example.com|3600
MX_REC1=domain|priority|mailserver|ttl
Example:
MX_REC1=example.com|10|mail1.example.com|3600
MX_REC2=example.com|20|mail2.example.com
TXT_REC1=domain|"text value"|ttl
Example:
TXT_REC1=example.com|v=spf1 include:_spf.example.com ~all|3600
TXT_REC2=_dmarc.example.com|v=DMARC1; p=reject; rua=mailto:dmarc@example.com
# Basic Configuration
DNS_PORT=10053
DNS_RELAY_SERVERS=8.8.8.8:53,1.1.1.1:53
DNS_DEFAULT_TTL=60
# A Records
A_REC1=domain|ip-addr|[ttl]
# CNAME Records
# ...
# MX Records
# ...
# TXT Records
# ...
docker run -d \
--name nanodns \
-p 10053:10053/udp \
-e DNS_PORT=10053 \
-e DNS_RELAY_SERVERS=8.8.8.8:53,1.1.1.1:53 \
-e "A_REC1=app.example.com|10.10.0.1|300" \
-e "A_REC2=api.example.com|service:webapp" \
-e "TXT_REC1=example.com|v=spf1 include:_spf.example.com ~all" \
-v ${PWD}/.env:/app/.env \
ghcr.io/mguptahub/nanodns:latest
name: nanodns
services:
dns:
image: ghcr.io/mguptahub/nanodns:latest
environment:
# DNS Server Configuration
- DNS_PORT=10053 # Optional, defaults to 53
- DNS_RELAY_SERVERS=8.8.8.8:53,1.1.1.1:53 # Optional relay servers
# Local Records
- A_REC1=app.example.com|service:webapp
- A_REC2=api.example.com|10.10.0.5|300
- TXT_REC1=example.com|v=spf1 include:_spf.example.com ~all
ports:
- "${DNS_PORT:-10053}:${DNS_PORT:-10053}/udp"
volumes:
- ./.env:/app/.env
networks:
- app_network
networks:
app_network:
driver: bridge
For detailed instructions on deploying NanoDNS in Kubernetes, see our Kubernetes Deployment Guide.
Install using the script
curl -fsSL https://nanodns.mguptahub.com/install.sh | sh -s -- --install
Start using the script
# Check the values in /usr/local/share/nanodns.env before starting
nanodns start
Help Command
nanodns --help
Usage: nanodns [command | options]
commands:
start Run the binary as a daemon
stop Stop the running daemon service
status Show service status
logs Show service logs
logs -a Show action logs
options:
-v | --version Show the binary version
-h | --help Show the help information
# Test local records
dig @localhost -p 10053 app.example.com A
# Test relay resolution (for non-local domains)
dig @localhost -p 10053 google.com A
# Test other record types
dig @localhost -p 10053 www.example.com CNAME
dig @localhost -p 10053 example.com MX
dig @localhost -p 10053 example.com TXT
-
Port 53 already in use (common on macOS and Linux):
- Use a different port by setting
DNS_PORT=10053
or another available port - Update your client configurations to use the custom port
- Use a different port by setting
-
Permission denied when using port 53:
- Use a port number above 1024 to avoid requiring root privileges
- Set
DNS_PORT=10053
or another high-numbered port
-
DNS Relay Issues:
- Verify upstream DNS servers are accessible
- Check network connectivity to relay servers
- Ensure correct format in DNS_RELAY_SERVERS (comma-separated, with ports)
- Monitor logs for relay errors
Before opening a new issue:
- Check existing issues to avoid duplicates
- Use issue templates when available
- Include:
- NanoDNS version
- Operating system
- Clear steps to reproduce
- Expected vs actual behavior
- Error messages if any
- Star the repository to show support
- Watch for updates and new releases
- Join discussions in issues and PRs
- Share your use cases and feedback
We welcome contributions! Here's how to get started:
- Star β and watch π the repository
- Check open issues for tasks labeled
good first issue
orhelp wanted
- Read our Contributing Guide for:
- Development setup
- Code style guidelines
- PR process
- Release workflow
NanoDNS is open-source software licensed under AGPLv2. This means:
β You CAN:
- Use NanoDNS in your development environment
- Use NanoDNS as part of your infrastructure
- Package NanoDNS with your GPL-compatible software (with attribution)
- Modify and distribute NanoDNS (while keeping it open source)
β You CANNOT:
- Sell NanoDNS as a standalone product
- Include NanoDNS in proprietary software
- Remove or modify the license and copyright notices
π You MUST:
- Include the original license
- State significant changes made
- Include the complete corresponding source code
- Include attribution to this repository
This software uses NanoDNS (https://github.com/mguptahub/nanodns)
-
Simplicity:
- Clearer and more concise terms compared to v3
- Well-established legal precedents
-
Compatibility:
- Works well with other GPL v2 software
- Broader ecosystem compatibility
-
Core Protection:
- Ensures source code remains open
- Prevents commercial exploitation
- Requires attribution
While NanoDNS can be used within commercial products as a supporting utility:
- The complete source code must be available
- Proper attribution must be included
- Any modifications must be shared under AGPLv2
- It cannot be sold as a standalone product or service
Add this to your documentation:
This product uses NanoDNS (https://github.com/mguptahub/nanodns),
an open-source DNS server licensed under AGPL-2.0.
If you plan to use NanoDNS in your project, ensure your project's license is compatible with AGPLv2. When in doubt, open an issue for clarification.