Subdomain per User with Wildcard DNS: Setup Guide
This guide shows you how to create a unique subdomain for each new user automatically, using wildcard DNS and a bit of server configuration. You’ll set up a wildcard DNS record so that anything.yourdomain.com points to your server, then configure your web server or application to handle each subdomain dynamically. This is ideal for SaaS platforms, multi-tenant apps, or any service where each user gets their own space like john.yourdomain.com.
What You’ll Need
- A domain name (e.g.,
yourdomain.com) with DNS management access. - A server (VPS, dedicated, or cloud instance) with a public IP address.
- Web server software installed (Apache, Nginx, or Caddy) or an application framework that supports dynamic subdomains (e.g., Rails, Django, Node.js).
- SSL certificate capability (Let’s Encrypt or a wildcard certificate) for HTTPS.
- Basic command-line and server administration knowledge.
Step-by-Step
- Create a wildcard DNS record. Log into your DNS provider (e.g., Cloudflare, Namecheap, Route 53). Add an
Arecord with host*pointing to your server’s public IP address. For IPv6, add anAAAArecord with host*as well. This makesanything.yourdomain.comresolve to your server. - Verify the wildcard DNS. Use a tool like
digor an online DNS checker to confirm that a random subdomain (e.g.,test123.yourdomain.com) resolves to your server IP. Note that DNS propagation can take up to 48 hours, but often it’s much faster. - Configure your web server to accept all subdomains. For Apache, create a virtual host with
ServerAlias *.yourdomain.com. For Nginx, use aserver_namedirective with*.yourdomain.com. For Caddy, simply use*.yourdomain.comin the site address. This tells the server to respond to any subdomain. - Set up a default virtual host or server block. Create a configuration that catches all subdomains and routes them to your application. In Apache, this is the virtual host with the wildcard alias. In Nginx, it’s a server block with the wildcard server_name. Make this the default for port 80 (and 443 if using HTTPS).
- Extract the subdomain in your application. In your backend code, read the
Hostheader from the incoming request. Parse out the subdomain part (the part before your main domain). For example, if the host isjohn.yourdomain.com, extractjohn. Most frameworks have utilities for this (e.g.,request.subdomainin Express,request.hostin Django). - Use the subdomain to identify the user. When a request comes in, look up the user or tenant based on the subdomain. For instance, query your database for a user with username
johnor a tenant with slugjohn. If not found, return a 404 or a custom error page. - Create subdomains dynamically on user signup. When a new user registers, you don’t need to create a DNS record—the wildcard already covers it. Instead, just store the subdomain (e.g., username) in your database and associate it with the user. The next time they visit
theirname.yourdomain.com, your app will recognize them. - Set up SSL certificates. For HTTPS, you have two options: use a wildcard certificate for
*.yourdomain.com(covers all subdomains) or use Let’s Encrypt with DNS-01 challenge to automatically issue certificates for each subdomain on the fly. The latter is more flexible but requires automation (e.g., certbot with a DNS plugin). - Test with a real user. Create a test account, then visit
testuser.yourdomain.comin a browser. Ensure the site loads and shows the correct user-specific content. Also test a non-existent subdomain to see if it returns a proper error. - Monitor and maintain. Keep an eye on server logs for any unusual subdomain requests. Periodically review your DNS settings to ensure the wildcard record is still in place. If you use on-the-fly SSL, ensure your renewal automation is working.
Common Mistakes
- Forgetting the dot in the DNS record. Some DNS providers require a trailing dot (e.g.,
*.yourdomain.com.) to indicate absolute domain. Check your provider’s documentation. - Wildcard only covers one level.
*.yourdomain.commatchesjohn.yourdomain.combut notjohn.doe.yourdomain.com. If you need multiple levels, you’ll need a separate wildcard for each level or use a different approach. - Not configuring the default server. If you don’t set a default virtual host, requests to unknown subdomains might hit the wrong site or show an error. Always have a catch-all.
- Using the subdomain for security decisions without validation. Always validate the subdomain against your database; never trust it blindly. An attacker could spoof the Host header.
- Ignoring SSL certificate coverage. If you use a single certificate for your main domain only, subdomains will show security warnings. Use a wildcard cert or automate per-subdomain issuance.
Tips
- Use a reverse proxy. If you have multiple services, set up Nginx as a reverse proxy and route subdomains to different backend ports or containers.
- Cache DNS lookups. In your application, cache the subdomain-to-user mapping to avoid a database query on every request.
- Implement a fallback. If a subdomain doesn’t exist, redirect to a signup page or a friendly 404 page.
- Use environment variables for your domain. Hardcoding the domain can cause issues if you change it. Store it in config.
- Consider using a framework’s built-in subdomain routing. Rails, Laravel, and Django have features or packages for this, saving you time.
Troubleshooting
- Subdomain doesn’t resolve. Check that the wildcard DNS record is correct. Use
dig subdomain.yourdomain.comto see what it returns. If it doesn’t show your server IP, wait for propagation or check your DNS provider’s settings. - Server returns a 404 for all subdomains. Your web server configuration likely isn’t catching the wildcard. Double-check the
ServerAliasorserver_namesyntax. Restart the web server after changes. - SSL certificate errors. If you’re using Let’s Encrypt, ensure the DNS-01 challenge can create TXT records automatically. For wildcard certs, verify the certificate covers
*.yourdomain.com. - App doesn’t recognize the subdomain. Check your code that parses the Host header. Ensure you’re extracting the correct part—if your domain has a subdomain like
www, you need to handle that. Also check for trailing dots or port numbers in the header. - Only the main domain works, not subdomains. This often means the wildcard DNS record is missing or the web server isn’t configured to accept wildcard hostnames. Revisit steps 1 and 3.
- Subdomain works but shows the same content as the main site. Your application might be ignoring the subdomain. Make sure you’re actually using the subdomain in your routing logic, not just serving a static site.
Frequently Asked Questions
Do I need to create a DNS record for each user?
No. The wildcard DNS record handles all subdomains automatically. You only need to store the subdomain in your database and configure your server to accept wildcard requests.
Can I use a wildcard subdomain with HTTPS?
Yes. You can use a wildcard SSL certificate (e.g., from Let’s Encrypt) that covers all subdomains, or you can automate per-subdomain certificates using DNS-01 challenges.
What if a user wants a subdomain with dots (e.g., jane.doe)?
Wildcard DNS only covers one level. For multi-level subdomains, you’d need a wildcard for each level (e.g., *.doe.yourdomain.com) or use a different scheme like path-based routing.
How do I handle subdomain collisions?
Before assigning a subdomain, check if it’s already taken. Use a unique identifier like a username or a random string. You can also reserve common names like www or admin.
Is wildcard DNS safe?
Yes, but be cautious. Wildcard DNS can expose your server to more traffic from random subdomains. Ensure your server is secure and that your application handles unknown subdomains gracefully.
Can I use this for a local development environment?
Yes. You can edit your hosts file to point *.localhost or a custom domain to 127.0.0.1, then configure your web server similarly. Tools like dnsmasq can also simulate wildcard DNS locally.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.