如何在 nginx 中设置海量动态虚拟主机?

Posted

技术标签:

【中文标题】如何在 nginx 中设置海量动态虚拟主机?【英文标题】:How to setup mass dynamic virtual hosts in nginx? 【发布时间】:2012-01-02 05:01:26 【问题描述】:

nginx 玩了大约一个小时,试图设置大量动态虚拟主机。 如果你曾经在 apache 中做过,你就会明白我的意思。

目标是为办公室中的少数人(超过 50 人)提供动态子域

【问题讨论】:

“动态子域”是什么意思?您在寻找多“动态”?重启服务器可以接受吗? 【参考方案1】:

也许这样做会让你到达你想去的地方:

server 

    root /sites/$http_host;

    server_name $http_host;

    ...


我喜欢这样,因为我可以即时创建站点,只需创建以域命名的新目录并将 DNS 指向服务器 ip。

【讨论】:

我无法告诉你我找了多久...谢谢! 好东西!我可以使用通配符子域来做到这一点,让 www.domain.com 和 domain.com 都指向 /sites/domain.com/?我有一个用于 apache 的 httpd.conf 可以执行此操作,但不知道如何使用 nginx 复制配置。 @Juhani 我是 nginx 新手,但要指向 www.domain.com 重定向到 domain.com 可能会使用一些类似的规则,例如重写:nginx.org/en/docs/http/converting_rewrite_rules.html 可能与 www.$http_host?并将其重定向到$http_host? 我建议您为www 创建一个符号链接。 @Juhani 我建议 server_name _default_ 而不是使用 $http_host,根据 Freenode 上 #nginx IRC 房间的讨论。这样您就可以捕获默认虚拟主机,并且不会干扰其他重定向规则【参考方案2】:

您需要一些脚本知识才能将它们组合在一起。我会使用 php,但如果你擅长 bash 脚本,请使用它。我会这样做:

    首先创建一些文件夹(/usr/local/etc/nginx/domain.com/)。

    在主 nginx.conf 添加命令:include /usr/local/etc/nginx/domain.com/*.conf;

    此文件夹中的每个文件都应该是不同的虚拟主机名 subdomain.conf。

配置生效不需要重启nginx服务器,只需要重新加载即可:/usr/local/etc/rc.d/nginx reload

或者您只能制作一个配置文件,所有虚拟主机都应在其中设置。这样可能更好,这样 nginx 就不需要加载 50 个文件,而只需要加载一个....

如果您在编写脚本时遇到问题,请提出相关问题...

【讨论】:

有点像,但不是同时。我运行批处理脚本并创建了 50 多个子域 user##.domain.com 现在许多用户想要创建自定义子域 test.user##.domain.com 并且可能一个用于发布,一个用于共享。手动控制这个很痛苦。应该提到每个用户的子域都有自己的目录 /webroot/domain.com/userXX/user01/ 我有 www 作为主目录。 简而言之:我可以为每个用户管理子域,但不能也不想管理他们的子域 就像 Cees 说的,你可以用脚本做任何事情。你甚至可以将 nginx reload 放到 cronjob 中,这样用户就无法控制 nginx reload... 这是公认的答案吗?这不是动态虚拟主机,因为这不需要对配置进行任何更改。【参考方案3】:

根据 user2001260 的回答,后来由 partlov 编辑,这是我的结果。

请记住,这是针对位于本地虚拟机上的开发服务器,其中 .dev 前缀用于每个域的末尾。如果您想删除它或使用其他东西,可以编辑或完全删除 server_name 指令中的 \.dev 部分。

server 
    listen 80 default_server;
    listen [::]:80 default_server;

    # Match any server name with the format [subdomain.[.subdomain...]].domain.tld.dev
    server_name ~^(?<subdomain>([\w-]+\.)*)?(?<domain>[\w-]+\.[\w-]+)\.dev$;

    # Map by default to (projects_root_path)/(domain.tld)/www;
    set $rootdir "/var/www/$domain/www";

    # Check if a (projects_root_path)/(subdomain.)(domain.tld)/www directory exists
    if (-f "/var/www/$subdomain.$domain/www")
        # in which case, set that directory as the root
        set $rootdir "/var/www/$subdomain.$domain/www";
     

    root $rootdir;

    index index.php index.html index.htm index.nginx-debian.html;

    # Front-controller pattern as recommended by the nginx docs
    location / 
        try_files $uri $uri/ /index.php;
    

    # Standard php-fpm based on the default config below this point
    location ~ \.php$ 
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    

    location ~ /\.ht 
        deny all;
    

server_name 中的正则表达式捕获变量 subdomaindomainsubdomain 部分是可选的,可以为空。我已将其设置为默认情况下,如果您有一个子域,例如admin.mysite.com,则将根设置为与mysite.com 相同的根。这样,同一个前端控制器(在我的情况下为index.php)可以基于子域进行路由。但是,如果您想在子域中保留一个完全不同的应用程序,您可以拥有一个 admin.mysite.com 目录,它将使用该目录来调用 admin.mysite.com

小心:在当前的 nginx 版本中不鼓励使用if,因为它会为每个请求增加额外的处理开销,但在开发环境中使用应该没问题,即这个配置有什么用。在生产环境中,我建议不要使用大量虚拟主机配置并单独配置每个站点,以获得更多控制和更好的安全性。

【讨论】:

【参考方案4】:
server_name ~^(?<vhost>[^.]*)\.domain\.com$;
set $rootdir "/var/www/whatever/$vhost";
root $rootdir;

【讨论】:

【参考方案5】:

正如@Samuurai 建议的那样,这是一个带有 nginx 构建集成的短版本 Angular 5:

server 
    server_name ~^(?<branch>.*)\.staging\.yourdomain\.com$;
    access_log /var/log/nginx/branch-access.log;
    error_log /var/log/nginx/branch-error.log;
    index index.html;
    try_files $uri$args $uri$args/ $uri $uri/ /index.html =404;
    root /usr/share/nginx/html/www/theft/$branch/dist;

【讨论】:

【参考方案6】:

另一种选择是包含几个级别的深度,以便可以根据您认为合适的方式对目录进行分类。例如:

include sites-enabled/*.conf;
include sites-enabled/*/*.conf;
include sites-enabled/*/*/*.conf;
include sites-enabled/*/*/*/*.conf;

【讨论】:

【参考方案7】:

只要你熟悉脚本,编写一些脚本可以快速在 nginx 中设置虚拟主机并不难。 This slicehost 文章通过设置几个虚拟主机并以易于编写脚本并保持配置分开的方式进行。唯一的缺点是必须重新启动服务器,但这在配置更改时是可以预料的。


更新:如果您不想自己维护任何配置,那么您唯一的两个选择(无论如何都是安全的)将是找到一个程序,让您的用户管理他们自己的 nginx 块config(这将让他们创建他们想要的所有子域),或者自己创建这样一个面向用户的管理控制台。

自己做这件事不会太难,特别是如果您已经有了脚本来完成设置工作。基于 Web 的界面可以调用脚本来完成实际工作,因此 Web 界面所要做的就是管理谁可以访问什么东西。

【讨论】:

请参考其他答案的评论

以上是关于如何在 nginx 中设置海量动态虚拟主机?的主要内容,如果未能解决你的问题,请参考以下文章

虚拟机中设置 CentOS 静态 IP

如何在xampp中设置虚拟主机?

如何在一个文件中设置多个虚拟主机

如何在 xampp 中设置具有相同父服务器别名或名称的虚拟主机

如何在虚拟 conda 环境中设置 streamlit 的路径

如何在idea中设置Tomcat虚拟路径