Report this

What is the reason for this report?

How To Set Up Apache Virtual Hosts on Ubuntu Server

Updated on January 29, 2026

Not using Ubuntu 20.04?
Choose a different version or distribution.
Ubuntu 20.04
How To Set Up Apache Virtual Hosts on Ubuntu Server

Introduction

The Apache HTTP server is a popular open-source web server that offers flexibility, power, and widespread support for developers. Apache server configuration does not take place in a single monolithic file, but instead happens through a modular design where new files can be added and modified as needed. Within this modular design, you can create an individual site or domain called a virtual host.

Using virtual hosts, one Apache instance can serve multiple websites. Each domain or individual site that is configured using Apache will direct the visitor to a specific directory holding that site’s information. This is done without indicating to the visitor that the same server is also responsible for other sites. This scheme is expandable without any software limit as long as your server can handle the load.

In this guide, you will set up Apache virtual hosts on an Ubuntu server. During this process, you’ll learn how to serve different content to different visitors depending on which domains they are requesting by creating two virtual host sites.

Validated on recent Ubuntu releases: The steps and commands in this tutorial have been verified on Ubuntu 20.04 LTS, 22.04 LTS, and 24.04 LTS. Apache’s configuration layout (sites-available, sites-enabled, a2ensite, a2dissite) and the directory structure used here are the same across these versions.

Key takeaways

  • Virtual hosts let one Apache instance serve multiple sites; each domain points to its own document root.
  • You create a directory under /var/www per site (for example, /var/www/your_domain/public_html) and set ownership and permissions so the web server can read files and your user can edit them.
  • Each site gets its own config file in /etc/apache2/sites-available/ with ServerName, ServerAlias, and DocumentRoot.
  • Use a2ensite and a2dissite to enable or disable sites, then reload or restart Apache so changes apply.
  • You can test without real DNS by editing your local hosts file to point your example domains at the server IP.

Prerequisites

Before you begin this tutorial, you will need:

If you are using DigitalOcean, you can learn how to set up domains by following our product documentation, How to add and set up domains.

In order to successfully complete this tutorial, you will need two domains with:

  • An A record with your_domain pointing to your server’s public IP address.
  • An A record with www.your_domain pointing to your server’s public IP address.

For other providers, please refer to their relevant product documentation.

Note: If you do not have domains available at this time, you can use test values locally on your computer. Step 6 of this tutorial will show you how to test and configure your test values. This will allow you to validate your configuration even though your content won’t be available to other visitors through the domain name.

Step 1 — Creating the Directory Structure

The first step is to create a directory structure that will hold the site data that you will be serving to visitors.

Your document root, the top-level directory that Apache looks at to find content to serve, will be set to individual directories under the /var/www directory. You will create a directory here for each of the virtual hosts.

Within each of these directories, you will create a public_html directory. The public_html directory contains the content that will be served to your visitors. The parent directories, named here as your_domain_1 and your_domain_2, will hold the scripts and application code to support the web content.

Use these commands, with your own domain names, to create your directories:

  1. sudo mkdir -p /var/www/your_domain_1/public_html
  2. sudo mkdir -p /var/www/your_domain_2/public_html

Be sure to replace your_domain_1 and your_domain_2 with your own respective domains. For example, if one of your domains was example.com you would create this directory structure: /var/www/example.com/public_html.

Step 2 — Granting Permissions

You’ve created the directory structure for your files, but they are owned by the root user. If you want your regular user to be able to modify files in these web directories, you can change the ownership with these commands:

  1. sudo chown -R $USER:$USER /var/www/your_domain_1/public_html
  2. sudo chown -R $USER:$USER /var/www/your_domain_2/public_html

The $USER variable will take the value of the user you are currently logged in as when you press ENTER. By doing this, the regular user now owns the public_html subdirectories where you will be storing your content.

You should also modify your permissions to ensure that read access is permitted to the general web directory and all of the files and folders it contains so that the pages can be served correctly:

  1. sudo chmod -R 755 /var/www

Your web server now has the permissions it needs to serve content, and your user should be able to create content within the necessary folders. The next step is to create content for your virtual host sites.

Step 3 — Creating Default Pages for Each Virtual Host

With your directory structure in place, you can start focusing on each individual virtual host site and the content within that site. Start by creating an index.html page for your first site your_domain_1.

Open and create the index.html file with your preferred text editor. This example uses nano:

  1. nano /var/www/your_domain_1/public_html/index.html

Within this file, create an HTML file that indicates to visitors which site they are connected to:

/var/www/your_domain_1/public_html/index.html
<html>
  <head>
    <title>Welcome to your_domain_1!</title>
  </head>
  <body>
    <h1>Success! The your_domain_1 virtual host is working!</h1>
  </body>
</html>

To save and close the file in nano, start by pressing CTRL+X. Press Y when prompted to save the file, then press ENTER when you are finished to exit.

Next, copy this file to use as the base for your second site by typing:

  1. cp /var/www/your_domain_1/public_html/index.html /var/www/your_domain_2/public_html/index.html

Then open this new file and modify the relevant pieces of information using your text editor like before:

  1. nano /var/www/your_domain_2/public_html/index.html
/var/www/your_domain_2/public_html/index.html
<html>
  <head>
    <title>Welcome to your_domain_2!</title>
  </head>
  <body> <h1>Success! The your_domain_2 virtual host is working!</h1>
  </body>
</html>

Save and close this file. You now have one page for each site that you can use to test the virtual host configuration.

Step 4 — Creating New Virtual Host Files

Virtual host files specify the actual configuration of your virtual hosts and control how the Apache web server responds to different domain requests. For more on Apache’s layout and global options, see How To Configure the Apache Web Server on an Ubuntu or Debian VPS.

Apache comes with a default virtual host file called 000-default.conf. You can copy this file to create virtual host files for each of your domains.

Copy the default configuration file over to the first domain:

  1. sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/your_domain_1.conf

Be aware that the default Ubuntu configuration requires that each virtual host file end in .conf.

Open the new file in your preferred text editor with root privileges:

  1. sudo nano /etc/apache2/sites-available/your_domain_1.conf

With comments removed, the file will be similar to this:

/etc/apache2/sites-available/your_domain_1.conf
<VirtualHost *:80>
  ...
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
   ...
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Within this file, customize the items for your first domain and add some additional directives. This virtual host section matches any requests that are made on port 80, the default HTTP port.

First, change the ServerAdmin directive to an email that the site administrator can receive emails through:

/etc/apache2/sites-available/your_domain_1.conf
ServerAdmin admin@your_domain_1

After this, add two additional directives. The first, called ServerName, establishes the base domain for the virtual host definition. The second, called ServerAlias, defines further names that should match as if they were the base name. This is useful for matching additional hosts you defined. For instance, if you set the ServerName directive to example.com you could define a ServerAlias to www.example.com, and both will point to this server’s IP address.

Add these two directives to your configuration file after the ServerAdmin line:

/etc/apache2/sites-available/your_domain_1.conf
<VirtualHost *:80>
  ...
    ServerAdmin admin@your_domain_1
    ServerName your_domain_1
    ServerAlias www.your_domain_1
    DocumentRoot /var/www/html
    ...
</VirtualHost>

Next, change your virtual host file location for the document root for this domain. Edit the DocumentRoot directive to point to the directory you created for this host:

/etc/apache2/sites-available/your_domain_1.conf
DocumentRoot /var/www/your_domain_1/public_html

Here is an example of the virtual host file with all of the adjustments made above:

/etc/apache2/sites-available/your_domain_1.conf
<VirtualHost *:80>
  ...
    ServerAdmin admin@your_domain_1
    ServerName your_domain_1
    ServerAlias www.your_domain_1
    DocumentRoot /var/www/your_domain_1/public_html
    ...
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    ...
</VirtualHost>

Save and close the file.

Create your second configuration file by copying over the file from your first virtual host site:

  1. sudo cp /etc/apache2/sites-available/your_domain_1.conf /etc/apache2/sites-available/your_domain_2.conf

Open the new file in your preferred editor:

  1. sudo nano /etc/apache2/sites-available/your_domain_2.conf

You now need to modify all of the pieces of information to reference your second domain. When you are finished, it should look like this:

/etc/apache2/sites-available/your_domain_2.conf
<VirtualHost *:80>
  ...
    ServerAdmin admin@your_domain_2
    ServerName your_domain_2
    ServerAlias www.your_domain_2
    DocumentRoot /var/www/your_domain_2/public_html
    ...
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    ...
</VirtualHost>

Save and close the file when you are finished.

Step 5 — Enabling the New Virtual Host Files

Now that you have created your virtual host files, you must enable them. Apache includes some tools that allow you to do this.

You’ll be using the a2ensite tool to enable each of your sites. If you would like to read more about this script, you can refer to the a2ensite man page.

Use the following commands to enable your virtual host sites:

  1. sudo a2ensite your_domain_1.conf
  2. sudo a2ensite your_domain_2.conf

There will be output for both sites, similar to the example below, reminding you to reload your Apache server:

Output
Enabling site example.com. To activate the new configuration, you need to run: systemctl reload apache2

Before reloading your server, disable the default site defined in 000-default.conf by using the a2dissite command:

  1. sudo a2dissite 000-default.conf
Output
Site 000-default disabled. To activate the new configuration, you need to run: systemctl reload apache2

Next, test for configuration errors:

  1. sudo apache2ctl configtest

You should receive the following output:

Output
. . . Syntax OK

When you are finished, restart Apache to make these changes take effect.

  1. sudo systemctl restart apache2

Optionally, you can check the status of the server after all these changes with this command:

  1. sudo systemctl status apache2

Your server should now be set up to serve two websites. If you’re using real domain names, you can skip Step 6 and move on to Step 7. If you’re testing your configuration locally, follow Step 6 to learn how to test your setup using your local computer.

Step 6 — (Optional) Setting Up Local Hosts File

If you haven’t been using actual domain names that you own to test this procedure, and have been using example domains instead, you can still test the functionality of your virtual host sites by temporarily modifying the hosts file on your local computer. This will intercept any requests for the domains that you configured and point them to your Virtual Private Server (VPS), just as the DNS system would do if you were using registered domains. This will only work from your local computer and is only for testing purposes.

Make sure you are operating on your local computer for these steps and not your VPS server. You will need to know the computer’s administrative password or otherwise be a member of the administrative group.

If you are on a Mac or Linux computer, edit your local file with administrative privileges by typing:

  1. sudo nano /etc/hosts

If you are on a Windows machine, open the Command Prompt and type:

  1. notepad %windir%\system32\drivers\etc\hosts

The details that you need to add are the public IP address of your server, followed by the domain you want to use to reach that server. Using the domains used in this guide, and replacing your server IP for the your_server_IP text, your file should look like this:

/etc/hosts
127.0.0.1   localhost
127.0.1.1   guest-desktop
your_server_IP your_domain_1
your_server_IP your_domain_2

This will direct any requests for your two domains on your computer and send them to your server at the designated IP address.

Save and close the file.

Step 7 — Testing Your Results

Now that you have your virtual hosts configured, you can test your setup by going to the domains that you configured in your web browser:

http://your_domain_1

An example of the virtual host web page with edited content

You can also visit your second host page and view the file you created for your second site:

http://your_domain_2

An example of a different virtual host web page with edited content

If both of these sites work as expected, you’ve successfully configured two virtual hosts on the same server.

Note: If you adjusted your local computer’s hosts file, like in Step 6 of this tutorial, you may want to delete the lines you added now that you verified that your configuration works. This will prevent your hosts file from being filled with entries that are no longer necessary.

Frequently Asked Questions

1. What are Apache Virtual Hosts?

Apache Virtual Hosts are a way to run more than one website on a single Apache server. Each virtual host has its own domain (or subdomain), document root, and settings. Visitors see only the site for the domain they request; they do not see that other sites are on the same server.

2. How many virtual hosts can Apache handle?

Apache does not limit the number of virtual hosts. You can add as many as your server has resources for. Each new site needs its own config file in /etc/apache2/sites-available/, its own directory under /var/www, and then you enable it with a2ensite and reload Apache.

3. What is the difference between ServerName and ServerAlias?

The ServerName and ServerAlias directives specify which hostnames Apache should respond to for each virtual host, but they serve slightly different purposes:

Directive Description Example
ServerName The main, canonical hostname for the virtual host. Apache matches this name exactly. example.com
ServerAlias Alternate hostnames that also point to this virtual host, including wildcards. www.example.com, *.example.com

How does it work?

  • Use ServerName for the main domain.
  • Use ServerAlias for other hostnames (like www. versions or subdomains) that should display the same site content.

Any request that matches the ServerName or any of the ServerAlias entries is served by that virtual host. For more information, see the official Apache documentation on virtual hosts.

4. Do I need a domain name for virtual hosts?

You do not need a registered domain to follow this guide. You can use example hostnames and point them at your server by editing the hosts file on your computer (see Step 6). For a site that others will reach over the internet, you need a real domain and DNS records that point it to your server. If you use DigitalOcean, you can add and manage domains in the control panel; see our DNS quickstart for how to add a domain.

5. Where are Apache virtual host files stored?

On Ubuntu and Debian, virtual host configs live in /etc/apache2/sites-available/. Each site has a .conf file there (for example, example.com.conf). Enabling a site with a2ensite adds a symlink in /etc/apache2/sites-enabled/ that points to that file. The default site that answers when no other host matches is 000-default.conf.

Conclusion

You now have a single server handling two separate domain names. You can expand this process by following the steps we outlined above to add additional virtual hosts. There is no software limit on the number of domain names Apache can handle, so feel free to make as many virtual hosts as your server is capable of handling.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Kong Yang
Kong Yang
Author
See author profile

Associate Technical Writer @ DigitalOcean

Anish Singh Walia
Anish Singh Walia
Author
Sr Technical Writer
See author profile

I help Businesses scale with AI x SEO x (authentic) Content that revives traffic and keeps leads flowing | 3,000,000+ Average monthly readers on Medium | Sr Technical Writer @ DigitalOcean | Ex-Cloud Consultant @ AMEX | Ex-Site Reliability Engineer(DevOps)@Nutanix

Category:

Still looking for an answer?

Was this helpful?


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

So I’ve followed this command by command, for the past 2 weeks with no luck. So visiting your_domain_2 will redirect me to your_domain_1. I’ve made the two seperate folders, I’ve created and enabled the virtual hosts pointing to the correct directories, I’ve dissabled 000-default etc.

Good article, but I have two questions.

  1. On the remote server setup with apache2, should the website directory ownership (/var/www/vhost1/public_html) be modified instead to the apache server (www-data:www-data) and not the current logged in user?

  2. I followed the article and created the entries for vhost1 and vhost2, each associated with individual and seperate directories as outlined in the article. However, without explanation, the URL for vhost2 points to vhost1. Do you have insight what might be causing the issue?

The domains for vhost1 and vhost2 point to the same IP hosting the server running apache2.

The solution to the issue where two VHosts are individually defined but are served by the same Vhost, maybe related to whether an “ssl certificate” has been setup for apache2. In this situation all Vhosts must have “ssl certificates” to have apache serve each vhost individually. The server defaults to the 443 port and the vhost without “ssl” will be served from the vhost with “ssl.”

If you’re running into an issue with your second website redirecting to your first website, just re-setup Let’s Encrypt with the following:

sudo certbot --apache 

Once you install SSL for each domain then it will no long redirect.

Creative CommonsThis work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 4.0 International License.
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.