DomainsAugust 4, 20265 min read

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.

NBy Nxeon

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.

Deploying a new server with the Nxeon one-click deploy wizard
Deploying a new server with the Nxeon one-click deploy wizard

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.com to 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.

#wildcard#subdomains#dns#vps#nginx#seobatch

Deploy your first server in under a minute

Creating an account is free and takes no card details. You pay when you deploy — choose a billing term and pay from your wallet or by card at checkout.