If you self-host applications from your home lab, you know the frustration of cobbling together a domain name that feels both professional and reliable. The .self TLD—a new top-level domain designed specifically for personal infrastructure—offers a clean alternative. Unlike .local, which is limited to LAN multicast DNS, or traditional TLDs that require public registration and ICANN fees, .self is a non-public namespace built for your own servers, containers, and services. It eliminates the need for dynamic DNS workarounds or awkward port-forwarding hacks that break when your ISP changes your IP. By the end of this guide, you will know how to register a .self domain, configure it with Cloudflare for secure access, integrate it with Docker and reverse proxies, and automate DNS updates for dynamic IPs. Whether you are hosting a personal dashboard, a development API, or a private file sync service, this practical walkthrough will help you set up a domain that is truly yours—without the overhead of public registration or the limitations of local-only solutions.
What the .self TLD Actually Solves for Self-Hosters
Self-hosters have long grappled with a frustrating trade-off: either use a domain that works reliably only on the local network, or expose a publicly registered domain that requires constant DNS upkeep and leaks your personal infrastructure to the world. The .self TLD is designed specifically to eliminate this dilemma.
Common Workarounds and Their Limitations
| Approach | LAN Access | WAN Access | DNS Management | Privacy | Cost |
|---|---|---|---|---|---|
| .local (mDNS) | Yes, seamless via Bonjour/LLMNR | No, not routable on the internet | Zero configuration, but limited to local network | High (never exposed to internet) | Free |
| Standard TLD (.com, .net, etc.) | Requires split-brain DNS or hairpin NAT | Yes, after public registration and propagation | Full control, but slow propagation and requires public registrar | Low (public WHOIS, DNS records visible) | Annual registration fee, often $10-$15 |
| Dynamic DNS (e.g., .duckdns.org) | Yes, if configured on internal DNS | Yes, but subdomain is often unwieldy | Requires client to update IP; limited to provider’s TLD | Medium (subdomain is public, but no personal info) | Usually free or low cost |
| .self TLD | Yes, with proper DNS setup | Yes, if you configure your router and Cloudflare Tunnel | Full control, no propagation delays for internal use | High (not in public root, no WHOIS, no ICANN fees) | One-time or low fee (varies by registrar) |
As the table shows, .self combines the best of both worlds: it works on your local network without requiring split-brain DNS, and it can also be exposed to the internet via a tunnel or public IP, all while keeping your infrastructure hidden from public registries.
LAN vs. WAN Access Simplified
With .local, you are confined to your home network. With a standard TLD, you can access your services from anywhere, but you must manage DNS propagation and often deal with hairpin NAT issues. .self solves this by allowing you to set up internal DNS records (e.g., on your router or local Pi-hole) that resolve immediately, and external records (via Cloudflare) that point to your home lab’s public IP or tunnel. No more waiting for DNS changes to propagate; your internal users see the correct IP, and external users follow the public record.
Privacy by Design
Because the .self TLD is not part of the public DNS root, your domain does not appear in any global registry. There is no WHOIS database, no ICANN fee, and no obligation to publish your contact information. For a self-hoster running a personal blog, a development API, or a file sync service, this is a significant privacy benefit. You can hand out your .self domain to friends or clients without exposing your real name, address, or even the fact that you own the domain. Combined with Cloudflare’s proxy, your origin IP remains hidden, further hardening your setup.
In short, .self is purpose-built for the self-hosting community: it eliminates the awkwardness of .local, the cost and publicity of standard TLDs, and the complexity of dynamic DNS. It gives you a clean, professional namespace that works everywhere you need it.
How to Register a .self Domain: Step-by-Step
Registering a .self domain is a straightforward process, but it differs from buying a traditional public TLD like .com. Because .self is not part of the public DNS root, you won’t find it at standard registrars. Instead, you’ll need to locate a specialized registry or early-adopter program that supports the namespace.
Finding a Registrar
Start by searching for “.self TLD registrar” or “self TLD registry” in communities like the r/selfhosted subreddit, HomeLab forums, or self-hosting blogs. Many early-adopter programs are run by organizations that advocate for private, non-public TLDs. You can also check if the registry behind .self maintains a list of authorized resellers. If you’re part of a self-hosting group, ask for recommendations—word of mouth is often the fastest way to find reliable sources.
Registration Checklist
Once you’ve identified a registrar, follow this checklist:
-
Availability Check – Use the registrar’s search tool to see if your desired domain (e.g.,
myhomelab.self) is free. Because .self is new, many names are still available. - Account Creation – Create an account with the registrar. Some may require a minimal profile, while others ask for a description of your self-hosting setup to verify genuine use.
- Purchase & Payment – Complete the order. Typical costs range from $10 to $20 per year, though some early-adopter programs offer the first year at a discount or even free. Renewal terms are usually annual, but multi-year options may exist.
- WHOIS Privacy – Since .self is not in the public root, WHOIS may not be publicly exposed. Still, check if the registrar offers privacy protection—it’s often included automatically.
- Proof of Setup – Some registries require you to demonstrate that you have a self-hosting environment (e.g., a public IP, a DNS server, or a plan to use the domain). Be prepared to provide a brief explanation or a pointer to your infrastructure.
After Purchase
Once the domain is registered, you’ll typically receive access to manage its DNS zone or at least set custom nameservers. This is where you’ll point the domain to your home lab, Cloudflare, or a reverse proxy. Keep your registration details safe—you’ll need them to configure DNS and renew the domain annually.
By following these steps, you’ll have a clean, professional .self domain ready for the configuration guides in the next sections.
Configuring Your .self Domain with Cloudflare for Self-Hosting
Now that you have registered a .self domain, configuring it for use with Cloudflare is the logical next step. Cloudflare provides robust DNS management, DDoS protection, SSL/TLS termination, and a tunnel service that hides your home IP—perfect for self-hosters with dynamic addresses.
Step 1: Add Your .self Domain to Cloudflare
- Log into your Cloudflare account and click “Add a Site.”
- Enter your .self domain (e.g.,
myself.self). Cloudflare will show an error if it cannot verify the domain via the public DNS root—this is expected because .self is not a public TLD. Ignore the warning and click “Continue.” - On the next screen, Cloudflare will present nameserver values. Since .self domains are not in the public root, you cannot change delegation at the registry. Instead, you will configure Cloudflare as a primary DNS provider by manually creating the required NS records at your .self registrar.
- At your registrar, set the NS records for your domain to point to Cloudflare’s assigned nameservers (e.g.,
danny.ns.cloudflare.comandlucy.ns.cloudflare.com). After that, return to Cloudflare and click “Done, check nameservers.”
Step 2: Add DNS Records
Navigate to the DNS settings for your .self domain. Create A or AAAA records to point to your home lab’s public IP address. For example:
| Type | Name | Content | TTL |
|---|---|---|---|
| A | docker | 203.0.113.42 | Auto |
| A | @ | 203.0.113.42 | Auto |
If your public IP changes frequently, do not use static records. Instead, set up a Cloudflare Tunnel (step 3).
Step 3: Use Cloudflare Tunnel to Avoid Exposing Your IP
Cloudflare Tunnel creates an encrypted connection from your server to Cloudflare’s edge, so you never need to expose your home IP.
- Install
cloudflaredon your server (Raspberry Pi, VPS, or Docker host). On Docker, pull the official image:docker pull cloudflare/cloudflared. - Authenticate:
cloudflared tunnel loginand follow the browser link to authorize your Cloudflare account. - Create a tunnel:
cloudflared tunnel create home-lab. - Create a configuration file (
config.yml) that routes traffic for your .self domain:
tunnel: home-lab
credentials-file: /home/pi/.cloudflared/home-lab.json
ingsress:
- hostname: docker.myself.self
service: http://localhost:8080
- hostname: app.myself.self
service: http://localhost:3000
- service: http_status:404
- Start the tunnel:
cloudflared tunnel run home-lab. - In Cloudflare DNS, add a CNAME record pointing
docker.myself.selfto the tunnel UUID (e.g.,home-lab.cfargotunnel.com).
Step 4: Configure SSL/TLS
Cloudflare offers several SSL options. For self-hosted services, the recommended approach is:
- Set SSL/TLS encryption mode to Full (strict) in the Cloudflare dashboard.
- If you use Cloudflare Tunnel, no certificate is needed on your origin server because Cloudflare terminates TLS at the edge and forwards traffic over the encrypted tunnel.
- For non-tunnel setups, generate a Cloudflare Origin CA certificate: go to SSL/TLS > Origin Server > Create Certificate. Install this cert on your web server (e.g., Nginx) to encrypt traffic from Cloudflare to your home lab.
Step 5: Example: Pointing docker.self to a Self-Hosted Web App
Assume you are running a Docker container with an application on port 8080. You want it accessible at https://docker.myself.self.
- Start a container:
docker run -d --name myapp -p 8080:80 nginxdemos/hello. - Configure Cloudflare Tunnel (as in step 3) with hostname
docker.myself.selfand servicehttp://localhost:8080. - Add the CNAME record in Cloudflare DNS.
- Wait a few seconds for propagation, then visit
https://docker.myself.selfin your browser.
If you prefer not using a tunnel, simply point the A record to your home IP and set up port forwarding on your router (port 443 -> 8080). Cloudflare Tunnel is safer because it avoids opening firewall ports.
Firewall Rules (Optional)
In Cloudflare, you can restrict access to specific countries or IP ranges using Firewall Rules (Security > WAF). For example, block all traffic except from your home IP or allow only VPN ranges for sensitive services.
This configuration gives you professional-grade DNS, SSL, and traffic routing for your .self domain. Next, we will integrate .self with Docker and reverse proxies to simplify multi-service deployments.
Integrating .self with Docker and Reverse Proxies
Once your .self domain is registered and configured in Cloudflare, the next step is making it work with your Docker containers and a reverse proxy. This combination enables you to host multiple services under subdomains like dashboard.self, api.self, or git.self, all routed through a single server.
Setting Up a Docker Network for Multi-Service Hosting
To avoid port conflicts and simplify internal routing, create a dedicated Docker network that all your services share:
docker network create self-host-net
In your docker-compose.yml, attach each service to this network and assign static hostnames that match your .self subdomains:
version: '3'
services:
traefik:
image: traefik:v3.0
container_name: traefik
networks:
- self-host-net
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.cloudflare.acme.dnschallenge=true"
- "--certificatesresolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
- "--certificatesresolvers.cloudflare.acme.email=you@example.com"
environment:
- CF_API_EMAIL=you@example.com
- CF_DNS_API_TOKEN=your-cloudflare-api-token
whoami:
image: traefik/whoami
container_name: whoami
networks:
- self-host-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.self`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=cloudflare"
networks:
self-host-net:
external: true
Configuring the Reverse Proxy
The above Compose file uses Traefik with Docker provider and Cloudflare DNS challenge. When Traefik starts, it reads labels on containers. The whoami service is labeled with traefik.http.routers.whoami.rule=Host(whoami.self), which tells Traefik to route any incoming request for whoami.self to the whoami container. The SSL certificate is obtained automatically via the Cloudflare DNS challenge.
For Nginx Proxy Manager, create a proxy host pointing to the container's internal IP (static IP on self-host-net) and set the domain to whoami.self. Ensure SSL is configured with a Let's Encrypt certificate using DNS challenge.
Common Mistake: Forgetting DNS for Subdomains
A frequent pitfall is registering you.self in Cloudflare, but forgetting to add individual DNS records for each subdomain. Even though Traefik handles routing, Cloudflare still needs an A or CNAME record for whoami.self pointing to your server's IP or tunnel. Without it, requests will never reach your reverse proxy. Always create wildcard DNS records (*.self) pointing to your tunnel or public IP, or add a record per subdomain.
What You've Enabled
With this setup, you can add new services by adding a container with the correct Traefik labels and a matching DNS record. No port mapping is needed for individual services—just traefik exposes ports 80 and 443. This keeps your stack clean and scalable.
Automating DNS Updates for Dynamic IPs Using .self
Most residential internet connections use dynamic IP addresses that change periodically—sometimes daily, sometimes only when the modem reboots. If you're pointing .self subdomains directly at your home public IP via A records, a single IP change can break all your self-hosted services until you manually update your DNS. Automating DNS updates for your .self domain ensures your services remain reachable without constant manual fixes.
Simple Bash Script for Dynamic DNS
Here is a lightweight bash script that checks your current public IP every few minutes and updates a Cloudflare DNS A record if the IP has changed. You'll need your Cloudflare API token, zone ID, and the DNS record ID for your .self domain.
#!/bin/bash
# cloudflare-ddns.sh – Update .self domain A record on IP change
CF_API_TOKEN="your_cloudflare_token"
ZONE_ID="your_zone_id"
RECORD_NAME="myservice.yourname.self"
RECORD_ID="your_record_id"
CURRENT_IP=$(curl -s https://api.ipify.org)
CF_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" | jq -r '.result.content')
if [ "$CURRENT_IP" != "$CF_IP" ]; then
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"content\":\"$CURRENT_IP\"}"
echo "Updated $RECORD_NAME to $CURRENT_IP"
fi
Make the script executable and test it manually before scheduling.
Automating with Cron
To run the script every five minutes, add this line to your crontab (crontab -e):
*/5 * * * * /home/you/bin/cloudflare-ddns.sh >> /var/log/ddns.log 2>&1
Check the log periodically to confirm updates are happening. If your IP changes overnight, cron catches it within minutes.
Using cloudflare-ddns Docker Image
If you prefer a containerized solution, the favonia/cloudflare-ddns Docker image handles everything with minimal setup. Mount a config file containing your Cloudflare API token and .self domain records:
version: '3'
services:
ddns:
image: favonia/cloudflare-ddns
restart: always
environment:
- CF_API_TOKEN=your_token
- DOMAINS=myservice.yourname.self,another.yourname.self
- PROXIED=true
- TTL=120
Run docker-compose up -d and it polls for IP changes every five minutes by default. This approach works well alongside your other self-hosted containers and requires no host-level cron setup.
Tunnel vs Dynamic DNS: Tradeoffs
Cloudflare Tunnel (discussed in Section 4) eliminates the need for dynamic DNS entirely by creating an outbound tunnel that bypasses your public IP. The table below compares both approaches:
| Approach | Pros | Cons |
|---|---|---|
| Dynamic DNS + A record | Full control; works with any service; no Cloudflare Tunnel dependency | Vulnerable to IP changes; script/container must run continuously; latency through direct connection |
| Cloudflare Tunnel | No public IP required; zero attack surface; automatic failover; no DNS updates needed | Requires tunnel daemon (cloudflared); proxied traffic adds slight overhead; all traffic passes through Cloudflare |
For most self-hosters using .self domains, Cloudflare Tunnel is simpler and more reliable—especially if you're already proxying through Cloudflare. However, if you have strict latency requirements or prefer direct client–server connections, dynamic DNS with automation is a proven fallback. Either way, your .self domain remains stable and accessible.
Next step: Decide whether tunnel or dynamic DNS fits your infrastructure. If you choose dynamic DNS, implement the script or Docker container above and schedule it to run every few minutes. Your .self domain will stay up even when your ISP rotates your IP at 3 AM.
Common Pitfalls When Self-Hosting with .self (and How to Avoid Them)
Even with a perfectly registered and configured .self domain, a few common mistakes can break your setup. Here are the pitfalls to watch for and how to fix them.
DNS propagation issues specific to .self — Because .self is not in the public DNS root, standard propagation checks (like whatismydns.net) won’t work. Your ISP’s resolver won’t know about your domain unless you explicitly tell it where to look. Fix: If you use Cloudflare, set your .self domain’s NS records to Cloudflare’s nameservers and ensure your home router points to a DNS resolver that respects those records (e.g., Cloudflare’s 1.1.1.1). Alternatively, use a local DNS server like Pi‑hole or Unbound to forward .self queries to Cloudflare.
Forgetting to update your router’s DNS resolver — After registering your .self domain, your router still defaults to your ISP’s DNS (which has no entry for .self). This means devices on your LAN can’t resolve docker.self or any other subdomain. Fix: In your router’s DHCP settings, set the primary DNS to Cloudflare (1.1.1.1) or a local DNS server you control. Also, configure your router to forward .self queries to your internal DNS or use conditional forwarding.
Misconfiguring your reverse proxy to bind to all interfaces — When you attach a reverse proxy (Traefik, Nginx) to your .self domain, it’s tempting to set
bind 0.0.0.0:80for simplicity. This exposes your proxy to every interface, including the WAN, which can create security risks and port conflicts. Fix: Bind your reverse proxy only to the Docker bridge network or to the specific IP your tunnel uses. For Cloudflare Tunnel, bind only to thecloudflaredsidecar container’s network.Expecting .self to resolve on mobile networks without a VPN — Mobile carriers and public Wi‑Fi use their own DNS, which has no record of your .self domain. Even if you’ve configured everything perfectly at home, your phone won’t resolve
dashboard.selfwhen you’re out. Fix: Use a VPN like Tailscale or WireGuard. Configure your VPN’s DNS settings to route .self queries to a resolver that knows about your domain (e.g., Pi‑hole on your home network). Tailscale’s MagicDNS can be configured to handle custom TLDs if you run a local DNS server.Not configuring conditional forwarding for .self in complex networks — If you run multiple VLANs or subnets (e.g., separate IoT and server networks), devices on one VLAN may not be able to reach your .self domain because they don’t share the same DNS resolver. Fix: Set up your DNS server to conditionally forward .self queries to the authoritative nameserver (Cloudflare) or to an internal resolver that holds the records. For home labs with Unbound, add a
forward-zonefor.self.
Quick Checklist of 5 Mistakes and Fixes
- [ ] Mistake: .self not resolving anywhere → Fix: Set router DNS to Cloudflare or use a local DNS with conditional forwarding.
- [ ] Mistake: .self resolves on LAN but not over VPN → Fix: Add a DNS search domain or split‑tunnel rule in your VPN config.
- [ ] Mistake: Reverse proxy binds to WAN interface → Fix: Bind to
127.0.0.1or the Docker bridge IP instead of0.0.0.0. - [ ] Mistake: Cloudflare tunnel is running but no SSL cert → Fix: Enable Full (strict) in Cloudflare SSL/TLS and use a proper origin certificate.
- [ ] Mistake: Dynamic IP updates don’t work → Fix: Use Cloudflare Tunnel instead of dyndns, or automate with
cloudflare-ddnsas shown in Section 6.
Avoiding these pitfalls will keep your .self domain reliable and secure. Next, we’ll put everything into practice with a real project.
Your Next Self-Hosted Project: Applying What You've Learned
With your .self domain configured on Cloudflare, integrated with a reverse proxy, and automated for dynamic IPs, you have a robust foundation for any self-hosted service. Now, put it to work. Choose a real project that excites you—maybe a personal dashboard, a development test API, or a private file sync service. For example, imagine building a lightweight web app to track your home lab metrics and hosting it at metrics.yourdomain.self. Start by defining the core functionality you need, then deploy it using Docker with Traefik labels so it automatically picks up your existing SSL and routing. The skills you've learned—DNS management, reverse proxy configuration, and automation—are exactly what you'll use day after day. If you want to take it further by building a polished frontend or a robust backend, you can explore how https://paradane.com helps developers design and deploy custom web applications quickly. The important thing is to start: pick a project, set a weekend to work on it, and enjoy the satisfaction of accessing your own service via your very own .self domain. This hands-on practice will cement everything you've learned and open the door to many more self-hosted projects.
Top comments (0)