You can host multiple websites on a single public IP address by configuring Apache HTTP Server with Name-Based Virtual Hosts. This technique allows the web server to distinguish between requests for different subdomains based on the hostname provided in the HTTP header, directing traffic to the correct document root and backend application without requiring separate IP addresses.
Understanding Name-Based Virtual Hosting
The core mechanism enabling this setup is called Name-Based Virtual Hosting. When a client connects to your server’s IP address, it sends an HTTP request that includes a
Host header specifying which domain or subdomain it wants to access. Apache reads this header before processing the request and matches it against its configured virtual hosts. If a match is found, Apache serves content from the corresponding directory; if not, it falls back to a default configuration. This method is efficient because it eliminates the need for expensive additional IP addresses while maintaining complete isolation between different sites hosted on the same machine.
Configuring Apache Virtual Hosts
To implement this, you must create distinct configuration files for each subdomain. Start by creating a new file in the
/etc/apache2/sites-available/ directory for each subdomain you wish to host. For example, create
site1.conf for
app.example.com and
site2.conf for
api.example.com. Each file should define a
<VirtualHost> block listening on port 80 (and optionally 443 for HTTPS). Inside this block, specify the
ServerName directive to match the subdomain exactly. Set the
DocumentRoot to point to the specific directory where the website files are stored. Ensure that the permissions for these directories allow the Apache user to read the files. After saving the configuration files, enable them using the
a2ensite command for each new site. This step creates symbolic links in the
sites-enabled directory, making the configurations active for the server.
Resolving Port Conflicts and Service Binding
A common challenge arises when the two webservers are not both standard Apache instances but perhaps one is running a Node.js application, a Python Flask app, or a Docker container. In such cases, you cannot have both services listening directly on port 80 or 443 of the public IP. Instead, configure your primary Apache instance as a reverse proxy. Use the
ProxyPass and
ProxyPassReverse directives within the virtual host block to forward requests to the internal port where the secondary web server is running. For instance, if your Node.js app runs on localhost:3000, you would map
app.example.com to
http://localhost:3000. This approach ensures that Apache handles the incoming HTTPS/TLS termination and routing, while the backend service remains isolated on a non-standard port. You may encounter issues if the backend service is not bound to
127.0.0.1 correctly, so verify your local firewall rules. If you suspect network connectivity issues between the proxy and the backend, consult our guide on
Why I Can't Access My Web Service on Port 80 to troubleshoot binding errors.
DNS and SSL Configuration
Before testing the virtual hosts, ensure your DNS records are correctly configured. Both subdomains must resolve to the same public IP address via A records. Without proper DNS resolution, the browser will never send the correct
Host header to Apache, resulting in 404 errors or the wrong site being displayed. If you plan to use HTTPS, which is mandatory for modern browsers, you need SSL certificates for each subdomain. You can obtain free certificates using Let's Encrypt via Certbot. Run Certbot for each domain separately, or use the
--dry-run flag to test the process. Ensure that the
SSLEngine on directive is present in your virtual host configurations if you are managing certificates manually. Pay attention to certificate name constraints; some older setups might fail if the SAN (Subject Alternative Name) does not include the specific subdomain. If you experience issues with redirect loops during SSL setup, check your
.htaccess rules carefully, as incorrect redirects can cause browsers like Firefox to get stuck. For more details on fixing redirect loops, refer to
Firefox Stuck on .htaccess Redirect? How to Fix It.
Testing and Troubleshooting
After applying all changes, restart Apache to load the new configurations. Use the command
systemctl restart apache2 on Debian-based systems or
service httpd restart on Red Hat-based systems. Before restarting, always run
apache2ctl configtest to validate the syntax of your configuration files. This prevents downtime caused by syntax errors. Once restarted, use tools like
curl -I http://subdomain.example.com to inspect the response headers and confirm that the correct virtual host is serving the request. Check the Apache error logs located in
/var/log/apache2/error.log if you encounter permission denied errors or missing files. Remember that changing ports or listen directives in
httpd.conf can sometimes lead to unexpected behavior if not aligned with your virtual host definitions. If you find that your port changes are not taking effect, review our article on
Changing port in Apache httpd.conf listen not working to understand how Apache prioritizes configuration sources. Properly isolating your subdomains ensures that a crash or security issue in one web server does not compromise the other, providing a robust and scalable hosting environment.
Frequently Asked Questions
Can I host more than two subdomains on the same IP?
Yes, Apache supports any number of virtual hosts on a single IP address as long as they have unique
ServerName directives. There is no hard limit imposed by the protocol itself, though system resources like memory and file descriptors may eventually become a bottleneck for thousands of sites.
What happens if a request does not match any virtual host?
Apache will serve content from the first virtual host defined in its configuration order, often referred to as the default virtual host. To prevent accidental exposure of sensitive data, it is best practice to configure a strict default host that returns a 403 Forbidden error or redirects to a main landing page.
Do I need separate SSL certificates for each subdomain?
While you can obtain individual certificates for each subdomain, it is more efficient to use a Single Certificate with Subject Alternative Names (SAN) or a Wildcard Certificate (*.example.com). This reduces management overhead and simplifies renewal processes for Let's Encrypt users.
How do I debug why my subdomain shows the wrong site?
Use
curl -H "Host: subdomain.example.com" http://127.0.0.1 to simulate a request directly to the server. This bypasses DNS issues and confirms whether Apache is routing the request to the correct document root based on the hostname header alone.
Is it safe to run different web frameworks on the same server?
It is safe provided you isolate the processes correctly using reverse proxies and set appropriate file permissions. Avoid running backend services as the root user and ensure that each framework listens only on localhost interfaces to prevent direct external access bypassing Apache.