When configuring multiple websites on a single CentOS 7.1 server running Apache, I encountered an unexpected behavior with port-based virtual hosting. While the first site works perfectly on port 80, the second site on port 8080 keeps redirecting to the first site when accessed via domain name, though IP:8080 works correctly.
The current httpd.conf contains these key elements:
Listen 80
Listen 8080
<VirtualHost 62.210.xx.xx:80>
ServerName first-site.com
ServerAlias www.first-site.com
DocumentRoot /var/www/first-site
</VirtualHost>
<VirtualHost 62.210.xx.xx:8080>
ServerName second-site.com
ServerAlias www.second-site.com
DocumentRoot /var/www/second-site
</VirtualHost>
Running apachectl -S
reveals important insights:
62.210.xx.xx:8080 m.second-site.com (/etc/httpd/conf/httpd.conf:427)
62.210.xx.xx:80 is a NameVirtualHost
default server first-site.com (/etc/httpd/conf/httpd.conf:363)
port 80 namevhost second-site.com (/etc/httpd/conf/httpd.conf:401)
This shows that second-site.com is incorrectly being listed under port 80 name-based virtual hosts.
The fundamental issue lies in how Apache processes VirtualHost directives. When using port-based virtual hosting, you need to ensure:
- Each VirtualHost block explicitly declares its port
- The ServerName/ServerAlias directives are properly isolated per port
- No overlapping configurations exist between ports
Here's the proper way to configure port-based virtual hosting:
Listen 80
Listen 8080
# Default virtual host (optional)
<VirtualHost _default_:80>
DocumentRoot /var/www/html
</VirtualHost>
# First site - Port 80
<VirtualHost *:80>
ServerName first-site.com
ServerAlias www.first-site.com
DocumentRoot /var/www/first-site
# Additional directives
ErrorLog /var/log/httpd/first-site_error.log
CustomLog /var/log/httpd/first-site_access.log combined
</VirtualHost>
# Second site - Port 8080
<VirtualHost *:8080>
ServerName second-site.com
ServerAlias www.second-site.com
DocumentRoot /var/www/second-site
# Additional directives
ErrorLog /var/log/httpd/second-site_error.log
CustomLog /var/log/httpd/second-site_access.log combined
</VirtualHost>
- Use
*:port
instead of specific IP addresses unless absolutely necessary - Ensure all relevant ports are declared in Listen directives
- Maintain separate log files for each virtual host
- Remove all NameVirtualHost directives (deprecated in Apache 2.4)
After making configuration changes:
- Run
apachectl configtest
to check syntax - Restart Apache:
systemctl restart httpd
- Verify with
curl -I http://second-site.com:8080
- Check access/error logs for each site
If issues persist:
1. Check SELinux status: sestatus
2. Verify firewall rules: firewall-cmd --list-ports
3. Test with IP address first: curl http://62.210.xx.xx:8080
4. Examine detailed debug logs: httpd -X
(debug mode)
For production environments with multiple port-based virtual hosts:
- Consider implementing a reverse proxy (Nginx, HAProxy)
- Evaluate if port-based hosting is truly necessary vs. name-based
- Monitor connection limits and resource usage per port
When configuring multiple websites on a CentOS 7.1 server, I encountered a puzzling behavior with Apache's VirtualHost directives. While accessing http://62.210.xx.xx:8080/
correctly served the second site, domain-based access on port 8080 kept redirecting to the first site.
Here's the relevant httpd.conf excerpt:
Listen 80
Listen 8080
# First site configuration
ServerName first-site.com
ServerAlias www.first-site.com
DocumentRoot /var/www/first-site
# Second site configuration
ServerName second-site.com
ServerAlias www.second-site.com
DocumentRoot /var/www/second-site
Several important findings from debug commands:
netstat -tulpn | grep httpd
tcp6 0 0 :::80 :::* LISTEN 25253/httpd
tcp6 0 0 :::8080 :::* LISTEN 25253/httpd
The output of apachectl -S
revealed that while port 8080 was properly assigned to m.second-site.com, all other domains were somehow bound to port 80 name-based virtual hosts.
The issue stems from how Apache processes VirtualHost directives when both IP+port and name-based virtual hosts are mixed. The critical mistake was including the IP address in the VirtualHost directive while also using ServerName.
Here's the corrected configuration:
Listen 80
Listen 8080
# Default catch-all (should point to empty directory)
DocumentRoot /var/www/default
# First site - port 80
ServerName first-site.com
ServerAlias www.first-site.com
DocumentRoot /var/www/first-site
# Second site - port 8080
ServerName second-site.com
ServerAlias www.second-site.com
DocumentRoot /var/www/second-site
# Additional recommendation for subdomains
ServerName image.first-site.com
DocumentRoot /var/www/first-site/images
# Important global setting
ServerName main-server.com
After making these changes:
- Run
apachectl configtest
to check syntax - Restart Apache:
systemctl restart httpd
- Verify with
curl -v http://second-site.com:8080
- Check all name resolutions in /etc/hosts
For production environments:
- Consider using separate IP addresses for critical sites
- Implement proper firewalling for non-standard ports
- Set up SELinux contexts correctly for non-default document roots
- Configure proper DNS records instead of relying on /etc/hosts
If issues persist:
# Check active configuration
httpd -S
# Verify port listening
ss -tulnp | grep httpd
# Examine request processing
tail -f /var/log/httpd/access_log
tail -f /var/log/httpd/error_log