在AWS实例上为多类Web应用配置虚拟主机(vhost)
Hey there, let's break this down step by step to get your three apps running as separate subpaths correctly.
首先:Apache配置文件的位置
The location depends on which Linux distro your EC2 instance is using:
- Amazon Linux 2 / Amazon Linux 2023:
- 主Apache配置目录:
/etc/httpd/ - 虚拟主机文件放在
/etc/httpd/conf.d/下——只需在这里新建一个.conf文件(比如apps.conf),Apache会自动加载它。
- 主Apache配置目录:
- Ubuntu/Debian:
- 主Apache配置目录:
/etc/apache2/ - 虚拟主机文件存储在
/etc/apache2/sites-available/。创建配置文件后,用a2ensite your-config-file.conf启用它,必要时用a2dissite 000-default.conf禁用默认站点。
- 主Apache配置目录:
你的现有配置不可行——原因如下
你分享的VirtualHost配置无法生效,因为ServerName仅用于域名,不能是main.com/api这类带路径的格式。Apache通过ServerName匹配请求到对应的虚拟主机,所以在这里添加路径是没有意义的。同一域名下的不同子路径,我们应该用Alias指令来处理,而不是创建多个VirtualHost。
正确的配置方案
既然你希望三个应用都能在EC2的公网域名下通过子路径访问(比如http://ec2-xx-xx-xxx-xxx.eu-west-2.compute.amazonaws.com/admin),我们可以设置一个单独的VirtualHost,为每个应用配置别名。同时,Django应用的配置方式要和静态的AngularJS应用有所区别。
以下是可用的配置示例:
适用于Amazon Linux(保存为/etc/httpd/conf.d/apps.conf)
<VirtualHost *:80> ServerAdmin info@example.com ServerName ec2-xx-xx-xxx-xxx.eu-west-2.compute.amazonaws.com # 1. AngularJS Admin应用(静态文件) Alias /admin /var/www/html/admin <Directory /var/www/html/admin> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted # 如果你的AngularJS应用使用HTML5模式(美观URL),添加以下规则 RewriteEngine On RewriteBase /admin/ RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /admin/index.html [L] </Directory> # 2. AngularJS API应用(静态文件) Alias /api /var/www/html/api <Directory /var/www/html/api> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted # 如需HTML5模式,添加相同的重写规则 RewriteEngine On RewriteBase /api/ RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /api/index.html [L] </Directory> # 3. Django Main应用(动态后端) # 先配置静态文件访问 Alias /static /var/www/html/main/static <Directory /var/www/html/main/static> Require all granted </Directory> # 通过WSGI路由Django请求 WSGIScriptAlias /main /var/www/html/main/main/wsgi.py process-group=main <Directory /var/www/html/main/main> <Files wsgi.py> Require all granted </Files> </Directory> # 日志配置 ErrorLog ${APACHE_LOG_DIR}/apps-error.log CustomLog ${APACHE_LOG_DIR}/apps-access.log combined </VirtualHost>
适用于Ubuntu(保存为/etc/apache2/sites-available/apps.conf)
上面的配置几乎完全通用,只需先确保WSGI模块已启用:a2enmod wsgi。
修复404错误的后续步骤
你访问/main时出现的404错误,大概率是静态资源未正确加载,或者Django未识别子路径导致的。执行以下步骤:
更新Django的
settings.py:- 设置
ALLOWED_HOSTS = ['ec2-xx-xx-xxx-xxx.eu-west-2.compute.amazonaws.com'](把你的EC2域名添加进去) - 设置
STATIC_ROOT = '/var/www/html/main/static' - 确保
STATIC_URL = '/static/'
- 设置
收集Django的静态文件:
在Django项目目录下运行:python manage.py collectstatic重启Apache服务:
- Amazon Linux:
sudo systemctl restart httpd - Ubuntu:
sudo systemctl restart apache2
- Amazon Linux:
为什么这个配置能生效
Alias指令将每个子路径(/admin、/api、/static)直接映射到服务器上对应的目录。- 针对AngularJS的重写规则,确保深度链接(比如
/admin/dashboard)能正确加载应用,而不是返回404。 WSGIScriptAlias告诉Apache将所有/main开头的请求发送给Django的WSGI处理器,再通过Django的URL配置进行路由。
内容的提问来源于stack exchange,提问作者methuselah

