Skip to main content

Command Palette

Search for a command to run...

🌐 Mastering Subdomains on DigitalOcean: A Step-by-Step Guide with Nginx & SSL

Updated
3 min read
🌐 Mastering Subdomains on DigitalOcean: A Step-by-Step Guide with Nginx & SSL
M

I’m Insaf Nilam, a full-stack developer passionate about crafting clean, efficient, and future-ready software. I love solving complex problems, exploring new tech stacks, and sharing my learnings through blogs. When I’m not coding, I’m probably tweaking deployments, experimenting with microservices, or geeking out over cloud architecture.

If you have a primary domain (e.g., azan.lk) hosted on DigitalOcean, adding subdomains like dev.azan.lk is a simple process. In this guide, we’ll show you how to create subdomains, configure Nginx, and secure them with Let’s Encrypt SSL.


Prerequisites

  1. A DigitalOcean droplet running Ubuntu 24.04.

  2. Your primary domain (azan.lk) already pointing to DigitalOcean nameservers.

  3. SSH access to your droplet.
    Check this guide for secure SSH setup: Fortify Your DigitalOcean Droplet.


Step 1 — SSH Into Your Server

ssh deploy_user

Navigate to the web root directory:

cd /var/www/html

Step 2 — Create Subdomain Directory

Create a folder for your subdomain:

sudo mkdir dev.azan.lk
sudo chown -R $USER:$USER /var/www/html/dev.azan.lk

cd /var/www/html/dev.azan.lk

Add a test PHP file to verify everything works:

nano index.php
<?php phpinfo();?>

Adjust permissions:

sudo chown -R $USER:www-data .
sudo find . -type f -exec chmod 664 {} \;

Step 3 — Configure Nginx for the Subdomain

Create a new server block:

cd /etc/nginx/sites-available
sudo vim dev.azan.lk

Paste the following configuration:

server {
    listen 80;
    listen [::]:80;

    server_name dev.azan.lk;
    root /var/www/html/dev.azan.lk;

    index index.php;
    charset utf-8;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/var/run/php/php8.4-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Enable the site and test Nginx:

sudo ln -s /etc/nginx/sites-available/dev.azan.lk /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx

Step 4 — Configure DNS in DigitalOcean

You have two options:

Option 1 — CNAME (points to main domain)

TypeHostnameValueTTL
CNAMEdevazan.lk43200
Aazan.lk123.45.67.893600

Option 2 — A Record (points directly to server IP)

TypeHostnameValueTTL
Adev123.45.67.893600

Replace 123.45.67.89 with your droplet’s public IP.
A direct A record is slightly faster and simpler.

After updating the DNS Records

  1. Wait a few minutes for DNS to propagate (TTL matters).

  2. Test from your machine:

nslookup dev.azan.lk
ping dev.azan.lk

If it resolves to your server IP → browser will reach Nginx.


Step 5 — Enable SSL with Let’s Encrypt

If you see this warning when accessing your subdomain:

Your connection is not private
net::ERR_CERT_COMMON_NAME_INVALID

Install Certbot and enable HTTPS:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d dev.azan.lk

sudo certbot renew --dry-run

Follow the prompts:

  • Enter your email for renewal notifications.

  • Agree to Let’s Encrypt terms.

  • Choose to redirect HTTP to HTTPS.


Step 6 — Test Your Subdomain

Visit https://dev.azan.lk. You should see the PHP info page, confirming your subdomain is live and secured.


✅ Summary

  • Subdomains are just directories with their own Nginx configuration.

  • DigitalOcean lets you manage DNS and subdomains easily.

  • Let’s Encrypt SSL keeps your subdomains secure and trusted.

More from this blog

I

Insaf’s Dev Journal

28 posts