NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Domains and DNS

Set up a subdomain

Domains and DNS5 min readUbuntu 24.04 LTS

A subdomain is a name under your main domain, such as blog.example.com. You can point it at the same server as your main site or give it its own. The web server reads the requested name and serves the matching site, so one server can host many subdomains.

Before you begin

  • Your main domain already pointing at the server. See the guide on pointing a domain at your VPS.
  • Access to your DNS settings, so you can add a record for the subdomain.
  • A sudo-enabled user logged in over SSH.

Step 1: Create a DNS record for the subdomain

The simplest option is an A record for the subdomain name pointing at your server's IPv4 address. In your DNS editor, add:

  • Type: A
  • Name: blog
  • Value: 203.0.113.10
  • TTL: 3600

Alternatively, a CNAME named blog that points to example.com. works too, because it follows the main domain's address. Use one or the other, not both.

Step 2: Confirm the record

Check that the new name resolves. It can take a little time to appear, depending on the TTL:

dig +short blog.example.com A
203.0.113.10

Step 3: Install nginx and create a site folder

nginx is an open-source web server that handles many sites on one machine. Install it, then create a folder to hold the subdomain's files:

sudo apt update
sudo apt install -y nginx
sudo mkdir -p /var/www/blog.example.com/html

The -p flag creates any missing parent folders. Next, give the folder world-readable permissions so nginx can serve the files, and create a simple test page:

sudo chmod -R 755 /var/www/blog.example.com
echo 'Hello from blog.example.com' | sudo tee /var/www/blog.example.com/html/index.html

The chmod 755 command lets everyone read the files but only the owner change them. The tee command writes the test line into index.html.

Step 4: Write a server block

A server block tells nginx which name to answer for and which folder to serve. Create one for the subdomain:

sudo nano /etc/nginx/sites-available/blog.example.com

Enter the following, then save with Ctrl+O and exit with Ctrl+X:

server {
    listen 80;
    listen [::]:80;
    server_name blog.example.com;

    root /var/www/blog.example.com/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

server_name must match the subdomain exactly. root points at the folder you created. listen lines accept IPv4 and IPv6 connections on port 80.

Step 5: Enable the site and reload nginx

nginx loads configurations from sites-enabled, so create a link there. Then test the whole configuration before reloading:

sudo ln -s /etc/nginx/sites-available/blog.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Step 6: Allow web traffic through the firewall

If you followed the firewall guide, port 80 is already open. Confirm it:

sudo ufw status

If port 80 is missing, add it with sudo ufw allow 80/tcp.

Step 7: Test the subdomain

Request the page from your computer. curl downloads a page and prints it in the terminal:

curl http://blog.example.com
Hello from blog.example.com
Tip: Create a separate server block and folder for each subdomain. Keeping them apart makes it easy to change or remove one site without affecting the others.
Careful: Serving plain HTTP means visitors' traffic is not encrypted. Add HTTPS before you use the site for logins or forms.

Troubleshooting

  • 404 Not Found. The root path is wrong or the file is missing. List the folder with ls /var/www/blog.example.com/html and confirm index.html is there.
  • The default nginx welcome page appears. The server_name does not match, or the default site is taking priority. Remove the default link with sudo rm /etc/nginx/sites-enabled/default and reload nginx.
  • nginx -t reports an error. The message names the file and line. Fix the typo, such as a missing semicolon, then test again.
  • Permission denied in the error log. Check the folder permissions with ls -ld /var/www/blog.example.com. Read the latest errors with sudo tail -n 20 /var/log/nginx/error.log.

Next steps

Your subdomain serves a page over plain HTTP. To add free HTTPS, install Certbot with the nginx plugin, then run sudo certbot --nginx -d blog.example.com. It obtains a certificate from a free certificate authority and configures nginx for you.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support