How to Set Up a Wildcard Subdomain on a VPS
A wildcard subdomain catches every subdomain at once — ideal for multi-tenant apps and dynamic subdomains. Here's the DNS record, the wildcard SSL cert, and the Nginx config.

A wildcard subdomain — *.example.com — matches *any* subdomain that doesn't have its own record. It's what powers multi-tenant apps (acme.yourapp.com, globex.yourapp.com) and dynamic preview URLs without adding a DNS record per customer. This guide covers the DNS record, the wildcard TLS certificate, and the web-server config to make it real on a VPS.
Step 1: Add the wildcard DNS record
In your DNS panel:
- Type: A, Name:
*, Value:203.0.113.10(your VPS IP), TTL: 3600
That's it — * is the wildcard. Now anything.example.com resolves to your server. Note that a wildcard does not cover the root (example.com) or the bare www unless you add those separately, and any explicit record (say an A record for mail) always wins over the wildcard for that name. The concept is covered in wildcard DNS and catch-all subdomains.
Verify:
dig +short random123.example.com
dig +short whatever.example.com
Both should return your VPS IP.
Step 2: Get a wildcard SSL certificate
A normal certificate covers one hostname; a wildcard certificate covers *.example.com. Let's Encrypt issues these free, but wildcard certs require the DNS-01 challenge, which means Certbot needs to create a temporary TXT record — easiest via your DNS provider's API plugin. With Cloudflare, for example:
apt install certbot python3-certbot-dns-cloudflare
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d "example.com" -d "*.example.com"
The credentials file holds an API token scoped to edit that zone. Background on free certs: free SSL certificates with Let's Encrypt and free SSL for a custom domain.

Step 3: Configure Nginx for the wildcard
Point a server block at the wildcard so every tenant hits the same app, which reads the Host header to decide which tenant it is:
server {
listen 443 ssl;
server_name *.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Test and reload:
nginx -t && systemctl reload nginx
Your app at port 3000 now receives every subdomain and can route on $host. If you also want specific subdomains to hit different ports, combine this with how to point a subdomain to a different app or port.
Step 4: Handle the app logic
The DNS and TLS are done — your app extracts the tenant from the hostname. In Node/Express:
app.use((req, res, next) => {
const tenant = req.hostname.split(".")[0]; // "acme" from acme.example.com
req.tenant = tenant;
next();
});
Automate wildcard certificate renewal
Wildcard certs from Let's Encrypt last 90 days, and the DNS-01 challenge needs a fresh TXT record each renewal — so automate it. With the DNS plugin installed, Certbot already saved the config; a renewal just re-runs the challenge:
certbot renew --dry-run
If the dry run succeeds, the systemd timer or cron job Certbot installed will renew silently. Check the timer is active:
systemctl list-timers | grep certbot
The only thing that breaks unattended renewal is a stale or under-scoped DNS API token, so use a token that can edit the zone and doesn't expire. Background on the certificates themselves: free SSL certificates with Let's Encrypt.
Test multi-tenant routing
Before real customers arrive, confirm your app routes correctly on arbitrary subdomains. Because the wildcard resolves *anything*, you can test with a random label:
curl -H "Host: acme.example.com" https://example.com -k
curl -H "Host: globex.example.com" https://example.com -k
Each should return that tenant's content, proving your $host-based routing works. If both return the same tenant, your app isn't reading the hostname — revisit the middleware.
A security note on wildcard scope
A wildcard is powerful precisely because it's broad, and that's also its risk. Two things to keep in mind:
- One wildcard cert covers every subdomain, so if that private key leaks, an attacker can impersonate *all* of them. Store the key with tight permissions (
chmod 600) and never commit it. - Explicit records win. If you later need
mail.example.comto behave differently, add a specific record for it — it overrides the wildcard for that exact name. This is how you carve mail, staging or a specific app out of the wildcard. For staging specifically, see how to create a staging subdomain for your site.
Wildcards also don't stop bots probing random subdomains, so keep your app's auth and rate-limiting solid regardless of DNS.
FAQ
Does a wildcard cover the root domain?
No. *.example.com matches subdomains only. Add a separate A record for example.com (and www) if you need those.
Do I need a wildcard SSL certificate?
If you serve HTTPS on arbitrary subdomains, yes — a per-host cert can't cover names you don't know in advance. Let's Encrypt issues wildcard certs free via the DNS-01 challenge.
Will an explicit subdomain record override the wildcard?
Yes. A specific record (e.g. an A record for mail.example.com) always takes precedence over the wildcard for that exact name.
Can I use a wildcard CNAME instead of an A record?
Yes — * CNAME to another host works the same way, subject to the usual CNAME rules. An A record is simplest when pointing at your own VPS IP.
Can I have a wildcard and specific subdomains at the same time?
Yes — it's the normal setup. A wildcard * record is a fallback that answers for any subdomain with no record of its own. The moment you add an explicit record — an A record for mail.example.com, a CNAME for shop.example.com — that specific record wins for that exact name, and the wildcard handles everything else. This lets you route mail to a mail server, shop to a SaaS platform, and every other subdomain to your multi-tenant app from one zone. The one subtlety: a wildcard matches a single label, so *.example.com covers a.example.com but not a.b.example.com — you'd add *.b.example.com for that deeper level.
Multi-tenant apps love a VPS you fully control. Spin up an NVMe VPS with root access from Nxeon, or if you build with containers, our Docker hosting has you covered.