Sign inSign up

marcuoli/codexdns

By marcuoli

•Updated 16 days ago

DNS server with web management UI, DHCP integration, filtering, and NTP support

Image
0

1.6K

marcuoli/codexdns repository overview

⁠CodexDNS — DNS Server with Web Management

A comprehensive DNS server solution with an intuitive web interface, designed for network administrators and self-hosters.

šŸ“š Full documentation: https://docs.codexs.com.br/codexdns/⁠


⁠Quick Start

⁠Basic Setup (HTTP only)
docker run -d \
  --name codexdns \
  --restart unless-stopped \
  -p 8080:8080 \
  -p 53:53/udp \
  -p 53:53/tcp \
  -v codexdns-data:/app/data \
  -v codexdns-config:/app/config \
  -v codexdns-logs:/app/logs \
  -v codexdns-certs:/app/certs \
  marcuoli/codexdns:latest

Access the web UI at: http://localhost:8080⁠

⁠Production Setup (HTTPS + DNS/DHCP/NTP)
docker run -d \
  --name codexdns \
  --restart unless-stopped \
  -p 8080:8080 \
  -p 8443:8443 \
  -p 53:53/udp \
  -p 53:53/tcp \
  -p 853:853/tcp \
  -p 123:123/udp \
  -v codexdns-data:/app/data \
  -v codexdns-config:/app/config \
  -v codexdns-logs:/app/logs \
  -v codexdns-certs:/app/certs \
  -e TZ=America/New_York \
  -e CODEXDNS_ADMIN_PASSWORD=your-strong-admin-password \
  -e CODEXDNS_SESSION_SECRET=$(openssl rand -hex 32) \
  marcuoli/codexdns:latest
⁠Docker Compose
services:
  codexdns:
    image: marcuoli/codexdns:latest
    container_name: codexdns
    restart: unless-stopped
    ports:
      - "8080:8080"    # HTTP Web UI
      - "8443:8443"    # HTTPS Web UI
      - "53:53/udp"    # DNS
      - "53:53/tcp"    # DNS
      - "853:853/tcp"  # DNS-over-TLS
      - "123:123/udp"  # NTP
    volumes:
      - codexdns-data:/app/data
      - codexdns-config:/app/config
      - codexdns-logs:/app/logs
      - codexdns-certs:/app/certs
    environment:
      - TZ=America/New_York
      - CODEXDNS_ADMIN_PASSWORD=your-strong-admin-password
      - CODEXDNS_SESSION_SECRET=replace-with-output-of-openssl-rand-hex-32

volumes:
  codexdns-data:
  codexdns-config:
  codexdns-logs:
  codexdns-certs:

⁠First Login

  • Username: admin
  • Password: Set via the CODEXDNS_ADMIN_PASSWORD environment variable
⁠Setting the admin password

Option A — provide a password at startup (recommended):

docker run -d \
  --name codexdns \
  -e CODEXDNS_ADMIN_PASSWORD=your-strong-password \
  ...

The password must be at least 12 characters. The admin account is created with this password on first boot; if the account already exists the seed step is skipped.

Option B — auto-generated password (if CODEXDNS_ADMIN_PASSWORD is not set):

CodexDNS generates a strong random 24-character password and prints it once to the startup logs. Retrieve it before the first login:

docker logs codexdns | grep -A1 'CODEXDNS ADMIN PASSWORD'

You will also be prompted to change this password on your first login.


⁠Port Mapping

PortProtocolServiceRequired
8080TCPHTTP Web UIāœ… Yes
8443TCPHTTPS Web UIOptional
53UDP/TCPDNS Serverāœ… Yes (if using DNS)
853TCPDNS-over-TLSOptional
443TCPDNS-over-HTTPSOptional
123UDPNTP ServerOptional

⁠Volume Mapping

Container PathPurposeRequired
/app/dataSQLite database, blocklistsāœ… Required
/app/configConfiguration filesāœ… Required
/app/logsApplication logsRecommended
/app/certsTLS/SSL certificatesRequired for HTTPS/DoT

⁠Environment Variables

All CODEXDNS_* variables map directly to config file fields via the CODEXDNS_ prefix (e.g. CODEXDNS_HTTP_PORT overrides http_port). Environment variables always take precedence over values in config.json.

VariableDefaultDescription
TZUTCTimezone (e.g., America/New_York)
CODEXDNS_CONFIG_FILE/app/config/config.jsonCustom config file path
Web UI
CODEXDNS_HTTP_PORT8080HTTP web UI port
CODEXDNS_HTTPS_ENABLEDfalseEnable HTTPS web UI
CODEXDNS_HTTPS_PORT8443HTTPS web UI port
CODEXDNS_GIN_MODEreleaseGin framework mode (debug/release)
DNS Server
CODEXDNS_DNS_HOST0.0.0.0DNS bind address
CODEXDNS_DNS_PORT53DNS port (UDP + TCP)
CODEXDNS_UPSTREAM_SERVERS8.8.8.8:53;1.1.1.1:53Semicolon-separated upstream DNS forwarders
CODEXDNS_UPSTREAM_STRATEGYorderedUpstream selection (ordered/round-robin/fastest-response/lowest-latency)
Services
CODEXDNS_NTP_ENABLEDfalseEnable built-in NTP server
CODEXDNS_DHCP_ENABLEDfalseEnable built-in DHCP server
Database
CODEXDNS_DB_DRIVERsqliteDatabase driver (sqlite/postgres/mysql)
CODEXDNS_DB_DSN/app/data/codexdns.dbDatabase path or DSN
Cache
CODEXDNS_CACHE_BACKENDredisCache backend (redis/memory/none)
CODEXDNS_CACHE_ENABLEDtrueEnable DNS query caching
CODEXDNS_REDIS_ADDRlocalhost:6379Redis server address (when cache_backend=redis)
Logging
CODEXDNS_LOG_LEVELinfoLog level (debug/info/warn/error)
Security
CODEXDNS_ADMIN_PASSWORD(auto-generated)Password for the built-in admin account. Printed once to the startup log if not set.
CODEXDNS_SESSION_SECRET(required in production)Secret used to sign session cookies. Must be at least 32 characters. Generate with openssl rand -hex 32. Startup aborts in release mode if missing or too short.

⁠Features

⁠✨ DNS Server
  • Authoritative zones (forward & reverse)
  • DNS forwarding with per-domain rules
  • DNS-over-HTTPS (DoH), DNS-over-TLS (DoT), DNS-over-QUIC (DoQ)
  • EDNS0 support
  • Per-upstream concurrency caps and circuit breakers
ā šŸ›”ļø Security & Filtering
  • Ad blocking and malware protection
  • Custom blocklists/whitelists
  • Per-client DNS policies
  • Safe search enforcement (Google, YouTube, Bing, DuckDuckGo, and more)
  • TLS certificate management
ā šŸ–„ļø Web Management
  • Modern responsive UI (mobile-friendly)
  • Real-time DNS query monitoring
  • Statistics and analytics dashboards
  • Zone and record management (A, AAAA, CNAME, MX, TXT, PTR, NS, SRV)
  • Role-based access control
ā šŸ”§ Advanced Features
  • DHCP integration with dynamic DNS (RFC 2136)
  • NTP server with time synchronization
  • Client discovery (reverse DNS, NetBIOS, mDNS, LLMNR)
  • MAC vendor lookup (OUI database)
  • Redis caching support
  • Multi-database support (SQLite, PostgreSQL, MySQL)
  • Prometheus metrics endpoint
  • Structured, per-subsystem log files (HTTP, DNS, DHCP, NTP)
  • Goroutine-per-query DNS handling with configurable concurrency caps and singleflight deduplication

⁠⚔ Performance & Concurrency

CodexDNS is built on Go's native concurrency model — lightweight goroutines scheduled by the Go runtime across all available CPU cores. There is no thread pool to size; the runtime automatically parallelises work across every core the container is given.

⁠Independent service goroutines

Each protocol server and background service runs in its own independent goroutine, so a restart of the DNS server (via the web UI or API) never pauses the HTTP/HTTPS interface, and vice versa.

Goroutine / WorkerRole
HTTP serverWeb UI and REST API
HTTPS serverTLS-terminated Web UI and REST API
DNS UDP + TCPStandard DNS on port 53
DNS-over-TLS (DoT)Encrypted DNS on port 853
DNS-over-HTTPS (DoH)DNS via HTTPS on port 443
DNS-over-QUIC (DoQ)DNS over HTTP/3
NTP serverTime synchronisation on port 123
Stats servicePeriodic query-rate aggregation
Async log writerBuffered write queue (up to 10,000 in-flight entries)
DNS query DB loggerAsync persistence queue (up to 20,000 in-flight entries)
Client tracking workersConfigurable pool — reverse DNS / mDNS / NetBIOS discovery
Filter list updaterBackground blocklist refresh
TLS cert renewal monitorAutomatic certificate re-issue
Prometheus exporterMetrics collection and exposure
Signal handlerClean shutdown on SIGINT / SIGTERM
⁠Per-query concurrency

Each incoming DNS query is dispatched to its own goroutine. Two mechanisms prevent overload:

  • dns_max_concurrent_queries — configurable hard cap; queries that exceed the limit are dropped gracefully with a counter exposed in the dashboard and Prometheus metrics.
  • singleflight deduplication — identical upstream forwarding requests that arrive simultaneously are collapsed into a single round-trip, reducing upstream load and latency spikes under burst traffic.
⁠CPU resource limits and GOMAXPROCS

Go 1.25 is fully cgroup-aware: when you set --cpus (or a cgroup CPU quota) on a container, the runtime reads the quota and automatically caps GOMAXPROCS to match — no extra configuration needed.

# Give CodexDNS 2 vCPUs; GOMAXPROCS will be set to 2 automatically
docker run -d --cpus="2" --name codexdns ...

For single-core environments (e.g. a small home Raspberry Pi) CodexDNS works fine — goroutines that are waiting on I/O (network, disk) yield the CPU automatically, so even one vCPU handles typical home DNS load with headroom to spare.

⁠Sizing recommendations
Deployment scenarioRecommended vCPUsNotes
Home / lab (< 50 clients)1Default settings work fine
Small office (50–200 clients)2Consider increasing dns_client_tracking_workers
Medium network (200–1 000 clients)2–4Enable Redis caching; tune dns_max_concurrent_queries
Large network (1 000+ clients)4+Use PostgreSQL or MySQL; Redis strongly recommended

⁠Configuration

On first start, CodexDNS copies its built-in default configuration to /app/config/config.json if no config file exists. You can then edit it via the web UI or by mounting your own file. For a full list of configuration parameters see the Configuration Reference⁠.

⁠Mount a custom config
docker run -d \
  --name codexdns \
  -v /path/to/config.json:/app/config/config.json \
  -v codexdns-data:/app/data \
  -v codexdns-logs:/app/logs \
  -v codexdns-certs:/app/certs \
  -p 8080:8080 -p 53:53/udp -p 53:53/tcp \
  marcuoli/codexdns:latest

A minimal config.json to get started:

{
  "http_port": "8080",
  "dns_host": "0.0.0.0",
  "dns_port": "53",
  "db_driver": "sqlite",
  "db_dsn": "/app/data/codexdns.db",
  "cache_backend": "memory",
  "log_level": "info",
  "upstream_servers": ["8.8.8.8:53", "1.1.1.1:53"],
  "upstream_strategy": "round-robin"
}

⁠Logs & Troubleshooting

# View logs
docker logs codexdns

# Follow logs in real-time
docker logs -f codexdns

# View container status
docker ps -a | grep codexdns

# Check health endpoint
docker exec codexdns wget -qO- http://localhost:8080/health

# Access logs directory (if mounted)
docker exec codexdns ls -la /app/logs

⁠Documentation

Full documentation is available at https://docs.codexs.com.br/codexdns/⁠


⁠Security Notes

  • Set CODEXDNS_ADMIN_PASSWORD to a strong password before first boot; if omitted, a random 24-character password is auto-generated and printed once to the startup log
  • Set CODEXDNS_SESSION_SECRET to a unique random string of at least 32 characters; startup will abort in release (production) mode if this is missing, too short, or left as a placeholder — generate one with openssl rand -hex 32
  • Use HTTPS in production (mount TLS certificates to /app/certs)
  • Restrict network access using firewall rules or Docker networks
  • Keep the image updated for security patches

⁠License

MIT License — see https://github.com/marcuoli/codexdns/blob/main/LICENSE⁠

Built with: Go, Gin, GORM, Templ, TailwindCSS, Alpine.js, HTMX
Base image: Alpine Linux 3.19
Architecture: Multi-stage optimized build (~50 MB)

Tag summary

Content type

Image

Digest

sha256:a2313d5d1…

Size

50.7 MB

Last updated

16 days ago

docker pull marcuoli/codexdns