Custom Domains & Networking
Configure custom domains, DNS, load balancers, VPCs, and SSL certificates on DigitalOcean.
What you'll accomplish
Your application accessible via custom domain with proper networking
Prerequisites
- Application deployed
- Domain name you own
Domain Management
DigitalOcean provides free DNS hosting for your domains.
Add a Domain
bash# Add domain to DigitalOcean doctl compute domain create example.com # Point to Droplet doctl compute domain records create example.com \ --record-type A \ --record-name @ \ --record-data DROPLET_IP \ --record-ttl 1800
Update Nameservers
At your domain registrar, set nameservers to:
ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
Common DNS Records
bash# A record (IPv4) doctl compute domain records create example.com \ --record-type A \ --record-name @ \ --record-data 1.2.3.4 # AAAA record (IPv6) doctl compute domain records create example.com \ --record-type AAAA \ --record-name @ \ --record-data 2001:db8::1 # CNAME record (alias) doctl compute domain records create example.com \ --record-type CNAME \ --record-name www \ --record-data @ # MX record (email) doctl compute domain records create example.com \ --record-type MX \ --record-name @ \ --record-data mail.example.com \ --record-priority 10 # TXT record (verification) doctl compute domain records create example.com \ --record-type TXT \ --record-name @ \ --record-data "v=spf1 include:_spf.google.com ~all"
List DNS Records
bashdoctl compute domain records list example.com
Update/Delete Records
bash# Update record doctl compute domain records update example.com \ --record-id RECORD_ID \ --record-data NEW_IP # Delete record doctl compute domain records delete example.com RECORD_ID
App Platform Domains
Add Custom Domain
- Control Panel → App → Settings → Domains
- Click Add Domain
- Enter your domain
- Follow DNS instructions
DNS Configuration for App Platform
| Type | Name | Value |
|---|---|---|
| CNAME | www | your-app.ondigitalocean.app |
| CNAME | @ | your-app.ondigitalocean.app |
Or use A record if CNAME not supported for apex:
| Type | Name | Value |
|---|---|---|
| A | @ | (IP from DigitalOcean) |
SSL Certificates
App Platform provides automatic SSL:
- Let's Encrypt certificates
- Automatic renewal
- Force HTTPS option
Load Balancers
Distribute traffic across multiple Droplets.
Create Load Balancer
bash# Create load balancer doctl compute load-balancer create \ --name mylb \ --region nyc1 \ --forwarding-rules "entry_protocol:http,entry_port:80,target_protocol:http,target_port:3000" \ --health-check "protocol:http,port:3000,path:/health,check_interval_seconds:10,response_timeout_seconds:5,healthy_threshold:3,unhealthy_threshold:3" \ --droplet-ids DROPLET_ID_1,DROPLET_ID_2
Using Tags
Auto-discover Droplets by tag:
bash# Tag your Droplets doctl compute droplet tag DROPLET_ID --tag-name web # Create LB with tag doctl compute load-balancer create \ --name mylb \ --region nyc1 \ --tag-name web \ --forwarding-rules "entry_protocol:http,entry_port:80,target_protocol:http,target_port:3000"
HTTPS Termination
bash# First, upload certificate doctl compute certificate create \ --name mycert \ --type lets_encrypt \ --dns-names example.com,www.example.com # Create HTTPS load balancer doctl compute load-balancer create \ --name mylb \ --region nyc1 \ --forwarding-rules "entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:CERT_ID" \ --forwarding-rules "entry_protocol:http,entry_port:80,target_protocol:http,target_port:3000" \ --redirect-http-to-https \ --droplet-ids DROPLET_ID
Health Checks
Configure proper health checks:
bashdoctl compute load-balancer update LB_ID \ --health-check "protocol:http,port:3000,path:/api/health,check_interval_seconds:10"
Sticky Sessions
bashdoctl compute load-balancer update LB_ID \ --sticky-sessions "type:cookies,cookie_name:lb_session,cookie_ttl_seconds:3600"
VPC (Virtual Private Cloud)
Isolate your resources in private networks.
Create VPC
bash# Create VPC doctl vpcs create \ --name myvpc \ --description "Production VPC" \ --region nyc1 \ --ip-range 10.10.10.0/24
Create Resources in VPC
bash# Create Droplet in VPC doctl compute droplet create myserver \ --image ubuntu-22-04-x64 \ --size s-1vcpu-1gb \ --region nyc1 \ --vpc-uuid VPC_UUID
VPC Benefits
- Resources communicate via private IPs
- No bandwidth charges for VPC traffic
- Isolated from other customers
- Secure by default
List VPCs
bashdoctl vpcs list
Cloud Firewalls
Network-level security rules.
Create Firewall
bash# Create firewall with rules doctl compute firewall create \ --name myfw \ --inbound-rules "protocol:tcp,ports:22,address:YOUR_IP/32" \ --inbound-rules "protocol:tcp,ports:80,address:0.0.0.0/0,::/0" \ --inbound-rules "protocol:tcp,ports:443,address:0.0.0.0/0,::/0" \ --outbound-rules "protocol:tcp,ports:all,address:0.0.0.0/0,::/0" \ --outbound-rules "protocol:udp,ports:all,address:0.0.0.0/0,::/0" \ --droplet-ids DROPLET_ID
Rule Examples
bash# Allow SSH from specific IP --inbound-rules "protocol:tcp,ports:22,address:1.2.3.4/32" # Allow HTTP from anywhere --inbound-rules "protocol:tcp,ports:80,address:0.0.0.0/0,::/0" # Allow from tag --inbound-rules "protocol:tcp,ports:3000,tag:web" # Allow from load balancer --inbound-rules "protocol:tcp,ports:3000,load_balancer_uid:LB_ID" # Allow internal VPC traffic --inbound-rules "protocol:tcp,ports:all,address:10.10.10.0/24"
Apply to Multiple Droplets
bash# By tag doctl compute firewall add-tags FW_ID --tag-names web,api # By Droplet ID doctl compute firewall add-droplets FW_ID --droplet-ids ID1,ID2
SSL Certificates
Let's Encrypt Certificates
DigitalOcean manages Let's Encrypt certificates:
bash# Create certificate doctl compute certificate create \ --name mycert \ --type lets_encrypt \ --dns-names example.com,www.example.com
Requirements:
- Domain DNS hosted on DigitalOcean
- Domain points to DigitalOcean resources
Custom Certificates
bash# Upload custom certificate doctl compute certificate create \ --name mycert \ --type custom \ --certificate-chain-path /path/to/fullchain.pem \ --private-key-path /path/to/privkey.pem \ --leaf-certificate-path /path/to/cert.pem
Use with Load Balancer
bash# Get certificate ID CERT_ID=$(doctl compute certificate list --format ID --no-header) # Create HTTPS forwarding rule doctl compute load-balancer update LB_ID \ --forwarding-rules "entry_protocol:https,entry_port:443,target_protocol:http,target_port:3000,certificate_id:$CERT_ID"
Spaces CDN
Accelerate content delivery with the built-in CDN.
Enable CDN
bash# Via Control Panel: # Spaces → Your Space → Settings → CDN → Enable
CDN URL
https://space-name.region.cdn.digitaloceanspaces.com/file.jpg
Custom Domain for CDN
- Add CNAME record:
cdn.example.com → space.region.cdn.digitaloceanspaces.com - Configure in Space settings
- SSL automatically provided
Reserved IPs
Static IPs that can move between Droplets.
Create Reserved IP
bash# Create and assign to Droplet doctl compute reserved-ip create \ --region nyc1 \ --droplet-id DROPLET_ID
Reassign IP
bash# Unassign doctl compute reserved-ip-action unassign RESERVED_IP # Assign to different Droplet doctl compute reserved-ip-action assign RESERVED_IP DROPLET_ID
Use Cases
- High availability (failover)
- Consistent IP for DNS
- Blue-green deployments
Complete Architecture Example
Internet
│
▼
┌─────────────────────┐
│ Load Balancer │
│ (HTTPS, SSL) │
└──────────┬──────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ web-1 │ │ web-2 │ │ web-3 │
│(Droplet)│ │(Droplet)│ │(Droplet)│
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
└─────────────┼─────────────┘
│ (VPC)
▼
┌─────────────────────┐
│ Managed Database │
│ (PostgreSQL) │
└─────────────────────┘
Setup Script
bash#!/bin/bash set -e # Configuration REGION="nyc1" PROJECT="myapp" # Create VPC VPC_ID=$(doctl vpcs create \ --name ${PROJECT}-vpc \ --region $REGION \ --ip-range 10.10.10.0/24 \ --output json | jq -r '.[0].id') echo "VPC: $VPC_ID" # Create Droplets for i in 1 2; do doctl compute droplet create ${PROJECT}-web-$i \ --image ubuntu-22-04-x64 \ --size s-1vcpu-1gb \ --region $REGION \ --vpc-uuid $VPC_ID \ --tag-names ${PROJECT}-web \ --user-data-file setup.sh done # Wait for Droplets sleep 60 # Create Load Balancer LB_ID=$(doctl compute load-balancer create \ --name ${PROJECT}-lb \ --region $REGION \ --tag-name ${PROJECT}-web \ --forwarding-rules "entry_protocol:http,entry_port:80,target_protocol:http,target_port:3000" \ --health-check "protocol:http,port:3000,path:/health" \ --output json | jq -r '.[0].id') echo "Load Balancer: $LB_ID" # Create Firewall doctl compute firewall create \ --name ${PROJECT}-fw \ --inbound-rules "protocol:tcp,ports:22,address:YOUR_IP/32" \ --inbound-rules "protocol:tcp,ports:3000,load_balancer_uid:$LB_ID" \ --outbound-rules "protocol:tcp,ports:all,address:0.0.0.0/0,::/0" \ --tag-names ${PROJECT}-web # Get LB IP LB_IP=$(doctl compute load-balancer get $LB_ID --format IP --no-header) echo "Load Balancer IP: $LB_IP" echo "Point your domain to: $LB_IP"
Troubleshooting
DNS Not Propagating
bash# Check DNS dig example.com @ns1.digitalocean.com # Wait up to 48 hours for global propagation # Use https://dnschecker.org to verify
SSL Certificate Issues
- Verify domain points to DigitalOcean
- Check DNS is properly configured
- Wait for certificate provisioning (up to 24 hours)
- Check certificate status in Control Panel
Load Balancer Not Routing
- Check health checks are passing
- Verify Droplets are listening on target port
- Check firewall allows LB traffic
- Verify Droplets are in same region
Note
Checkpoint: Configure your custom domain with SSL, verify HTTPS is working, and test load balancer if using multiple backends.