I have a Laravel 8 project running on an Nginx Webserver in a Docker container through an Nginx Reverse Proxy.
So DNS -> Reverse Proxy -> Docker Webserver container -> PHP-FPM container
The problem is that when I use Laravel's route()
it is missing the www resulting in login not working (as well as assets etc).
Because I AM on the www domain (because of Nginx redirect) but the route endpoint is non-www (so a different site, token issue I believe).
In my .env I have APP_URL set which I believe is only for CLI commands and additionally I have ASSET_URL set, which works for the asset()
functions. I should not have to use ASSET_URL if the source of the problem, my setup, is correct (which it clearly is not).
I CAN bypass the problem by using URL::forceRootUrl(config('app.url'));
in my router, that forces the APP_URL set in my .env to be used in the RouteUrlGenerator
(I believe)
Output of \URL::to('/')
is https://example.com, so NON-WWW (obv. WITHOUT using URL::forceRootUrl(config('app.url'));
)
Even though my browser's URL is including www, so https://www.example.com/blabla.
I would say something is wrong in my setup, either my DNS, Nginx Reverse Proxy, or Nginx Webserver configs but I can't figure out what it is...
I hope it is just a simple redirect fix somehow.
I have also already restarted my servers etc and done a php artisan optimize:clear
and also config:cache
and config:clear
to be sure.
Please find below my configs:
DNS via CloudFlare (proxied):
A example.com 123.123.123.123 Proxied
A www 123.123.123.123 Proxied
CNAME * example.com DNS Only
My Nginx Reverse Proxy config:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:8012;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
My Nginx webserver config:
server {
# listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
server {
# listen 80 default_server;
index index.html index.htm index.php;
server_name www.example.com;
root /var/www/public;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php-fpm:9012;
fastcgi_index index.php;
include fastcgi_params;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /var/www/example.com/public/$fastcgi_script_name;
# fastcgi_param SCRIPT_FILENAME $document_root/example.com.au/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
# Support Clean (aka Search Engine Friendly) URLs & enable Gzip compression:
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
}
My "default" Laravel 8 .htaccess:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>
My .env:
APP_NAME=SomeSite.com
APP_ENV=production
APP_KEY=base64:sdljkldasjkasjasdjklaslkasd
APP_DEBUG=true
APP_URL=https://www.example.com#Used for CLI function such as artisan...
#ASSET_URL=https://asseturl.test#Only used in asset()
TRUSTPROXIES=*
...
Solution is moving the 301 redirect from Nginx Webserver to Nginx Reverse Proxy (superior level).
This is the following part of the configuration file:
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
Edit: I suspect it's related to the part:
proxy_set_header Host $host;