NOTE: This project works well on my localhost.
I installed this Laravel project on my server with Nginx as the webserver. It installed fine since I followed the instructions but when I upload an image to replace a current one like: avatar, logos, favicons; they’re uploaded but do not show up. The image field shows broken images.
Browser console says "Failed to load resource: the server responded with a status of 404 (Not Found)" and when I try previewing the image following the link provided, it says "404 | NOT FOUND" even though it exists and that is the correct URL.
I have done all what I know to do like clearing Laravel’s routes, config and cache. I have tried setting the folder’s permission to 777 just to be sure. I’ve set all the necessary permissions the way they should be set but not working still. I even had to install Apache webserver because I thought Nginx had the problem only to get the same error. I had to revert back to Nginx.
I can’t visit a sub-directory I created myself like "/main/" or view an uploaded image using the correct URL.
- I turned off NGINX: systemctl stop nginx
- I installed Apache and started the service; moved the project to a new directory, updated the Virtual hosts record (of cos I used "public"). The same issue
- I’ve set file and directory permissions for all files and directories in the project directory: 644 and 755; still the same error.
- I made sure the main project directory is owned by www-data; did all that with chgrp, chown. The same issue
PROJECT: solut.website.com
user@localhost:/var/www$ ls -l
total 12
drwxr-xr-x 16 www-data www-data 4096 Apr 8 15:26 solut.website.com
PROJECT ROOT DIR & FILES
user@localhost:/var/www$ ls -la solut.website.com/
total 83748
drwxr-xr-x 16 www-data www-data 4096 Apr 8 15:26 .
drwxr-xr-x 5 root root 4096 Apr 8 09:11 ..
drwxr-xr-x 12 www-data www-data 4096 Dec 23 2022 app
-rw-r--r-- 1 www-data www-data 1686 Dec 23 2022 artisan
drwxr-xr-x 3 www-data www-data 4096 Dec 23 2022 bootstrap
-rw-r--r-- 1 www-data www-data 2727 Apr 20 2023 composer.json
-rw-r--r-- 1 www-data www-data 411030 Apr 20 2023 composer.lock
drwxr-xr-x 2 www-data www-data 4096 Apr 3 2023 config
drwxr-xr-x 5 www-data www-data 4096 Dec 23 2022 database
-rw-r--r-- 1 ample www-data 258 Dec 23 2022 .editorconfig
-rw-r--r-- 1 ample www-data 589 Mar 28 09:09 .env
-rw-r--r-- 1 ample www-data 590 Mar 28 08:15 .env_backup
-rw-r--r-- 1 ample www-data 912 Dec 23 2022 .env.example
drwxr-xr-x 2 www-data www-data 4096 May 28 2023 erpgo
-rw-r--r-- 1 www-data www-data 84783392 May 28 2023 erpgo.zip
-rw-r--r-- 1 ample www-data 152 Dec 23 2022 .gitattributes
-rw-r--r-- 1 ample www-data 16 Feb 23 2023 .gitignore
-rw-r--r-- 1 ample www-data 931 Dec 23 2022 .htaccess
drwxr-xr-x 3 ample www-data 4096 Apr 28 2023 .idea
-rw-r--r-- 1 www-data www-data 563 Mar 9 2023 index.php
drwxr-xr-x 3 www-data www-data 4096 Dec 23 2022 lang
drwxr-xr-x 2 www-data www-data 4096 May 28 2023 main
-rw-r--r-- 1 www-data www-data 682 Apr 26 2023 package.json
-rw-r--r-- 1 www-data www-data 406860 Apr 26 2023 package-lock.json
-rw-r--r-- 1 www-data www-data 717 May 27 2023 phptest.php
-rw-r--r-- 1 www-data www-data 1175 Dec 23 2022 phpunit.xml
drwxr-xr-x 8 www-data www-data 4096 Jun 5 2023 public
-rw-r--r-- 1 www-data www-data 3958 Dec 23 2022 README.md
drwxr-xr-x 6 www-data www-data 4096 Feb 17 2023 resources
drwxr-xr-x 2 www-data www-data 4096 Mar 28 17:12 routes
drwxrwxrwx 19 www-data www-data 4096 May 28 2023 storage
-rw-r--r-- 1 ample www-data 162 Dec 23 2022 .styleci.yml
-rw-r--r-- 1 www-data www-data 487 Dec 23 2022 tailwind.config.js
drwxr-xr-x 4 www-data www-data 4096 Dec 23 2022 tests
drwxr-xr-x 69 www-data www-data 4096 Apr 20 2023 vendor
-rw-r--r-- 1 www-data www-data 5046 Apr 28 2023 verification.php
-rw-r--r-- 1 www-data www-data 596 Dec 23 2022 webpack.mix.js
PROJECT .htaccess file
user@localhost:/var/www$ cat solut.website.com/.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_URI} !(.css|.js|.png|.jpg|.jpeg|.gif|robots.txt|.ico|.woff|.woff2|.ttf|.svg)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^(css|assets|landing|storage|installer|js)/(.*)$ public/$1/$2 [L,NC]
</IfModule>
## NGINX Virtual Host
user@localhost:/var/www$ cat /etc/nginx/sites-available/solut.website.com.conf
server {
# Server
server_name solut.website.com; # managed by Certbot
# Root directory
root /var/www/solut.website.com/public;
# Laravel Deployment: laravel.com/docs/10.x/deployment#nginx
# LD 1
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
# Index page
index index.php index.html index.htm; #was previously DISABLED
# LD 2
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string; #because of LARAVEL
}
# LD 3
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
# LD 4
error_page 404 /index.php;
# Setup PHP
location ~ .php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
# LD 6
location ~ /.(?!well-known).* {
deny all;
}
# Disable .htaccess from being served
location ~ /.ht {
deny all;
}
# Serving static files
location ~* .(css|js|png|jpg|jpeg|gif|ico|woff|woff2|ttf|svg)$ {
expires max;
log_not_found off;
access_log off;
}
# Serving public directory
location ~* ^/public/(css|assets|landing|storage|installer|js)/(.*)$ {
rewrite ^/public/(css|assets|landing|storage|installer|js)/(.*)$ /public/$1/$2 break;
}
#location ~ /* {
#rewrite ^/(.*)$ /index.php?_url=/$1;
#}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/solut.website.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/solut.website.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = solut.website.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 ;
listen [::]:80 ;
server_name solut.website.com;
return 404; # managed by Certbot
}
Nothing in the Logs have been helpful either other than "404"
2
Answers
Note the vertical bar, it identifies "it" as Laravel.
Only you use Nginx to run Laravel, this is a route handled by Laravel now, not of the webserver.
Note that here, "it" it is a file and that "is the correct URL" is irrelevant as for your Laravel you want to know if a route exists (not a file) and that the correct route is in use (and not a correct URL only).
TLDR: Sounds like a configuration issue. Destroy the server and provision it a new, then deploy the application.
It normally then works and even if not, you have limited the configuration error to the deployment routine and the server provisioning. Continue there then with your trouble-shooting as you have now managed to make the problem reproducible.
Try
php artisan storage:link
and ensure that the folderpublic/storage
exitsts. Also make sure that all images are placed in the folderpublic
, and that you are useasset()
to access them in your templates.Also, in the
.env
make sure that you have the APP_URL defined properly. If you are usingphp artisan server
on port 8000, you will need to setAPP_URL=http://localhost:8000
.