我拥有多个域,希望它们都由一个主机提供服务。有许多用户在此主机上创建他们的项目,这些项目应全部按子域路由。我想在 Apache 配置中设置一些规则,以自动确定文档根目录,但我不知道该怎么做,或者 Apache 是否允许这种“复杂”的重写规则。
文件夹结构应该是这样:
/var/www
| example.org
| - foo
| - - index.html
| - bar
| - - somehiddenfile.txt
| - - public
| - - - index.html
| - www
| - - index.html
| - error.html
在这个例子中,我希望example.org
和www.example.org
被路由到/var/www/example.org/www
。
foo.example.org
应路由到/var/www/example.org/foo
并且bar.example.org
应路由到/var/www/example.org/bar/public
。如果存在则应foobar.example.org
始终提供服务/var/www/example.org/error.html
,否则/var/www/example.org/www
也路由到。
现在,由于我不想在每次有人创建新的子域时都创建新的配置(它们通常是通过 A 通配符设置的(*.example.org
)),我希望能够尽可能地自动化。
然而,我不知道如何-d
在重写条件中使用子域进行检查。RewriteCond /var/www/${HTTP_HOST} !-d
我可以做类似的事情,但我没有找到任何关于对拆分主机 (TLD) 和子域执行相同操作的信息。如果可以的话,请告诉我。
答案1
由于每个子域都与不同的内容相关,即指向相应的 DocumentRoot,并具有自己的设置(例如自定义 404 文档),因此您可能想要使用“基于名称”的 VirtualHost 指令(而不是自己在请求中匹配主机)。请参阅Apache 文档有关更多信息,请参阅 VirtualHosts。
基本思路是,您有一个站点列表(www. foo. bar...),其中包含单独的参数(名称、别名、DocRoot、ErrorDoc),并且您需要在 apache conf 文件中为每个站点生成一系列 VirtualHost 声明。然后将生成的文件放在或/etc/httpd/conf.d/
(/etc/apache2/sites-enabled
或类似的地方,取决于您的目标操作系统)中
通常对于简单的情况,管理员只需手动编写 Apache 配置即可。但是,如果您要管理的网站不止几个,或者想要定期自动更改它们,那么最简单的方法就是使用模板系统,例如jinja2或者埃鲁比斯,(或者如果您更熟悉,可以使用 bash、python、perl 等来执行,或者甚至使用 Chef 或 Ansible,如果您想走 DevOps 路线!)
我认为您可能仍需要添加重写条件来解决提供正确的 Error.html 的问题,但ServerName
、Alias
和的主要问题DocumentRoot
已经使用模板系统解决了。
如果您有一个通配符域记录并将*.example.org
其指向服务器,则将ServerName
完成ServerAlias
剩下的工作......
基本上,网站结构在 yaml 中是这样的;
---
sites:
- server_name: www.example.org
server_alias: example.org
document_root: "/var/www/example.org/www"
- server_name: foo.example.org
document_root: "/var/www/example.org/foo"
- server_name: bar.example.org
document_root: "/var/www/example.org/bar/public"
- server_name: foobar.example.org
document_root: "/var/www/example.org/foobar"
custom_error: "/error.html"
您可以使用 jinja2 模板将其呈现到 apache 配置文件中。模板看起来类似于以下内容;
{% for site in sites %}
<VirtualHost *:80 >
ServerName {{ site.server_name }}
{% if is defined site.server_alias %}ServerAlias {{ site.server_alias }}{% end if %}
DocumentRoot {{ document_root }}
{% if is defined site.custom_error %}ErrorDocument 404 {{ site.custom_error }}{% endif %}
<Directory {{ document_root }} >
Options FollowSymLinks
AllowOverride FileInfo Options
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
{% endfor %}
它将为 VirtualHosts 生成一个如下所示的配置;
<VirtualHost *:80 >
ServerName www.example.org
ServerAlias example.org
DocumentRoot /var/www/example.org/www
<Directory /var/www/example.org/www>
Options FollowSymLinks
AllowOverride FileInfo Options
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80 >
ServerName foo.example.org
DocumentRoot /var/www/example.org/foo
<Directory /var/www/example.org/foo>
Options FollowSymLinks
AllowOverride FileInfo Options
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80 >
ServerName bar.example.org
DocumentRoot /var/www/example.org/bar/public
<Directory /var/www/example.org/bar>
Options FollowSymLinks
AllowOverride FileInfo Options
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80 >
ServerName foobar.example.org
DocumentRoot /var/www/example.org/foobar
ErrorDocument 404 http://www.example.org/error.html
<Directory /var/www/example.org/bar>
Options FollowSymLinks
AllowOverride FileInfo Options
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
基本上,您可以用 yaml(或 json)表达您的需求,然后使用模板工具将其转换为所需的配置。例如,此工具只需获取 j2 文件和 yaml 文件并将其呈现出来;
https://github.com/kolypto/j2cli
这基本上就是 ansible 和 chef 等工具的设计目的,事实上 ansible 使用 jinja2 模板,而 chef 使用 erubis。然而 chef 和 ansible 都相当复杂,如果你想添加其他内容(例如添加 mysql 数据库或配置 SSL 证书),那么它们会很有用,那么你可能会使用 chef/ansible 而不是直接使用模板...