Nginx: обслуживать несколько приложений Laravel с одним и тем же URL-адресом, но в двух разных подпунктах в Linux

Я хочу обслуживать несколько приложений Laravel на одном сервере nginx, у первого есть корневой каталог в /var/www/html/app1, у второго - /var/www/html/app2 и так далее. Файл index.php каждого приложения находится в подкаталоге с именем /public.

Всякий раз, когда пользователь вызывает http://www.mywebsite.com/app1, nginx должен возвращать app1, а если пользователь вызывает http://www.mywebsite.com/app2, nginx должен возвращать app2.

Мой текущий файл nginx conf выглядит следующим образом:

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

        root /var/www/html;

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

        server_name _;

        location /app1 {
                root /var/www/html/app1/public;
                index index.php;
        }

        location /app2 {
                root /var/www/html/app2/public;
                index index.php;
        }

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                # try_files $uri $uri/ =404;
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        }

}

Но nginx всегда возвращает результат 404 страницы. Что здесь не так?

Что не так в вашей конфигурации, если вы просматриваете / app1, он перенаправляется на /var/www/html/app1/public/app1/index.php и не может найти это местоположение и выдает 404. Кроме того, указав директиву index в каждом блоке местоположения ПЛОХО и не требуется. Достаточно директивы index, определенной в серверном блоке.

ben5556 25.10.2018 14:11

Вам нужно использовать alias, а не root, и вам нужно будет использовать вложенный блок location в каждом для URI .php. См. этот ответ.

Richard Smith 25.10.2018 14:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
2
1 937
1

Ответы 1

Во время одного из развертываний на Linux-сервере я столкнулся с какой-то вашей проблемой. Это было как следует

  • <base_url>: Для этого нужен один проект Laravel.
  • <base_url>/<sub_url>: Для этого нужно обслужить еще один проект Laravel.

Конечно, это можно распространить на любое количество проектов Laravel, которые следуют концепции <base_url>/<unique_sub_url>.

Теперь перейдем к реальной реализации.

# Nginx.conf
# App 1(Path: /var/www/html/app1, Url: http://www.mywebsite.com)
# App 2(Path: /var/www/html/app2, Url: http://www.mywebsite.com/app2)
server {
    # Listing port and host address
    # If 443, make sure to include ssl configuration for the same.
    listen 80; 
    listen [::]:80;

    server_name www.mywebsite.com;

    # Default index pages
    index index.php;

    # Root for / project
    root /var/www/html/app1/public;

    # Handle main root / project
    location / {
        #deny all;
        try_files $uri $uri/ /index.php?$args;
    }

    # Handle app2 project, just replicate this section for further projects app3, app4 
    # by just replacing app2 with appropriate tag(app3/app4)
    location /app2 {
        # Root for this project
        root /var/www/html/app2/public;

        # Rewrite $uri=/app2/xyz back to just $uri=/xyz
        rewrite ^/app2/(.*)$ /$1 break;

        # Try to send static file at $url or $uri/
        # Else try /index.php (which will hit location ~\.php$ below)
        try_files $uri $uri/ /index.php?$args;
    }

    # Handle all locations *.php files (which will always be just /index.php)
    # via factcgi PHP-FPM unix socket
    location ~ \.php$ {
        # At this point, $uri is /index.php, $args=any GET ?key=value and $request_uri = /app2/xyz.
        # But we don't want to pass /app2/xyz to PHP-FPM, we want just /xyz to pass to fastcgi REQUESTE_URI below. 
        # This allows laravel to see /app2/xyz as just /xyz in its router.  
        # So laravel route('/xyz') responds to /app2/xyz as you would expect.
        set $newurl $request_uri;
        if ($newurl ~ ^/app2(.*)$) {
                set $newurl $1;
                root /var/www/html/app2/public;
        }

        # Pass all PHP files to fastcgi php fpm unix socket
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # Use php fpm sock which is installed on your machine like php7.2, php5.6
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; 
        fastcgi_index index.php;
        include fastcgi_params;
        # Here we are telling php fpm to use updated route that we've created to properly
        # response to laravel routes.
        fastcgi_param REQUEST_URI $newurl;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    # Deny .ht* access
    location ~ /\.ht {
        deny all;
    }
}

Примечание. Когда мы используем настройку laravel на основе сеанса, все функции генератора маршрутов (url(), route()) используют имя хоста www.mywebsite.com в качестве корневого URL-адреса, а не www.mywebsite.com/app2. Чтобы решить эту проблему, внесите следующие изменения в приложение laravel.

  1. Определите APP_URL в файле .env как APP_URL = "www.mywebsite.com/app2"
  2. Перейдите к RouteServiceProvider, который находится по адресу app/Providers/RouteServiceProvider, и заставьте laravel использовать APP_URL в качестве корневого URL-адреса для вашего приложения.
public function boot()
{
    parent::boot();
    // Add following lines to force laravel to use APP_URL as root url for the app.
    $strBaseURL = $this->app['url'];
    $strBaseURL->forceRootUrl(config('app.url'));
}

Обновлять: Обязательно выполните команду php artisan config:clear или php artisan config:cache, чтобы загрузить обновленное значение APP_URL.

Для windows: Несколько приложений Laravel с использованием Nginx - Windows

Это решение идеально подходит и сработало для меня. Однако была одна проблема - сеансы Laravel. сеансы не работали должным образом. Например, каждый раз, когда я пытался войти в свое приложение и посещать другую страницу, которая требует, чтобы я вошел в систему, я перенаправлялся обратно на страницу входа. Это означает, что сеанс не сохраняется должным образом. есть решение для этого?

Michael Yousrie 18.03.2021 05:44

Отвечая на свой предыдущий комментарий, я решил проблему, установив специальный ключ «SESSION_COOKIE» в моем файле env. это позволило мне создать собственное имя сеанса для другого моего приложения laravel. Другое решение заключалось в том, чтобы изменить переменную APP_NAME с «Laravel» по умолчанию, поскольку она используется для создания имени файла cookie.

Michael Yousrie 18.03.2021 06:10

Другие вопросы по теме