Setting up Apache virtual hosts on Ubuntu lets you host multiple websites on a single server, each with its own domain name and document root. This guide walks you through creating a directory structure, configuring virtual host files, enabling them, and testing the result. You’ll need a running Ubuntu server (20.04 or newer) with Apache installed and sudo access.
What You’ll Need
- Ubuntu server (20.04 LTS or later) with a non-root sudo user.
- Apache2 installed (
sudo apt install apache2). - Domain names (or test domains) pointing to your server’s IP, or you can edit your local
/etc/hostsfile for testing.
Step-by-Step
- Create the directory structure. For each site, create a directory under
/var/www/. For example, forexample.comandtest.com:sudo mkdir -p /var/www/example.com/public_html sudo mkdir -p /var/www/test.com/public_html
- Set ownership and permissions. Give your user ownership so you can edit files without sudo, and set the correct permissions:
sudo chown -R $USER:$USER /var/www/example.com/public_html sudo chown -R $USER:$USER /var/www/test.com/public_html sudo chmod -R 755 /var/www
- Create a test page for each site. Add an
index.htmlfile to each directory so you can verify the virtual host works. For example:echo "<h1>Welcome to Example.com!</h1>" | tee /var/www/example.com/public_html/index.html echo "<h1>Welcome to Test.com!</h1>" | tee /var/www/test.com/public_html/index.html
- Copy the default configuration file. Apache uses configuration files in
/etc/apache2/sites-available/. Copy the default file to create a new one for each site:sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/test.com.conf
- Edit the virtual host files. Open the first file with a text editor (e.g., nano):
sudo nano /etc/apache2/sites-available/example.com.conf
Update the
ServerAdminemail, addServerNameandServerAlias, and change theDocumentRootto the new directory. A minimal configuration looks like:<VirtualHost *:80> ServerAdmin admin@example.com ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/public_html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>Save and exit. Repeat for the second site, adjusting the domain and paths.
- Enable the virtual host files. Use
a2ensiteto enable each site:sudo a2ensite example.com.conf sudo a2ensite test.com.conf
- Disable the default site (optional but recommended). To avoid conflicts, disable the default site:
sudo a2dissite 000-default.conf
- Test the configuration. Before restarting Apache, check for syntax errors:
sudo apache2ctl configtest
You should see
Syntax OK. If not, fix the errors before continuing. - Restart Apache. Apply the changes:
sudo systemctl restart apache2
- Test the virtual hosts. If your domains are live, visit them in a browser. If you’re testing locally, edit your
/etc/hostsfile to point the domains to your server’s IP (e.g.,127.0.0.1 example.com), then visithttp://example.comandhttp://test.com. Each should show the corresponding test page.
Common Mistakes
- Forgetting to enable the site. Creating a config file in
sites-availabledoes nothing until you runa2ensite. - Wrong DocumentRoot path. A typo in the path leads to a 404 or a generic Apache page.
- Not using
ServerName. Without it, Apache may route requests to the first virtual host, causing wrong sites to load. - Not disabling the default site. If the default site is still enabled, it can catch requests that don’t match any ServerName.
- Forgetting to restart Apache. Changes only take effect after a reload or restart.
Tips
- Use
sudo systemctl reload apache2instead of restart for minor changes; it’s faster and less disruptive. - Keep each site’s logs separate by setting
ErrorLogandCustomLogto files like${APACHE_LOG_DIR}/example.com-error.log. - For HTTPS, later add a virtual host on port 443 and use Let’s Encrypt with
certbot. - Use
sudo apache2ctl -Sto list all virtual hosts and verify their configuration. - If you have many sites, consider using a wildcard
ServerAliaslike*.example.comfor subdomains.
Troubleshooting
- Site shows default Apache page. This usually means the virtual host isn’t being used. Check that the site is enabled (
a2ensite) and that theServerNamematches the domain you’re visiting. Also ensure the default site is disabled. - 404 Not Found. The DocumentRoot path is wrong or the index file is missing. Check the directory exists and contains the file.
- Permission denied. Apache may not have read access to the document root. Ensure the directory permissions are 755 and files are 644, and that the ownership is correct (usually
www-datafor the group, but your user can own it). - Syntax errors after editing. Run
sudo apache2ctl configtestto see the exact error. Common issues are missing closing tags or typos in paths. - Domain not resolving. If you’re testing locally, edit
/etc/hoststo map the domain to your server IP. For production, check your DNS records. - Port 80 already in use. If another service is using port 80, Apache won’t start. Check with
sudo netstat -tulpn | grep :80and stop the conflicting service or change Apache’s port.
Frequently Asked Questions
Can I use virtual hosts with IP-based instead of name-based hosting?
Yes, but name-based virtual hosts (using ServerName) are the default and more common. IP-based hosting requires each site to have a unique IP address, which is rare on a single server.
How do I set up a virtual host for a subdomain?
Create a new virtual host file with a ServerName like sub.example.com and point its DocumentRoot to a separate directory. Enable it with a2ensite and restart Apache.
What is the difference between sites-available and sites-enabled?
sites-available holds all configuration files, even inactive ones. sites-enabled contains symlinks to the active configurations. The a2ensite and a2dissite commands manage these symlinks.
Can I run multiple sites on different ports?
Yes, you can specify a different port in the <VirtualHost> tag, e.g., <VirtualHost *:8080>. You’ll also need to add a Listen 8080 directive in ports.conf.
How do I redirect all traffic to HTTPS?
After setting up SSL with Let’s Encrypt, you can add a redirect in the port 80 virtual host: Redirect permanent / https://example.com/. Alternatively, use the certbot --apache command to automate this.
Why does my second site show the first site’s content?
This usually happens when the ServerName is missing or incorrect in the second virtual host. Apache then falls back to the first virtual host. Double-check the ServerName and that the site is enabled.
Related
General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.
More in this bed
- Photonic Inference vs GPU Inference: Key Differences16,384.00 µs
- Android Low Storage Survival Tips That Actually Work
- How to Password Protect PDFs on iPhone
- iPhone Force Restart Not Working? Fixes
- Add or Remove Keyboard Layout in Windows 10
- Razer Barracuda V2 Pro Dongle: Store & Find