任何 AWS EB Laravel 路由都会得到 404 Not Found nginx/1.16.1 错误

24

我刚刚在AWS Elastic Beanstalk上部署了一个新的Laravel 7应用程序。我注意到他们将Apache服务器更改为Nginx服务器。

https://docs.aws.amazon.com/elasticbeanstalk/latest/platforms/platform-history-php.html

这是我的API后端URL:http://mappab-api-staging.mappab.com.br/

这是登录路由:http://mappab-api-staging.mappab.com.br/login - 状态码404。

你是否遇到相同的问题?我该如何解决?

我的php.conf位于/etc/nginx/conf.d/elasticbeanstalk/中:

root /var/www/html/public;

index index.php index.html index.htm;

location / {
   try_files $uri $uri/ /index.php?$query_string;
}

location ~ /\.ht {
   deny all;
}

location ~ /.well-known {
   allow all;
}

location ~ \.(php|phar)(/.*)?$ {
    fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;

    fastcgi_intercept_errors on;
    fastcgi_index  index.php;

    fastcgi_param  QUERY_STRING       $query_string;
    fastcgi_param  REQUEST_METHOD     $request_method;
    fastcgi_param  CONTENT_TYPE       $content_type;
    fastcgi_param  CONTENT_LENGTH     $content_length;

    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  REQUEST_URI        $request_uri;
    fastcgi_param  DOCUMENT_URI       $document_uri;
    fastcgi_param  DOCUMENT_ROOT      $document_root;
    fastcgi_param  SERVER_PROTOCOL    $server_protocol;
    fastcgi_param  REQUEST_SCHEME     $scheme;
    fastcgi_param  HTTPS              $https if_not_empty;

    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

    fastcgi_param  REMOTE_ADDR        $remote_addr;
    fastcgi_param  REMOTE_PORT        $remote_port;
    fastcgi_param  SERVER_ADDR        $server_addr;
    fastcgi_param  SERVER_PORT        $server_port;
    fastcgi_param  SERVER_NAME        $server_name;

    # PHP only, required if PHP was built with --enable-force-cgi-redirect
    fastcgi_param  REDIRECT_STATUS    200;

    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO $fastcgi_path_info;
    fastcgi_pass   php-fpm;
}

2
如果我猜的话,您还没有编辑nginx配置文件以使其与Laravel配合使用,而仍然依赖于htaccess?htaccess是Apache配置文件。Nginx根本不会读取或使用它。如果您搜索“nginx laravel设置”,您将找到大量关于如何设置默认配置的示例。如果您在htaccess中有任何自定义规则,则还需要将它们迁移到nginx配置文件中。 - M. Eriksson
7个回答

52

如果您正在使用带有NGINX服务器的Amazon Linux 2和Elastic Beanstalk,则需要遵循此文档

基本上,您需要做的就是创建一个文件夹结构,将您想要放置配置文件的NGINX配置位置映射到以.platform为最高级文件夹,这应该位于您的应用程序根目录中。

即在laravel应用程序中,在与应用程序文件夹同级别下创建名为.platform的文件夹。在这个.platform文件夹中创建以下内容。

/nginx/conf.d/elasticbeanstalk

你有一个文件夹结构,类似于.platform/nginx/conf.d/elasticbeanstalk

图片描述信息

在 elasticbeanstalk 文件夹中放置您的配置文件

例如: laravel.conf

location / {
    try_files $uri $uri/ /index.php?$query_string;
    gzip_static on;
}

输入图像描述

将应用程序上传到EB后,它将在服务器上将文件复制到相同的位置并重新启动NGINX。


额外信息

在某些情况下,这可能不足够,当尝试访问任何特定路由时,您将收到

419 | 页面过期

输入图像描述

要修复此问题,只需通过SSH进入您的实例,转到项目位置并清除缓存即可。

php artisan cache:clear

10
这是确定性的解决方案,也是正确的方法,特别是因为在 EBS 上运行命令不是一个很好的实践。 - Carlos Luis Rojas Aragonés
5
应该接受以下答案作为正确答案——ElasticBeanstalk的配置应该通过.ebextensions/.platforms等方式完成,而不是通过手动调整服务器。 - jOpacic
虽然这解决了我的问题,但每次我更新EC2实例中的内容时都需要这样做。有什么想法是为什么吗? - Sijan Bhattarai
如果您正在使用弹性 Beanstalk,则不需要直接更改 ec2 实例,所有设置和配置都是通过 EBS 完成的,可以使用控制台或上述配置文件进行操作。直接更改 ec2 实例只会是暂时性的更改。 - niallD
经过多个小时的努力,终于成功了。我在 Laravel 8 项目中创建了文件“/.platform/nginx/conf.d/elasticbeanstalk/laravel.conf”,然后将其推送到 Github,Elastic Beanstalk 检测到更改并完成了部署。 - Imran_Developer
1
这是最好的方法。没有必要通过SSH访问实例,因为这违反了EBS应该处理的方式。 - Umair Malhi

26

我遇到了同样的问题,自2020年4月30日起,EB自动配置为nginx,而不是apache,因此htaccess文件不再起作用。所以当我上传我的代码时,前台页面(index.php)可以工作,但api不能。这是我解决这个问题的方法 - 取自AWS开发者组:https://forums.aws.amazon.com/thread.jspa?messageID=942914&#942914

  1. 通过SSH进入弹性豆荚环境(您可以在EC2实例中生成一个密钥对,这将下载一个pem(私有密钥文件),然后在弹性豆荚环境的配置/安全性中附加密钥对)。
  2. 在终端上(在Mac上),导航到存储您的私有密钥的位置并使用:
ssh -i "your_private_key_name.pem" ec2-user@your_server

当出现您的PEM文件太开放的错误消息时,请使用以下命令:

chmod 400 your_private_key_name.pem
  1. 使用以下方式导航到php.conf文件:
cd /etc/nginx/conf.d/elasticbeanstalk
  1. 使用此选项输入文件:
sudo nano php.conf
  • 这将打开php.conf文件,它看起来会像这样:
  • # This file is managed by Elastic Beanstalk
    #
    # pass the PHP scripts to FastCGI server
    #
    # See conf.d/php-fpm.conf for socket configuration
    #
    root /var/www/html/public;
    
    index index.php index.html index.htm;
    
    location ~ \.(php|phar)(/.*)?$ {
        fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
    
        fastcgi_intercept_errors on;
        fastcgi_index  index.php;
    
        fastcgi_param  QUERY_STRING       $query_string;
        fastcgi_param  REQUEST_METHOD     $request_method;
        fastcgi_param  CONTENT_TYPE       $content_type;
        fastcgi_param  CONTENT_LENGTH     $content_length;
    
        fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
        fastcgi_param  REQUEST_URI        $request_uri;
        fastcgi_param  DOCUMENT_URI       $document_uri;
        fastcgi_param  DOCUMENT_ROOT      $document_root;
        fastcgi_param  SERVER_PROTOCOL    $server_protocol;
        fastcgi_param  REQUEST_SCHEME     $scheme;
        fastcgi_param  HTTPS              $https if_not_empty;
    
        fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
        fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    
        fastcgi_param  REMOTE_ADDR        $remote_addr;
        fastcgi_param  REMOTE_PORT        $remote_port;
        fastcgi_param  SERVER_ADDR        $server_addr;
        fastcgi_param  SERVER_PORT        $server_port;
        fastcgi_param  SERVER_NAME        $server_name;
    
        # PHP only, required if PHP was built with --enable-force-cgi-redirect
        fastcgi_param  REDIRECT_STATUS    200;
    
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        fastcgi_pass   php-fpm;
    }
    

    将以下内容插入到“index”之后、“location”之前。
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
    
    1. 保存文档

    2. 运行此命令以重新启动nginx


    sudo nginx -s reload
    

    退出环境,你的 API 现在应该可以工作了。

    1
    当您通过ssh登录EC2实例时,可能会收到错误消息“未受保护的私钥文件”。在这种情况下,请运行命令“sudo chmod 600 your_private_key_name.pem”,然后输入密码。尝试再次进行ssh登录,应该可以正常工作。 - John Welsh
    1
    我们能否将这些命令添加到“.ebextensions”文件夹中,以便在启动时自动运行? - Guri S
    嘿,为什么每次重新启动ec2实例都要不断更改我的php.conf文件?这是正常情况吗? - Sijan Bhattarai
    我尝试过这种方法3次,每次都导致整个网站崩溃... - jamesbcn
    @SijanBhattarai 为了使更改持久化,在项目的根目录下创建以下目录结构:.platform/nginx/conf.d/elasticbeanstalk,并将php.conf与其中的conf.php文件内容添加到其中。这对我有用;即使重新启动后更改仍然存在。 - Steve Dimock

    5

    我曾经处于同样的情况,为了更新Elastic Beanstalk自动提供的默认nginx设置,我准备了以下配置文件。

    1. 在Laravel项目中准备一个名为nginx.conf的自定义nginx配置文件。
    ~/workspace/your-laravel-app/
    |-- .platform
    |   -- nginx
    |      -- nginx.conf
    |-- other source files
    
    1. 按以下方式编辑您自己的nginx.conf文件。
    user                    nginx;
    error_log               /var/log/nginx/error.log warn;
    pid                     /var/run/nginx.pid;
    worker_processes        auto;
    worker_rlimit_nofile    32153;
    
    events {
        worker_connections  1024;
    }
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        include       conf.d/*.conf;
    
        map $http_upgrade $connection_upgrade {
            default     "upgrade";
        }
    
        server {
            listen        80 default_server;
            access_log    /var/log/nginx/access.log main;
    
            client_header_timeout 60;
            client_body_timeout   60;
            keepalive_timeout     60;
            gzip                  off;
            gzip_comp_level       4;
            gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    
            # Do not include the Elastic Beanstalk generated locations
            # include conf.d/elasticbeanstalk/*.conf;
    
            # Move Elastic Beanstalk healthd.conf content here
            if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
                set $year $1;
                set $month $2;
                set $day $3;
                set $hour $4;
            }
    
            access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
    
            # Move Elastic Beanstalk php.conf content here
            root /var/www/html/public;
    
            index index.php index.html index.htm;
    
            # This is an additional configuration
            location / {
                try_files $uri $uri/ /index.php?$query_string;
                gzip_static on;
            }
    
            location ~ \.(php|phar)(/.*)?$ {
                fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
    
                fastcgi_intercept_errors on;
                fastcgi_index  index.php;
    
                fastcgi_param  QUERY_STRING       $query_string;
                fastcgi_param  REQUEST_METHOD     $request_method;
                fastcgi_param  CONTENT_TYPE       $content_type;
                fastcgi_param  CONTENT_LENGTH     $content_length;
    
                fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
                fastcgi_param  REQUEST_URI        $request_uri;
                fastcgi_param  DOCUMENT_URI       $document_uri;
                fastcgi_param  DOCUMENT_ROOT      $document_root;
                fastcgi_param  SERVER_PROTOCOL    $server_protocol;
                fastcgi_param  REQUEST_SCHEME     $scheme;
                fastcgi_param  HTTPS              $https if_not_empty;
    
                fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
                fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
    
                fastcgi_param  REMOTE_ADDR        $remote_addr;
                fastcgi_param  REMOTE_PORT        $remote_port;
                fastcgi_param  SERVER_ADDR        $server_addr;
                fastcgi_param  SERVER_PORT        $server_port;
                fastcgi_param  SERVER_NAME        $server_name;
    
                # PHP only, required if PHP was built with --enable-force-cgi-redirect
                fastcgi_param  REDIRECT_STATUS    200;
    
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                fastcgi_param  PATH_INFO $fastcgi_path_info;
                fastcgi_pass   php-fpm;
            }
        }
    }
    

    部署您的更改,新配置将被加载。
    $ eb deploy
    

    谢谢,它正常工作。但你知道如何将非www重定向到www吗? - Najathi

    2

    我刚刚遇到了这个问题,不得不解决它。默认的PHP实现没有考虑到Laravel引起的文件夹差异(在文档中没有提到)。

    您需要在EC2服务器上查找您的nginx站点配置。对我来说,它是:

    /etc/nginx/conf.d/elasticbeanstalk/php.conf
    
    sudo nano php.conf
    

    默认的根目录是 /var/www/html;但是这是不正确的,因为需要添加 laravel 文件夹。所以,你需要将其添加进去:

    root /var/www/html/your-laravel-app-name/public;
    

    您需要在EC2服务器上进行操作,这样您就可以随时导航到该文件夹并检查它。

    我相信其他人将能够提供所需的内容以在弹性 Beanstalk 环境中进行自动配置。

    我还添加了以下行到 nginx 配置文件中,用于基本的 Laravel 配置:

    location / {
       try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ /\.ht {
       deny all;
    }
    
    location ~ /.well-known {
       allow all;
    }
    

    不用担心,如果这个答案有帮助,请将其标记为选择。如果你的配置不同,请放上你的配置以供其他人搜索相同的内容。 :) - Mugluck
    嗨。我使用 eb ssh 访问我的 php.conf。这样正确吗?正如你告诉我的那样,有一个名为 php.conf 的文件,看起来是正确的。root /var/www/html/public; index index.php index.html index.htm;我添加了你关于位置的额外行,但它不起作用。我应该访问我的 EC2 实例吗?难道 eb ssh 命令不是访问 EC2 实例吗?谢谢。 - Felipe Neuhauss
    在这种情况下,应该是ec2实例,root /var/www/html/public不正确,因为它没有考虑到laravel文件夹---/html/laravel-folder-here/public。 - Mugluck
    好的,我会检查我的EC2实例。谢谢!我已经编辑了我的问题,添加了完整的php.conf文件。 - Felipe Neuhauss
    是的。我将尝试在php.conf中添加应用程序名称。当我访问我的EC2实例时,我得到了与通过eb ssh访问时相同的环境。 - Felipe Neuhauss
    显示剩余4条评论

    0
    尝试将代理服务器更改为Apache。

    你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

    0

    -1
    我遇到了同样的问题,我的解决方法是将 laravel.conf 文件中的 error_page 指令删除。
    以下是我的配置文件:
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    
    client_max_body_size 10M;
    
    index index.php;
    
    charset utf-8;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
    
    #error_page 404 index.php;
    
    location ~ /\.(?!well-known).* {
        deny all;
    }
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接