1

我在 Debian 上使用 nginx。因此,除了主配置文件 /etc/nginx/nginx.conf 之外,还有文件夹 /etc/nginx/sites-available/ 带有 vhost 配置文件和 /etc/nginx/sites-enabled/ 带有指向活动 vhost 的链接。

所以让我先问我的问题。因为解释很长,也许你不需要阅读它......


我希望能够像这样使用几个虚拟主机模板:

server {
    listen   80;
    server_name ~^(?<project>.+)\.(?<area>.+)\.loc$;

    if ($host ~ ^(?<project>.+)\.(?<area>.+)\.loc$) {
        set $folder "$area/$project";
    }
    ...
    access_log /var/log/nginx/$area/$project.access.log;
    error_log /var/log/nginx/error.log;
    ...
    root /var/www/$folder/;
    ...
}

并定义哪个虚拟主机基于哪个模板。此外,有可能“扩展”模板会很棒,这样我就可以向我的虚拟主机添加新设置并重新定义从模板继承的设置。

我怎样才能实现它?


我当前的 vhost 文件结构如下所示:

/etc/nginx/sites-available 包含以下文件:

默认(默认虚拟主机) ax-common-vhost (虚拟主机模板) test.sandbox.loc (基于模板 ax-common-vhost 的虚拟主机;它包括include规则)...还有一些其他的...

/etc/nginx/sites-available 包含以下文件:

默认 -> /etc/nginx/sites-available/default test.sandbox.loc -> /etc/nginx/sites-available/test.sandbox.loc ...还有一些其他的...

模板 ax-common-vhost 使用服务器名称动态定义了一些选项,例如根文件夹:

server {
    listen   80;
    server_name ~^(?<project>.+)\.(?<area>.+)\.loc$;

    if ($host ~ ^(?<project>.+)\.(?<area>.+)\.loc$) {
        set $folder "$area/$project";
    }
    ...
    access_log /var/log/nginx/$area/$project.access.log;
    error_log /var/log/nginx/error.log;
    ...
    root /var/www/$folder/;
    ...
}

所以当我想创建一个新的虚拟主机时,我只需创建一个新的虚拟主机文件和一个指向它的链接——并且不需要复制和粘贴设置并手动设置路径。我只需要遵循约定,主机 %project%.%area%.loc 必须放在 [my webroot]/%area%/%project%

我想,它适用于包含规则:服务器获取请求 xyloc,查找名为 so 的文件,打开文件,最后处理其中的指令(因此包含指令和包含模板的全部内容) .

但事实并非如此。Nginx 似乎只是扫描整个文件夹 /etc/nginx/sites-available/ (按字母顺序?)并保留第一个文件 /server请求中的主机名等于/匹配的指令。

这意味着,包括

include /etc/nginx/sites-available/ax-common-vhost;

未使用。实际上,我已经从 vhost 文件中删除了包含指令——没有任何改变!

这是一个问题。因为当我添加一个新模板时,例如我的 Zend Framework 项目(使用 [project root]/public/ 作为 root):

文件 ax-zf-vhost

server {
    listen   80;
    server_name ~^(?<project>.+)\.(?<area>.+)\.loc$;

    if ($host ~ ^(?<project>.+)\.(?<area>.+)\.loc$) {
        set $folder "$area/$project";
    }
    ...
    access_log /var/log/nginx/$area/$project.access.log;
    error_log /var/log/nginx/error.log;
    ...
    root /var/www/$folder/public/;
    ...
}

...,它被忽略了,因为服务器没有得到任何关于 vhost myzf.sandbox.loc 基于 ax-zf-vhost 的信息。而不是这个,它只是循环 /etc/nginx/sites-available/ 文件夹,找到 ax-common-vhost,myzf.sandbox.loc 匹配模式 ^(?.+).(?.+).loc$,并且 nginx 使用 ax-common-vhost 作为 myzf.sandbox.loc。

如何解决这个问题?

谢谢

4

1 回答 1

1

好的,现在可以使用了!

我已经更改了基本 vhost 文件的 server_name 块,因此它只处理具有指令中列出的主机名的请求:

文件 ax-common-vhost:

server {
    listen   80;
    server_name test.sandbox.loc foo.sandbox.loc bar.sandbox.loc;
    ...
}

而不是通用的server_name ~^(?<project>.+)\.(?<area>.+)\.loc$;.

不需要 /etc/nginx/sites-available/ 中的 vhost 文件 test.sandbox.loc、foo.sandbox.loc、bar.sandbox.loc 等以及 /etc/nginx/sites-enabled/ 中指向它们的链接了。我已经创建了 /etc/nginx/sites-enabled/ax-common-vhost 到 /etc/nginx/sites-available/ax-common-vhost 的链接。

第二个通用 vhost 文件的方法是相同的,并且有效。

第一个问题得到解决:设置可以由多个虚拟主机/服务器块共享,我可以轻松添加新虚拟主机而无需重复设置。

但是:具有设置的 vhost 文件不能被另一个文件扩展。是否可以这样做,以便文件 B 可以“扩展”文件 A、继承其设置并仅覆盖指令/规则?我怎么能意识到这一点?

于 2013-02-07T13:16:45.053 回答