在没有子域的子文件夹中安装多个laravel项目


Install multiple laravel projects in subfolders without subdomain

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

  • 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中工作。有可能吗?

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

  • http://customerdemo.example.com/project1/
  • http://customerdemo.example.com/project2/
  • http://customerdemo.example.com/project3/

但我讨厌每次添加新项目时都要修改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来添加新项目。

事实上,我已经为自己开发了一个控制面板,在那里我可以点击"添加项目"并指定项目详细信息和新的比特桶回购,mysql用户和数据库将被创建,customerdemo服务器将被授予对该比特桶回购的部署访问权限,并且在该新回购中设置了一个webhook,每当有人在该回购上提交master时,该webhook将调用customerdemo服务器上的部署脚本,这将触发git克隆或git pull and composer安装和数据库迁移。这就是为什么我需要动态Nginx配置

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

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;
}}

我使用一个简单的符号链接在另一个网站的"子文件夹"中成功运行了一个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()可以处理地址栏中包含的内容。

我认为问题可能在您的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/在您的web根目录之外。

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

我从这个要点中得到了这个建议的基本想法。

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

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

在最后一个例子中,var_dump是模型,并查找它的来源。

您尝试过这种配置吗?

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

我明天会测试,只要我有时间在我的环境中复制你的情况。

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

步骤
1.将主域中的文件夹设为公用文件夹。您需要创建3个文件夹
主页/web/public/project1
主页/web/public/project2
主页/web/public/project3

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

(从您的Laravel项目)project1/public/{contents}--将其复制到-->(托管服务器)home/web/public/project1/{contents}

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

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

需要__DIR__'./..//PROJECTONE/bootstrap/autoload.php’;

$app=需要一次__DIR __'./..//PROJECTONE/bootstrap/app.php’;

试试这样的。。。。我的服务器使用以下.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;
    }
}