Point a Namecheap Subdomain to a Separate Server: DNS and Nginx Setup

by Fahim

You built an API, staging environment, or customer dashboard that lives on a separate VPS from your main marketing site. You need app.yourdomain.com or api.yourdomain.com to hit that new IP directly—without touching your apex domain, breaking existing mail routing, or causing downtime.

Here is how I set up an A record in Namecheap BasicDNS, verify resolution with dig, configure an isolated Nginx virtual host on Ubuntu (22.04 or 24.04), and lock it down with Let’s Encrypt.

Close up of server rack networking hardware representing separate subdomain routing
Close up of server rack networking hardware representing separate subdomain routing

The Two-Server Architecture

When you split services across machines, you don’t touch your primary nameservers. Your root domain (example.com) stays on your static host or managed provider, while your subdomain points straight to a dedicated IP on an unmanaged VPS or cloud instance.

Here is how the setup breaks down:

  • Main Site: example.com points to Server A (e.g., 198.51.100.10) hosting your WordPress or landing page.
  • App Subdomain: app.example.com points to Server B (e.g., 203.0.113.45) running a Node.js, Go, or Python backend behind an Nginx reverse proxy.
  • DNS Authority: Namecheap BasicDNS handles resolution for both records independently.

If you are deciding between host record types, check out our guide on Namecheap DNS A record vs CNAME to see when an IP mapping beats an alias.

Step 1: Add the Subdomain Record in Namecheap BasicDNS

Log in to Namecheap and head to your Domain List. Hit Manage next to your domain, then open the Advanced DNS tab.

Check the Host Records table. Leave your root records (@) and www entries alone so you do not take down your main site.

Click Add New Record and fill in:

  • Type: A Record
  • Host: Just the subdomain prefix (e.g., app for app.example.com, or api for api.example.com). Do not enter the full domain here.
  • Value: The public IPv4 address of your target server (e.g., 203.0.113.45).
  • TTL: Set to Automatic or 1 min so changes take effect quickly while testing.

Hit the green checkmark to save. If your secondary server also has an IPv6 address, add a matching AAAA Record using the same host prefix and your server’s IPv6 value.

Step 2: Verify DNS Propagation from the Command Line

Namecheap usually updates their authoritative nameservers within 1 to 3 minutes, but local ISP caching can fool you. Query Google DNS (8.8.8.8) or Cloudflare DNS (1.1.1.1) directly before touching the target server.

Run this from your local terminal:

dig +short app.example.com @8.8.8.8

If the DNS record propagated, you will see your target server IP immediately:

203.0.113.45

If you get an empty response or an NXDOMAIN error, query Namecheap’s nameservers directly to make sure the record actually saved in their zone file:

dig +short app.example.com @dns1.registrar-servers.com

Once Namecheap returns the IP, you know the record is live. Any remaining delay is just local resolver TTL caching.

Step 3: Create the Nginx Server Block on the Target Server

SSH into your secondary server (Server B). You need an isolated virtual host config so Nginx routes incoming traffic for this specific subdomain instead of falling back to a default catch-all.

Create a new configuration file in /etc/nginx/sites-available/:

sudo nano /etc/nginx/sites-available/app.example.com.conf

Paste in the configuration below. This handles both a static webroot or a reverse proxy passing traffic to a local app on port 3000:

server { listen 80; listen [::]:80; server_name app.example.com; # Path for static files or ACME challenges root /var/www/app.example.com/public; index index.html index.htm; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; # Logging access_log /var/log/nginx/app.example.com.access.log; error_log /var/log/nginx/app.example.com.error.log warn; location / { # If serving static files: try_files $uri $uri/ =404; # Or if proxying to a local backend app (uncomment below): # proxy_pass http://127.0.0.1:3000; # proxy_http_version 1.1; # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection 'upgrade'; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto $scheme; # proxy_cache_bypass $http_upgrade; }
}

If you are deploying a framework like Laravel or SvelteKit on this host, check our complete guide on deploying Laravel with Namecheap DNS and Nginx for framework-specific PHP-FPM fastcgi parameters.

Step 4: Enable the Virtual Host and Test Syntax

Create the webroot directory if you are serving static files, set user permissions, and symlink the file into /etc/nginx/sites-enabled/.

Run these on the target server:

sudo mkdir -p /var/www/app.example.com/public
sudo chown -R www-data:www-data /var/www/app.example.com
sudo chmod -R 755 /var/www/app.example.com # Create a test index file
echo "" | sudo tee /var/www/app.example.com/public/index.html # Enable the configuration
sudo ln -s /etc/nginx/sites-available/app.example.com.conf /etc/nginx/sites-enabled/

Always test your Nginx configuration syntax before reloading the daemon:

sudo nginx -t

You should see a successful test confirmation:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Reload Nginx to apply the new site:

sudo systemctl reload nginx

Step 5: Issue a Free Let’s Encrypt SSL Certificate

Never leave the subdomain running on plain HTTP. Use Certbot to automate TLS certificate issuance from Let’s Encrypt.

Install Certbot and the Nginx plugin via snap if you haven’t already:

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Request the certificate for your subdomain:

sudo certbot --nginx -d app.example.com

Certbot parses your Nginx server block, handles the HTTP-01 challenge by placing a temporary token in your webroot, and updates /etc/nginx/sites-available/app.example.com.conf to handle HTTPS on port 443 with automatic HTTP-to-HTTPS redirects.

If you prefer a single wildcard certificate across multiple subdomains, check out our guide on setting up Let’s Encrypt wildcard certificates with Certbot DNS-01.

Gotchas I Hit: Firewall Rules and the Default Server Trap

When I first set this up, two issues caused silent connection timeouts that cost me 20 minutes of debugging.

1. Unopened Ports on the Target Host Firewall

Ubuntu instances usually run ufw out of the box. Even if Nginx is listening on ports 80 and 443, external traffic drops silently if the firewall blocks incoming connections.

Run this on Server B to open web traffic:

sudo ufw allow 'Nginx Full'
sudo ufw reload

If you run on AWS EC2, GCP, or DigitalOcean with external cloud firewalls, ensure your inbound security rules permit port 80 and 443 from 0.0.0.0/0.

2. The Default Server Catch-All Conflict

If you leave the default Nginx site enabled at /etc/nginx/sites-enabled/default with listen 80 default_server;, requests with mismatched host headers or missing SNI can land on the default page instead of your new block.

Remove the default symlink to avoid weird routing quirks:

sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx

Testing Your New Subdomain

Test the live HTTPS connection from your local machine using curl -I to inspect response headers and the TLS handshake:

curl -I https://app.example.com

You should see an HTTP/2 200 OK or 301 response coming straight from your secondary server:

HTTP/2 200 server: nginx/1.24.0 (Ubuntu)
date: Thu, 20 Feb 2025 14:18:22 GMT
content-type: text/html
content-length: 44
last-modified: Thu, 20 Feb 2025 14:15:00 GMT
strict-transport-security: max-age=31536000; includeSubDomains

Your apex domain continues running untouched on your main server, while your subdomain points cleanly to your standalone infrastructure.

Frequently Asked Questions

Does pointing a subdomain to another server affect my main website?

No. DNS routes records independently. Your apex domain (example.com) and www records keep their own A or CNAME targets. Adding or editing a subdomain host record will not touch traffic going to your main web server.

Will changing subdomain DNS break my custom domain email?

No. Mail routing is handled entirely by MX records on your apex domain or dedicated mail hosts. As long as you leave your MX and SPF/DKIM TXT records alone in Namecheap, email delivery won’t skip a beat.

Should I use an A Record or a CNAME for my subdomain?

Use an A Record if your secondary server has a static public IPv4 address. Use a CNAME Record if your target platform provides a hostname instead of a dedicated IP (like Heroku, AWS Elastic Beanstalk, or Vercel). If you are deploying to Vercel, read our guide on pointing Namecheap domains to Vercel with apex DNS.

Why is Certbot failing the HTTP-01 verification challenge?

Certbot fails if DNS has not propagated to Let’s Encrypt’s edge servers yet, if your firewall blocks port 80, or if an Nginx routing rule blocks access to /.well-known/acme-challenge/. Double-check that port 80 is open in both ufw and your cloud provider’s security groups.

Next Steps

With your subdomain resolving to your secondary server, tighten your Nginx security headers and caching rules. If you are serving heavy static assets or API responses, check out our tutorial on configuring immutable cache-control headers in Nginx to keep origin load low.

Official resources

all_in_one_marketing_tool