The problem
To point a domain at your VPS you need two systems, DNS and nginx, agreeing on the same name. So far you have tested everything with a fake hostname like myapp.test, or by typing the server's raw IP address into the browser. That works for you and nobody else. It also does not look like a real site.
Going live means two halves meet in the middle:
-
DNS tells the internet "the name
yourdomain.comlives at this IP address". -
Nginx decides which site answers when a request arrives for that name, using
server_name(from listen and server_name).
Get both right and typing yourdomain.com lands on your server, and your server hands back the correct site. This lesson wires up both halves.
What is a DNS A record?
Your domain lives at a registrar or DNS provider (Namecheap, Cloudflare, OVH, and so on). There you edit DNS records. The one that matters most is the A record.
An A record maps a hostname to an IPv4 address:
Type Name Value TTL
A @ 203.0.113.10 3600
-
Type is
A. -
Name is
@, which means the bare domain itself (yourdomain.com). -
Value is your server's public IPv4 address. Your VPS provider shows this in its dashboard, or you can run
curl -4 ifconfig.meon the server itself. - TTL (time to live) is how many seconds resolvers may cache the answer. More on that below.
If your server also has an IPv6 address, add an AAAA record too. It is the same idea, but for IPv6:
Type Name Value TTL
AAAA @ 2001:db8::10 3600
AAAA is optional. If you do not have or do not want IPv6, skip it. But if you add an AAAA record, make sure it points at a working address, because some visitors will use it. A stale AAAA left over from an old host is a nasty one to debug: IPv6 clients try it first, fail silently, and the site looks down for half your audience while dig +short yourdomain.com (IPv4) looks perfect.
Add @ and www
Most people want the site to answer on both yourdomain.com and www.yourdomain.com. That is two names, so you add a record for each.
The simplest, most reliable setup is two A records pointing at the same IP:
Type Name Value TTL
A @ 203.0.113.10 3600
A www 203.0.113.10 3600
@ covers the bare domain and www covers the www. version. Both now resolve to your server. (You can instead make www a CNAME pointing at the bare domain, but two A records is easier to reason about when you are starting out.)
Save the records in your provider's panel. That is the DNS half done.
TTL and DNS propagation: why changes are not instant
DNS answers are cached all over the internet to keep it fast. When you add or change a record, the new value is not instant everywhere. This delay is called propagation.
-
TTL is the cache lifetime in seconds.
3600means one hour. A resolver that already cached the old answer may keep using it until the TTL expires. - A brand-new record (there was nothing before) usually shows up within minutes, because there was no old value to cache.
- A changed record can take up to the old TTL to clear everywhere. If you plan to change a record soon, lower its TTL first (say to
300), wait, then make the change.
The short version: if a fresh record does not resolve right away, wait a bit before assuming something is broken. One practical tip before a planned migration: drop the TTL to 300 a day ahead. The lower TTL itself has to propagate first, so setting it at the last minute buys you nothing.
Check DNS propagation with dig
Do not guess whether DNS is ready. Ask a resolver directly from your own machine.
dig +short yourdomain.com
+short trims the output to just the answer. When the record is live you'll see your server's IP:
203.0.113.10
Check www too:
dig +short www.yourdomain.com
If dig is not installed (it comes from dnsutils), or you are on Windows, nslookup does the same job:
nslookup yourdomain.com
You are looking for one thing: the IP in the answer matches your VPS's public IP. If dig prints nothing, the record has not propagated yet (or you typed the name wrong). Wait and try again.
Match the domain in nginx server_name
DNS gets the request to your server. Now nginx has to claim the name. Open the server block for your site (you set these up in includes and sites) and set server_name to both names:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/myapp/public;
# ... the rest of your config
}
server_name lists every name this block should answer to, separated by spaces. Here it claims both the bare domain and the www version, which is exactly the two names you set up in DNS.
Test and reload, the same safe two-step you learned in testing config safely:
sudo nginx -t && sudo systemctl reload nginx
Test the whole path
Now check both halves together. From your own machine:
curl -I http://yourdomain.com
-I fetches just the response headers. A 200 OK (or a redirect you set up on purpose) means the request travelled all the way: DNS pointed at your server, and nginx matched the name and answered. Open the domain in a browser for the final confirmation.
Common mistake: DNS has not propagated yet
The classic "it does not work" is really "it does not work yet". You added the record, typed the domain, got nothing, and assumed the config is broken.
Always confirm DNS first:
dig +short yourdomain.com
No answer, or the wrong IP, means the problem is DNS, not nginx. There is nothing to fix in your config. Wait for propagation and re-check.
Common mistake: server_name does not match
DNS is correct, the request reaches your server, but you see the wrong page (often nginx's default "Welcome to nginx" page). That means no server block's server_name matched the incoming name, so nginx fell back to the default site.
This happens when:
- You put
yourdomain.comin DNS but leftserver_name myapp.test;in the config. - You added the domain but forgot
www, sowww.yourdomain.commatches nothing.
Fix it by listing the exact names in server_name, then reload. When the name in the request matches the name in the block, your site answers instead of the default. (Chapter 3's listen and server_name covers exactly how nginx picks a block.)
FAQ
How long does DNS really take?
A new record is usually usable within a few minutes and almost always within an hour. Changes to an existing record can take up to its old TTL. If it has been well over an hour and dig still shows nothing, re-check that you saved the record at the right provider and used the correct IP.
Do I need both A and AAAA records?
No. A single A record (IPv4) is enough to be reachable by everyone. Add an AAAA record only if your server has a real IPv6 address and you want IPv6 visitors to use it. A broken AAAA record is worse than none, because IPv6 clients will try it first.
Should I use @ and www, or just one?
Set up both names in DNS and in server_name so neither version is a dead end. Then, once HTTPS is on, it is common to pick one as canonical and redirect the other to it (see redirect http to https for the redirect pattern).
dig works but the browser still fails. Why?
Your browser or operating system may be caching an older lookup, or you are behind a VPN or corporate resolver. Confirm with dig +short from the command line first. If dig is correct, flush your local DNS cache or try a different network before touching the server config.