Adding a domain to a DigitalOcean droplet is four steps in a specific order: delegate the domain’s nameservers to DigitalOcean, or leave them at the registrar and just add an A record there, create an A record pointing at the droplet’s public IP, add a server block in nginx that matches the domain name, and issue a certificate once DNS has propagated. Doing the certificate step before DNS has propagated is the most common failure, the ACME challenge cannot verify a domain that does not yet resolve to the droplet, and the fix is patience, not a different command.
This walkthrough is scattered across several sources: DigitalOcean’s own documentation for adding a domain, a Stack Overflow thread on nginx and certificates, a community Q&A on pointing an A record, and a Reddit thread about hosting multiple domains on one droplet. Each covers a piece correctly and none walks the whole path end to end. This post covers the full sequence, deciding where DNS should live, the A record, the nginx server block, the certificate, and how to verify propagation before assuming something is broken. It stays neutral about DigitalOcean throughout; the point is the DNS and TLS mechanics, which apply to any droplet or any VPS from any provider.
Table of contents
- Decide where DNS lives: the registrar or DigitalOcean
- Step one: point the nameservers or add records at the registrar
- Step two: create the A record (and www)
- Step three: the nginx server block
- Step four: certificate with certbot
- Verifying propagation before you assume it’s broken
- How this fits the rest of the stack
- FAQ
Decide where DNS lives: the registrar or DigitalOcean
Two setups both work, and picking one avoids a common mistake, adding a domain in DigitalOcean’s panel without ever pointing the registrar at DigitalOcean’s nameservers, which leaves the DigitalOcean DNS records sitting unused while the domain still resolves according to whatever the registrar has configured. DigitalOcean’s own documentation is explicit about this: delegate the domain to DigitalOcean’s nameservers first if DNS should live there, because DigitalOcean DNS integrates with its load balancers and object storage in ways that only work when it is actually managing the zone.
The alternative, simpler for a single droplet with no load balancer involved, is to leave the domain’s nameservers exactly where they are at the registrar and just add an A record there, pointing straight at the droplet’s public IP. Both are correct. Neither is a domain purchase, DigitalOcean sells the DNS management and the compute; the domain itself still belongs to whichever registrar it was bought from.
Step one: point the nameservers or add records at the registrar
If DNS will live on DigitalOcean, the registrar’s side of the job is short: replace the existing nameservers with DigitalOcean’s three, then add the domain inside DigitalOcean’s control panel or API so it starts answering for that zone.
ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
If DNS stays at the registrar instead, skip the nameserver change entirely and go straight to adding the A record in the registrar’s own DNS panel, described in the next section. Either path ends at the same place, a record somewhere pointing at the droplet’s IP, but only one path involves changing where the domain’s authoritative DNS actually lives. Nameserver changes take effect only once the registrar’s own systems propagate them outward, which is a separate wait from record propagation covered later in this post, and the two are often confused when a domain seems stuck.
Step two: create the A record (and www)
Whichever DNS provider ends up authoritative, the record itself is the same: an A record for the bare domain pointing at the droplet’s IPv4 address, and either a second A record or a CNAME for www pointing at the same place.
Type Name Content TTL
A @ 203.0.113.10 3600
CNAME www example.com 3600
TTL controls how long resolvers cache the record before checking again; a shorter TTL, a few minutes, during the initial setup makes mistakes cheaper to fix, and a longer TTL afterward reduces DNS query load once the record is confirmed working. If the droplet also needs to receive mail or SSH traffic under a specific hostname, add those as separate records rather than trying to reuse the web-facing A record for everything.
Step three: the nginx server block
The DNS record gets traffic to the droplet’s IP address; the nginx server block decides what that traffic actually sees once it arrives. Without a server_name matching the domain, nginx falls back to its default server block, which is why the domain doesn’t work sometimes turns out to be a DNS record pointing correctly at a droplet whose web server has no idea the domain exists.
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
}
Reload nginx after adding the block, nginx -t to check the config first, then a reload of the service, and the domain should serve the site over plain HTTP. HTTPS is the next step, and it depends on this block already working, because the certificate issuer needs a live, correctly routed HTTP endpoint to verify the domain against.
Step four: certificate with certbot
Certbot’s nginx plugin edits the server block automatically once it can prove control of the domain over HTTP, which is exactly why the previous step has to work first. Run it against both the bare domain and www, and it issues a certificate, updates the nginx config to serve HTTPS, and sets up a renewal that runs quietly in the background from then on.
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run
The dry-run renewal check is worth running once right after issuance, it confirms the automatic renewal path actually works before it matters, rather than finding out ninety days from now when the certificate silently expires and nobody set a reminder.
Verifying propagation before you assume it’s broken
The single most common source of confusion in this whole process is trying the certificate step, or just visiting the site, before DNS has actually propagated, and assuming something is broken when the real issue is timing. A record change is not instant everywhere; resolvers around the world cache the previous answer until its TTL expires, which can be minutes or, for a change to the nameservers themselves, up to 48 hours in the worst case.
dig +short example.com
nslookup example.com 8.8.8.8
Both commands ask a specific resolver directly what it currently believes, more reliable than refreshing a browser that has its own DNS cache sitting in front of everything. If dig returns the droplet’s IP but the browser still shows the old site, the browser or OS cache is the culprit, not DNS. If dig returns nothing or the wrong IP, the record itself has not propagated yet, and the fix is patience, not a different command.
A quick way to rule out the local machine entirely: check the record from a phone on mobile data, or from an online propagation checker that queries resolvers in several regions at once. If every one of them already returns the droplet’s IP, the record is live everywhere it needs to be, and any remaining old site is a caching artifact on one specific device, worth clearing rather than worth touching the DNS configuration again. Re-running certbot or re-editing the nginx block at that point fixes nothing, because the DNS and the server were never the problem in the first place.
How this fits the rest of the stack
Every step above exists to solve one problem: proving to the world, and to a certificate authority, that this specific server is allowed to answer for this domain. On a droplet, that is nameservers or records, an nginx block, and a certbot renewal you have to remember every ninety days. On a platform that handles custom domains and certificates itself, the equivalent steps are pointing a CNAME once and attaching the domain in the dashboard, the certificate is issued and renewed automatically, and there is no server block to keep in sync with the DNS by hand. The RunxBuild hosting calculator shows what a service or static site costs once the domain part stops being a maintenance task.
Useful related references:
- The .pt Domain: Who Can Register One, and What to Do Next
- What Is a .link Domain, and When Does It Fit a Project?
- .ES Domain: Requirements, the ID Rules, and Setting It Up
- Custom domains and certificates on RunxBuild
FAQ
Do I need to change my domain’s nameservers to use it with a DigitalOcean droplet?
No, not always. Changing nameservers to DigitalOcean’s makes sense if you want DNS managed there, especially alongside a load balancer or object storage. For a single droplet, it is simpler to leave the domain’s nameservers at the registrar and just add an A record there pointing at the droplet’s IP. Both approaches work equally well for a basic setup.
How long does it take for DNS changes to a droplet to propagate?
Usually minutes for a record change, since most TTLs are set low during initial setup. A nameserver change can take longer, up to 48 hours in the worst case, because it depends on every resolver’s cached copy expiring. Check with dig or nslookup against a specific resolver rather than relying on a browser, which caches DNS on its own.
Why does my SSL certificate fail right after pointing the domain?
Certbot’s HTTP verification needs the domain to already resolve to the droplet and the nginx server block to already be serving that domain correctly over plain HTTP. If DNS has not propagated yet, or the server block’s server_name does not match, the verification request fails before a certificate can be issued. Confirm the site loads over HTTP first, then run certbot.
What DNS record do I need for www to work?
Either a second A record for www pointing at the same IP as the bare domain, or a CNAME record for www pointing at the bare domain itself. A CNAME is slightly easier to maintain, since it follows the A record automatically if the droplet’s IP ever changes, rather than needing its own update.
Can I host multiple domains on one DigitalOcean droplet?
Yes. Point each domain’s A record at the same droplet IP, then add a separate nginx server block per domain with its own server_name and document root. Nginx matches incoming requests to the right block by the hostname in the request, so one droplet can serve several unrelated domains as long as it has the resources for all of them.