A complete step-by-step guide. No experience needed — just follow the steps in order.
You will host 3 websites on a single Linux server using Apache's Virtual Host feature. Each site gets its own free domain name and its own folder on the server.
The three .conf files provided are already an example of the final result. This guide will show you exactly how to create them.
You need the public IP of your Linux server. Run this command on the server:
curl ifconfig.me
It will print something like 85.12.34.56. Write it down — you'll need it in the next step.
VPS or cloud server? Your IP is shown in your provider's dashboard (DigitalOcean, Hetzner, AWS, etc.). Use that IP directly.
You need 3 free hostnames that point to your server's IP. You can use any combination of these services:
mysitename.ddns.net) → enter your server IP → Save.
istrati.dynu.net) → enter your server IP → Save.
Repeat for all 3 sites. By the end you'll have 3 hostnames like:
istrati.ddns.net # Site 1 – No-IP → yourname.ddns.net istrati.duckdns.org # Site 2 – DuckDNS → yourname.duckdns.org istrati.dynu.net # Site 3 – Dynu → yourname.dynu.net
DNS takes a few minutes to propagate. After setting the IP, wait 2–5 minutes before testing. You can verify with: ping yourdomain.ddns.net
Connect to your server via SSH, then run:
sudo apt update sudo apt install -y apache2
Check it's running:
sudo systemctl status apache2
You should see active (running) in green. If you visit your server's IP in a browser you'll see the default Apache page — that's good.
Each site needs its own folder. Site 1 already has /var/www/html (Apache's default). Create the others:
# Site 2 folder sudo mkdir -p /var/www/sito-alternativo # Site 3 folder sudo mkdir -p /var/www/sito-alternativo2 # Give your user write permission sudo chown -R $USER:$USER /var/www/sito-alternativo sudo chown -R $USER:$USER /var/www/sito-alternativo2
Each folder needs an index.html file. Here are simple examples — customize them however you like.
Site 1 — /var/www/html/index.html
<!DOCTYPE html> <html><head> <title>Site 1</title> </head><body> <h1>Welcome to Site 1!</h1> <p>This is the default site.</p> </body></html>
Site 2 — create with this command:
nano /var/www/sito-alternativo/index.html
<!DOCTYPE html> <html><head> <title>Site 2</title> </head><body> <h1>Welcome to Site 2!</h1> <p>This is the second virtual host.</p> </body></html>
Site 3 — same thing:
nano /var/www/sito-alternativo2/index.html
<!DOCTYPE html> <html><head> <title>Site 3</title> </head><body> <h1>Welcome to Site 3!</h1> <p>This is the third virtual host.</p> </body></html>
In nano: type your content, press Ctrl+O to save, then Ctrl+X to exit.
This is the core of Apache shared hosting. Each site gets a .conf file in /etc/apache2/sites-available/. Replace YOURDOMAIN with the actual hostname you registered in Step 2.
Site 1 — edit the existing default:
sudo nano /etc/apache2/sites-available/000-default.conf
<VirtualHost SITE1DOMAIN:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Site 2 — create a new file:
sudo nano /etc/apache2/sites-available/sito2.conf
<VirtualHost SITE2DOMAIN:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/sito-alternativo ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Site 3 — create another new file:
sudo nano /etc/apache2/sites-available/sito3.conf
<VirtualHost SITE3DOMAIN:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/sito-alternativo2 ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
Important: the domain in the <VirtualHost> tag must exactly match the hostname you registered. No http://, no trailing slash, just the bare hostname.
Use a2ensite to enable each config file, then reload Apache:
# Enable all three sites sudo a2ensite 000-default.conf sudo a2ensite sito2.conf sudo a2ensite sito3.conf # Check for syntax errors (optional but good habit) sudo apache2ctl configtest # Apply changes sudo systemctl reload apache2
configtest should say Syntax OK. If it shows an error, re-open the relevant .conf file and check for typos.
What does a2ensite do? It creates a symlink from sites-available/ to sites-enabled/. Apache only reads configs from sites-enabled/.
If your server has UFW (Ubuntu's default firewall) enabled, allow HTTP traffic:
sudo ufw allow 'Apache' sudo ufw status
You should see Apache listed as ALLOW.
Cloud / VPS providers (AWS, DigitalOcean, Hetzner, etc.) also have a firewall/security group in their dashboard. Make sure port 80 (HTTP) is open there too, otherwise the server firewall alone isn't enough.
Open a browser and visit each of your three domain names:
http://SITE1DOMAIN http://SITE2DOMAIN http://SITE3DOMAIN
Each should show a different page. If all three work, you're done! 🎉
Something not working? Checklist:
.conf file exactly matches your registered hostnameping yourdomain.ddns.net)sudo apache2ctl configtest says Syntax OKsudo systemctl status apache2 shows active (running)index.html file exists in each DocumentRoot folderTo see Apache's error logs if something is wrong:sudo tail -f /var/log/apache2/error.log
# Restart Apache after any config change sudo systemctl reload apache2 # Full restart (if reload doesn't work) sudo systemctl restart apache2 # Check Apache status sudo systemctl status apache2 # List all enabled sites ls /etc/apache2/sites-enabled/ # Disable a site sudo a2dissite sito2.conf # See live error log sudo tail -f /var/log/apache2/error.log
You now have a working shared Apache web hosting environment.
Three domains, three virtual hosts, three distinct landing pages — all on one server.