【问题标题】:nginx with multiple symfony2 apps带有多个 symfony2 应用程序的 nginx
【发布时间】:2015-02-22 14:23:10
【问题描述】:

我看到很多人在配置一个 nginx 服务器以拥有多个 symfony2 应用程序时遇到问题。然而,没有人想要和我一样的东西,也有同样的问题。 我想要做的是在同一个域上有多个应用程序。一个主应用程序将直接响应域,而其他应用程序将位于别名子目录中。 使用架构:

http://mydomain/         -> main app
http://mydomain/subdir1  -> another app
http://mydomain/subdir2  -> yet another app

我自己尝试这样做,并且主应用程序运行良好。但是子目录大部分时间都被主应用拦截,抛出404。当我尝试在子目录的URL中添加app.php(如http://mydomain/subdir1/app.php/my/route)时,服务器返回404。

这是我到现在为止所做的:

server {
    listen   80;
    server_name mydomain;
    root /server/www/main-app/web;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /app.php$is_args$args;
        # PROD
        location ~ ^/app\.php(/|$) {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;

            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param HTTPS off;
        }
    }

    location /subdir1/ {
        alias /server/www/other-app1/web;
        # try to serve file directly, fallback to app.php
        try_files $uri /server/www/other-app1/web/app.php$is_args$args;
        # PROD
        location ~ ^/other-app1/app\.php(/|$) {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;

            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param HTTPS off;
        }
    }
}

感谢您的帮助!

2014 年 12 月 26 日编辑: 对于那些不完全了解我想要什么的人:我想在同一个域名上托管多个 symfony2 应用程序,而无需子域。没有子域,我必须使用子目录。在此之前我尝试过 nginx,我使用的是 Apache2,使用 Alias 很容易做到这一点。

我进行了更多搜索,发现“alias”和“try_files”不是好朋友(请参阅此错误报告:http://trac.nginx.org/nginx/ticket/97)。所以我激活了调试模式并做了很多测试。 现在我几乎做到了。主要应用程序不再拦截子目录,其他应用程序回答。 但是那些其他应用程序的回答是 404,所以我查看了他们的日志。我发现他们在寻找带有子目录的 URL 模式。例如,他们搜索 /subdir1/login 而不是 /login。 所以这是我的新配置:

server {
    listen   80;
    server_name mydomain;
    root /server/www/main-app/web;

    location @rewriteapp {
        rewrite ^(.*)$ /app.php/$1 last;
    }

    location /subdir1/ {
        set $root "/server/www/other-app1/web";
        # try to serve file directly, fallback to app.php
        try_files $uri @rewriteapp;
    }

    location / {
        index app.php;
        set $root "/server/www/main-app/web";
        # try to serve file directly, fallback to app.php
        try_files $uri @rewriteapp;
    }

    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

如您所见,诀窍是不要将 $document_root 用于 SCRIPT_FILENAME,而是我创建了自己的。我不知道 symfony2 路由器如何搜索 URL 中的模式,但是使用我以前的配置(Apache2)我从来没有遇到过这个问题。因此,也许他们是向脚本 app.php 发送正确路径的另一个技巧。

再次感谢您的帮助!

【问题讨论】:

    标签: symfony nginx configuration url-rewriting url-routing


    【解决方案1】:

    经过几个小时的调试,我终于解决了这个问题。这是我的最终配置:

    server {
        listen   80;
        server_name mydomain;
        root /server/www; 
    
        location @rewriteMainApp {
            rewrite ^(.*)$ /app.php/$1 last;
        }
    
        location @rewriteOtherApp1 {
            rewrite ^(.*)$ /subdir1/app.php/$1 last;
        }
    
        location /subdir1 {
            alias /server/www/other-app1/web;
            index app.php;
            set $subfolder "other-app1/web";
            try_files $uri @rewriteOtherApp1;
        }
    
        location / {
            root /server/www/main-app/web;
            index app.php;
            set $subfolder "main-app/web";
            try_files $uri @rewriteMainApp;
        }
    
        # PROD
        location ~ /app\.php(/|$) {
            fastcgi_pass unix:/var/run/php5-fpm.sock;
    
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root/$subfolder/app.php;
        }
    }
    

    感谢大家的帮助!

    【讨论】:

    • 感谢您的帮助,我找到了类似的解决方案。我尝试了一百万件事,但这是有效的(见单独的答案)
    【解决方案2】:

    在我尝试了数百万件事之后,这终于为我解决了(感谢 Claros 的回答)。像这样,像下面这样工作的 url:

    /abc/path/to/endpoint

    但不是 /abc/app.php/path/to/endpoint。 Config.php 和 App_dev.php,如果在 web 文件夹中,则以纯文本形式返回。

    我仍然想办法让 /abc 工作(/abc/ 有效,但 /abc 无效)。我得到一个 Symfony 异常,找不到路由 /abc。

    还有一些字体网址(用于引导程序)仍然不正确,但样式、路由等有效。

      location /abc {
        set $subpath /abc;
        set $sfPath /var/www/abc/current/web;
    
        alias      $sfPath;
    
        try_files $uri @rewrite;
    
      } 
    
      location / {
        set $subpath "";
        set $sfPath /var/www/def/current/web;
    
        alias      $sfPath;
    
        try_files $uri @rewrite;
      } 
    
      location @rewrite {
        rewrite ^(.*)$ $subpath/app.php$1 last;
      } 
    
      location ~ /app\.php(/|$) {
        internal;
        include       /etc/nginx/fastcgi_params;
    
        fastcgi_index app.php;
        fastcgi_pass  unix:/var/run/php5-fpm.sock;
        fastcgi_param DOCUMENT_ROOT  $sfPath;
        fastcgi_param SCRIPT_FILENAME $sfPath/app.php;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
      }
    

    如果您还希望 app_dev.php 在演示环境中工作,我发现的最佳方法如下(每次在 location 块中都有 php 块):

    location /xyz {
        set $subpath /xyz;
        set $sfPath /var/www/xyz/current/web;
    
        alias      $sfPath;
    
        try_files $uri @rewrite;
    
        #Change the match for app_dev.php to work
        location ~ /(app|app_dev|config)\.php(/|$) {
          #Drop the internal for App_dev.php to work
          #internal;
          include       /etc/nginx/fastcgi_params;
    
          fastcgi_index app.php;
          fastcgi_pass  unix:/var/run/php5-fpm.sock;
          fastcgi_param DOCUMENT_ROOT  $sfPath;
          fastcgi_param SCRIPT_FILENAME $sfPath/app.php;
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
        } 
    } 
    

    【讨论】:

      【解决方案3】:

      在启用站点的文件中将您的应用程序与另一个服务器标签分开。

      例如:

      #站点 1

      server {
       #Configuration
      }
      
      server {
       #Configuration 2
      }
      
      server {
       #Configuration 3
      }
      

      示例配置:

      server {
          listen 80;
          root /var/www/yourdomain.com/web;
          server_name yourdomain.com www.yourdomain.com;
          add_header X-UA-Compatible "IE=Edge,chrome=1";
      
          location ~* \.(css|js|gif|jpe?g|png)$ {
              expires 1y;
              add_header Pragma public;
              add_header Cache-Control "public, must-revalidate, proxy-revalidate";
          }
      
          location / {
              try_files $uri @rewriteapp;
          }
      
          location @rewriteapp {
              rewrite ^(.*)$ /app_dev.php/$1 last;
          }
      
          location ~ ^/(app|app_dev|config)\.php(/|$) {
              fastcgi_pass unix:/var/run/php5-fpm.sock;
              fastcgi_split_path_info ^(.+\.php)(/.*)$;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param HTTPS off;
          }
      
          error_log /var/log/nginx/yourdomain.com.error.log;
          access_log /var/log/nginx/yourdomain.com.access.log;
      }
      
      server {
          listen 80;
          root /var/www/yourdomain.com/anotherproject/web;
          server_name sub1.yourdomain.com www.sub1.yourdomain.com;
          add_header X-UA-Compatible "IE=Edge,chrome=1";
      
          location ~* \.(css|js|gif|jpe?g|png)$ {
              expires 1y;
              add_header Pragma public;
              add_header Cache-Control "public, must-revalidate, proxy-revalidate";
          }
      
          location / {
              try_files $uri @rewriteapp;
          }
      
          location @rewriteapp {
              rewrite ^(.*)$ /app_dev.php/$1 last;
          }
      
          location ~ ^/(app|app_dev|config)\.php(/|$) {
              fastcgi_pass unix:/var/run/php5-fpm.sock;
              fastcgi_split_path_info ^(.+\.php)(/.*)$;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
              fastcgi_param HTTPS off;
          }
      
          error_log /var/log/nginx/sub1.yourdomain.com.error.log;
          access_log /var/log/nginx/sub1.yourdomain.com.access.log;
      }
      

      【讨论】:

      • 好的,如果我创建多个服务器,我该如何提及不同的子目录?是否可以有多个服务器具有相同的域名和相同的端口?
      • 喜欢子域?是的。我会做一个例子等等。
      • 感谢您的回答,很有趣。但是,我没有使用子域,而是使用别名的子目录。例如 domain.com/subdir1、domain.com/subdir2 等...在此之前我使用的是 apache2,它很容易配置。但是现在使用 nginx 无法弄清楚如何做到这一点。
      • 只需将 suddomain 更改为 domain :)
      • 这是我唯一需要改变的吗?因为我不明白如何告诉 nginx 我们希望应用在子目录中启动。
      猜你喜欢
      • 1970-01-01
      • 2011-10-24
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 2021-03-05
      • 1970-01-01
      相关资源
      最近更新 更多