Ravindra BagaleCourses & study guides

Chapter 9: Domain Names, DNS and Subdomains

9.10 Subdomains

Subdomains are free and unlimited. Each one is just another DNS record plus (usually) another server block or virtual host.

 example.com        ─┐
 www.example.com    ─┼─► A 13.233.10.25 (web-1) ─► server_name decides the folder
 blog.example.com   ─┘                              /var/www/example, /var/www/blog
 api.example.com    ───► A 13.234.55.60 (app server, Node on :3000 behind Nginx)
 shop.example.com   ───► CNAME my-alb-123.ap-south-1.elb.amazonaws.com

Step 1: DNS record (GoDaddy → DNS → Add New Record)

Type Name Value Use
A blog 13.233.10.25 Same server, different site
A api 13.234.55.60 Different EC2 instance (its own Elastic IP)
CNAME shop my-​alb-​123.​ap-​south-​1.​elb.​amazonaws.​com AWS load balancer / other hostname
A * 13.233.10.25 Wildcard: any undefined subdomain

In the Name field type only the subdomain part (blog), not blog.example.com. Otherwise you may create blog.example.com.example.com.

Step 2: a site for the subdomain on the server

sudo mkdir -p /var/www/blog
echo '<h1>Welcome to blog.example.com</h1>' | sudo tee /var/www/blog/index.html
# Nginx: blog.conf
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
    index index.html;
}
# Apache: blog.conf
<VirtualHost *:80>
    ServerName blog.example.com
    DocumentRoot /var/www/blog
    <Directory /var/www/blog>
        Require all granted
    </Directory>
</VirtualHost>

Test, reload, then verify with dig blog.example.com +short and curl http://blog.example.com.

Subdomain for a backend app (reverse proxy)

server {
    listen 80;
    server_name api.example.com;
    location / {
        proxy_pass http://127.0.0.1:3000;        # Express / Flask app (Chapter 10)
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

(On CentOS remember sudo setsebool -P httpd_can_network_connect 1.)