【问题标题】:Install multiple laravel projects in subfolders without subdomain在没有子域的子文件夹中安装多个 laravel 项目
【发布时间】:2019-01-31 21:00:58
【问题描述】:

我已经尝试搜索这个问题,但它与我的完全不同,所以我在这里发布。我正在尝试使用nginx 创建一个网络服务器,以在子文件夹中托管多个 laravel 项目。这是我的 实验室 服务器。所以我希望我的项目是这样的:

  • domain.com/project1
  • domain.com/project2
  • domain.com/project3

我正在为每个项目复制以下 nginx location 块(我不知道这里发生了什么,我只是从互联网上复制的,它有效):

location ^~ /project1/ {
        alias /home/web/project1/public;
        try_files $uri $uri/ @project1;

    location ~ \.php {
        fastcgi_pass                    unix:/var/run/php5-fpm.sock;
        fastcgi_index                   index.php;
        include                         /etc/nginx/fastcgi_params;
        fastcgi_param                   SCRIPT_FILENAME "/home/web/project1/public/index.php";
    }

}

location @project1 {
     rewrite /avm/(.*)$ /project1/index.php?/$1 last;
}

我的 laravel 应用程序中的 RESTful 路由如下:

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/

Route::get('/', ['middleware' => 'auth','uses' => 'HomeController@index'])->name('home');

// Authentication
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@authenticate');
Route::get('auth/logout', 'Auth\AuthController@getLogout');

// Administração
Route::group(['prefix' => 'administracao', 'middleware' => 'auth'], function() {
    Route::resource('filiais', 'FiliaisController');
    Route::resource('precos', 'PrecosController');
    Route::resource('funcionarios', 'FuncionariosController');
    Route::resource('cargos', 'CargosController');
    Route::resource('vendedores', 'VendedoresController');
});

// Comercial
Route::group(['prefix' => 'comercial', 'middleware' => 'auth'], function() {
    Route::resource('clientes', 'ClientesController');
    Route::resource('fichas', 'FichasController');
});

// Operacional
Route::group(['prefix' => 'operacional', 'middleware' => 'auth'], function() {
    Route::resource('agenda', 'AgendaController');
    Route::resource('os', 'OsController');
    Route::resource('ambientes', 'AmbientesController');
    Route::resource('processos', 'ProcessosController');
    Route::get('relatorios', 'RelatoriosController@index');

    Route::group(['prefix' => 'processo', 'middleware' => 'auth'], function() {
        Route::get('create', 'ProcessoController@create');
        Route::get('index', 'ProcessoController@index');

        Route::post('{os}/parse', 'ProcessoController@parse');

        Route::get('{os}', 'ProcessoController@principal');
        Route::match(['get', 'post'], '{os}/detalhe', 'ProcessoController@detalhe');
        Route::get('{os}/duplicidades', 'ProcessoController@duplicidades');
        Route::get('{os}/restantes', 'ProcessoController@restantes');
        Route::match(['get', 'post'], '{os}/auditoria', 'ProcessoController@auditoria');
        Route::match(['get', 'post'], '{os}/operadores', 'ProcessoController@operadores');
        Route::match(['get', 'post'], '{os}/divergencia', 'ProcessoController@divergencia');
        Route::match(['get', 'post'], '{os}/finalizar', 'ProcessoController@finalizar');
        Route::get('{os}/excluir/{setor}', 'ProcessoController@destroy');
    });
});

虽然它在进入业务逻辑(保存到数据库等)时似乎可以工作(页面出现等),但它似乎有很多错误。例如,当我尝试在 url http://domain.com/project1/administracao/funcionarios 中创建一个新员工时,它给了我错误:SQLSTATE[42S22]: Column not found: 1054 Unknown column '/administracao/funcionarios' in(它有点前置一些 url 路由)

当我设置像project1.domain.com 这样的子域时,一切正常。但我不想为每个项目创建一个子域,我希望它在子文件夹 url 中工作。有可能吗?

【问题讨论】:

  • 在此处查看接受的答案:stackoverflow.com/questions/16683046/…
  • 那是 Laravel 4.. 我已经试过了
  • 你能显示发布到project1/administracao/funcionarios的控制器代码吗?我想你正在使用 Input::all() 或类似的,我有兴趣查看发送到该函数的数据转储

标签: php .htaccess laravel nginx


【解决方案1】:

我已经使用简单的符号链接在另一个站点的“子文件夹”中成功运行了 Laravel 5.4 项目。

Nginx 配置中没有时髦的特殊重写规则。不能复制和粘贴项目的各个部分。没有提到路线中的子文件夹。只是一个常规的 Laravel 5 项目巧妙地包含在服务器上的某个位置,以及从主站点的文档根目录指向它的公共文件夹的符号链接。

/var/www/domain.com/public/project1 --> /var/www/project1/public

所有路线都行得通!

在编写视图时,您必须将客户端资产的路径包装在 asset() 辅助函数中,以便 HTML 中的路径包含子文件夹并且浏览器可以找到它们。

<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">

但是这样做并不会降低您的代码的灵活性,因为如果您确实在不通过子文件夹访问它的环境中运行该站点,它可以工作,因为asset() 与地址栏包含的内容一起工作。

【讨论】:

    【解决方案2】:

    最近我遇到了完全相同的问题。我想拥有

    但我讨厌每次添加新项目时都必须修改 nginx conf。

    这是我想出的:

    # Capture $project from /$projectname/controller/action
    map $request_uri $project {
    
        ~^/(?<captured_project>[a-zA-Z0-9_-]+)/? $captured_project;
        default / ;
    }
    
    server {
    
        listen 11.22.33.44:80;
    
        server_name customerdemo.example.com www.customerdemo.example.com;
    
        # Use $project/public as root
        root /sites/customerdemo.example.com/$project/public;
    
        # Use index.php as directory index
        index index.php;
    
        # Include the basic h5bp config set (see https://github.com/h5bp/server-configs-nginx)
        include h5bp/basic.conf;
    
        # Process /projectname/the/rest/of/the/url
        location ~ ^/([^/]+)/(.*) {
    
            # Save the rest of the URL after project name as $request_url
            set $request_url /$2;
    
    
            # If the saved url refers to a file in public folder (a static file), serve it,
            # else redirect to index.php, passing along any ?var=val URL parameters
            try_files $request_url /index.php?$is_args$args;
    
        }
    
        # Process any URL containing .php (we arrive here through previous location block)
        # If you don't need to serve any other PHP files besides index.php, use location /index.php here
        # instead, to prevent possible execution of user uploaded PHP code
        location ~ [^/]\.php(/|$) {
    
            # Define $fastcgi_script_name and $fastcgi_path_info
            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    
            # Immediately return 404 when script file does not exist
            if (!-f $document_root$fastcgi_script_name) {
                return 404;
            }
    
            # Mitigate https://httpoxy.org/ vulnerabilities
            fastcgi_param HTTP_PROXY "";
    
            # Define PHP backend location (find yours by grepping "listen ="
            # from your PHP config folder, e.g. grep -r "listen =" /etc/php/)
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    
            # Set SCRIPT_FILENAME to execute
            fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    
            # Include the default fastcgi parameters
            include fastcgi_params;
    
            # Overwrite REQUEST_URI (default is $request_uri) with $request_url we saved earlier
            fastcgi_param  REQUEST_URI        $request_url;
        }
    
    }
    

    结果是我不需要在 /sites/customerdemo.example.com/ 文件夹中执行除 git clone 之外的任何操作并运行 composer installphp artisan migrate 来添加新项目。

    实际上,我已经为自己开发了一个控制面板,我可以在其中单击“添加项目”并指定项目详细信息和一个新的 bitbucket 存储库,将创建 mysql 用户和数据库,并为 customerdemo 服务器提供对此 bitbucket 存储库的部署访问权限并且在这个新的 repo 中设置了一个 webhook,每次有人提交到这个 repo 上的 master 时,它将调用 customerdemo 服务器上的部署脚本,这将触发 git clone 或 git pull 以及 composer install 和数据库迁移。这就是我需要动态 Nginx 配置的原因。 ;-)

    【讨论】:

      【解决方案3】:

      检查这个Nginx configuration我相信它会帮助你

      server {
      server_name main-app.dev;
      root /var/www/projects/main/public;
      
      
      add_header X-Frame-Options "SAMEORIGIN";
      add_header X-XSS-Protection "1; mode=block";
      add_header X-Content-Type-Options "nosniff";
      
      index index.html index.htm index.php;
      charset utf-8;
      # sub_directory
      location ^~ /sub-app {
        alias /var/www/projects/sub/public;
        try_files $uri $uri/ @sub;
      
          location ~ \.php {
              fastcgi_split_path_info ^(.+\.php)(/.+)$;
              fastcgi_pass 127.0.0.1:9000;
              fastcgi_index index.php;
              fastcgi_read_timeout 30000;
              include fastcgi_params;
              fastcgi_param SCRIPT_FILENAME /var/www/projects/sub/public/index.php;
          }
          access_log off;
          error_log  /var/www/projects/sub/storage/log/error.log error;
      }
      
      location @sub {
         rewrite /sub/(.*)$ /sub/index.php?/$1 last;
      } # end sub_directory
      
      location / {
          try_files $uri $uri/ /index.php?$query_string;
      }
      
      location = /favicon.ico { access_log off; log_not_found off; }
      location = /robots.txt  { access_log off; log_not_found off; }
      
      access_log off;
      error_log  /var/www/projects/main/storage/log/error.log error;
      
      error_page 404 /index.php;
      
      location ~ \.php$ {
          fastcgi_split_path_info ^(.+\.php)(/.+)$;
          fastcgi_pass 127.0.0.1:9000;
          fastcgi_index index.php;
          fastcgi_read_timeout 30000;
          include fastcgi_params;
          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
          fastcgi_param PATH_INFO $fastcgi_path_info;
      }
      
      location ~ /\.(?!well-known).* {
          deny all;
      }}
      

      【讨论】:

      • 我会更新它,但这是有线的,链接是官方网站“GitHub”,如果 github 死了意味着开发世界也随之死去:)。我相信您应该为著名的网站添加一些例外。无论如何,我会更新我的答案。
      【解决方案4】:

      我认为问题可能出在您的nginx.conf 文件中。试试这个:

      location ^~ /project1 {
              alias /home/web/project1/public;
              try_files $uri $uri/ @project1;
      
          location ~ \.php {
              fastcgi_pass     unix:/var/run/php5-fpm.sock;
              fastcgi_index    index.php;
              include          /etc/nginx/fastcgi_params;
          }
      
      }
      
      location @project1 {
          rewrite /project1/(.*)$ /project1/index.php?/$1 last;
      }
      

      另外,请确保/home/web/project1/ 在您的网络根目录之外。

      话虽如此,确实不建议在子文件夹中运行 Laravel。在子域中容易得多。

      我从this gist得到了这个建议的基本思路。

      【讨论】:

      • 为什么它应该在我的网络根目录之外?
      • 如果你的 web 根目录是 /home/web/ 并且你把整个 laravel 项目放在那里,那么所有的私有 laravel 文件都会对 web 上的每个人可见。他们将能够浏览到yourdomain.com/project1/config 并查看那里的文件。
      【解决方案5】:

      不完全确定解决方案,但我认为您应该尝试以下解决方案:

      • 首先:在config/app.php文件中正确设置url
      • 其次:查看public/web.config 文件。问题可能是这些配置覆盖了你的 nginx。考虑更改&lt;action type="Rewrite" url="project1/index.php" /&gt;,看看它会返回什么。

      最后,var_dump 模型并查找它的来源。

      【讨论】:

        【解决方案6】:

        你试过这个配置吗?

        https://gist.github.com/tsolar/8d45ed05bcff8eb75404

        我将在明天有时间在我的环境中复制您的情况时尽快进行测试。

        【讨论】:

          【解决方案7】:

          “我希望它在子文件夹 url 中工作。有可能吗?”有一个简单的解决方案。

          步骤
          1. 在您的主域公共文件夹中创建文件夹。 您需要创建 3 个文件夹
          主页/网络/公共/project1
          主页/网络/公共/project2
          主页/网络/公共/project3

          2.在每个项目文件夹中,您需要粘贴 您的 laravel 应用程序的公共文件夹的内容

          (来自您的 Laravel 项目)project1/public/{contents} -- 复制到 -->(托管服务器)home/web/public/project1/ {内容}

          1. 将 laravel 项目的其余部分上传到公共根目录之外,并授予对该文件夹的写入权限。

          2. 现在打开(托管服务器)public/project1/index.php 更新这两个字段

          需要 __DIR __.'/../../PROJECTONE/bootstrap/autoload.php';

          $app = require_once __DIR __.'/../../PROJECTONE/bootstrap/app.php';

          【讨论】:

          • 抱歉回复晚了..这似乎可行..但是现在,如何修复我的路由以支持子目录?当我访问时:avminventarios.com.br/sts4/auth/login 它在 RouteCollection.php 中给了我 NotFoundHttpException
          • 你能分享 project/index.php 的(文件结构)文件夹位置和内容吗?所以我可以帮你解决这个问题。
          • 你能分享你的文件夹是如何管理/放置在服务器上的吗?
          • /avminventarios.com.br/laravel 拥有除公用文件夹之外的所有内容。而公用文件夹内容在/avminventarios.com.br/web/sts2
          • 所有你需要做的就是编辑 /avminventarios.com.br/web/sts2/index.php require __DIR __.'/../../laravel/bootstrap/autoload.php'; $app = require_once __DIR __.'/../../laravel/bootstrap/app.php';确保 laravel 文件夹具有读写权限
          【解决方案8】:

          尝试这样的事情......我正在为我的服务器使用.conf

          server {
              listen  80;
              root /vagrant;
              index index.html index.htm index.php app.php app_dev.php;
          
              server_name 192.168.33.10.xip.io;
          
              access_log /var/log/nginx/vagrant.com-access.log;
              error_log  /var/log/nginx/vagrant.com-error.log error;
          
              charset utf-8;
          
              location ~project(\d*)/((.*)\.(?:css|cur|js|jpg|jpeg|gif|htc|ico|png|html|xml))$ {
                  rewrite project(\d*)/((.*)\.(?:css|cur|js|jpg|jpeg|gif|htc|ico|png|html|xml))$ /project$1/public/$2 break;
              }
          
              location /project1{
                   rewrite ^/project1/(.*)$ /project1/public/index.php?$1 last;
              }
          
               location /project2 {
                  rewrite ^/project2/(.*)$ /project2/public/index.php?$1 last;
              }
          
              location = /favicon.ico { log_not_found off; access_log off; }
              location = /robots.txt  { access_log off; log_not_found off; }
          
              error_page 404 /index.php;
          
              location ~ \.php$ {
                  fastcgi_split_path_info ^(.+\.php)(/.+)$;
                  fastcgi_pass unix:/var/run/php5-fpm.sock;
                  fastcgi_index index.php;
                  include fastcgi_params;
                  set $laravel_uri $request_uri;
                  if ($laravel_uri ~ project(\d*)(/?.*)$) {
                      set $laravel_uri $2;
                  }
                  fastcgi_param REQUEST_URI $laravel_uri;
                  fastcgi_param LARA_ENV local; # Environment variable for Laravel
                  fastcgi_param HTTPS off;
              }
              location ~ /\.ht {
                  deny all;
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2019-08-27
            • 2018-02-25
            • 1970-01-01
            • 1970-01-01
            • 2012-09-28
            • 2019-09-21
            • 2014-03-14
            • 2015-10-24
            • 1970-01-01
            相关资源
            最近更新 更多