Guide: Create a Subdomain on Ubuntu + Apache + Certbot
This is the exact process we followed: DNS A record → deploy static repo → Apache VirtualHost (port 80) → HTTPS with Certbot. Ubuntu 24.04 LTS Apache 2.4 Certbot
0) Before you start
- You need a VPS with Apache installed and running.
- You need access to the domain DNS (Hostinger panel).
- Use your normal user (e.g.,
daniel) and run admin actions withsudo(recommended).
✅ Good practice: work as a regular user with sudo, not as root.
1) Create the DNS record (Hostinger panel)
Create an A record:
- Name/Host:
subdomain - Type:
A - Value:
<YOUR_VPS_PUBLIC_IP> - TTL: default is fine
⏳ Note: DNS propagation can take minutes (sometimes longer).
2) Deploy your site files
Recommended path pattern on Ubuntu:
/var/www/subdomain/public
2.1 Create folders + permissions
sudo mkdir -p /var/www/subdomain/public
sudo chown -R daniel:www-data /var/www/subdomain
sudo chmod -R 2755 /var/www/subdomain
2.2 Copy or clone your repo
Option A: copy from an existing clone:
rsync -av --delete ~/path/to/repo/ /var/www/subdomain/public/
Option B: clone directly into /var/www:
cd /var/www/subdomain
git clone <REPO_URL> public
sudo chown -R daniel:www-data /var/www/subdomain
2.3 Confirm you have an entry point
ls -la /var/www/subdomain/public
# You should see index.html (or your main HTML file)
3) Configure Apache (HTTP / port 80)
Create a new VirtualHost file:
sudo nano /etc/apache2/sites-available/subdomain.conf
Paste this (update domain + paths):
<VirtualHost *:80>
ServerName subdomain.seriousdesign.net
DocumentRoot /var/www/subdomain/public
<Directory /var/www/subdomain/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/subdomain_error.log
CustomLog ${APACHE_LOG_DIR}/subdomain_access.log combined
</VirtualHost>
3.1 Enable the site + reload
sudo a2ensite subdomain.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
✅ Expected: apache2ctl configtest returns Syntax OK.
3.2 Optional: disable the default site
If you don’t want Apache to ever serve the default placeholder site:
sudo a2dissite 000-default.conf
sudo systemctl reload apache2
4) Verify routing & DNS
4.1 Confirm DNS resolves on the server
getent hosts subdomain.seriousdesign.net
✅ Expected: it returns an IP address (your VPS IP).
4.2 Confirm Apache sees your vhost
sudo apache2ctl -S
✅ Expected: a line like
port 80 namevhost subdomain.seriousdesign.net (.../subdomain.conf:1)
4.3 Test HTTP response
curl -I http://subdomain.seriousdesign.net
5) Enable HTTPS (Certbot + Apache plugin)
5.1 Confirm Certbot is installed
certbot --version
5.2 Request certificate and auto-configure Apache
sudo certbot --apache -d subdomain.seriousdesign.net
When prompted, choose the option to redirect HTTP → HTTPS (recommended).
5.3 Reload and confirm your HTTPS vhost exists
sudo systemctl reload apache2
sudo apache2ctl -S | grep -E "subdomain\.seriousdesign\.net|:443"
5.4 Test HTTPS response
curl -I https://subdomain.seriousdesign.net
6) Confirm auto-renewal
sudo certbot renew --dry-run
✅ Expected: renewal simulation succeeds (no errors).
7) Troubleshooting checklist
- DNS not ready:
getent hosts subdomain.seriousdesign.netshows wrong IP or nothing. - Apache vhost not loaded: check
/etc/apache2/sites-enabled/and runsudo apache2ctl -S. - Syntax errors: run
sudo apache2ctl configtest. - Check logs:
sudo tail -n 100 /var/log/apache2/subdomain_error.log sudo tail -n 100 /var/log/apache2/subdomain_access.log
Appendix: What these commands mean (quick)
lsb_release -a→ shows Ubuntu distribution/version (helps match correct docs).apache2 -v→ shows Apache version/build (directive compatibility).apache2ctl -S→ shows loaded vhosts and which is default per port (routing table).a2dissite 000-default.conf→ disables the default catch-all site (optional, often recommended).
End of guide.