Issue with Storage on shared hosting - php

I am deploying my first project on a shared hosting.
I followed this tutorial to deploy the website and turn the public folder into the public_html folder of my hosting plan.
When I upload an image from my website (with storeAs() method), the file is uploaded in the private/storage folder, not the public one (where I would like).
The asset() function try to display the image from public_html/storage.
What can I do ?
Thank you :)
My files are like this :
private/
- app/
- bootstrap/
- config/
- database/
- resources/
- routes/
- storage/
- tests/
- vendor/
public_html/
- css/
- js/
- images/
- js/
- storage/
(Laravel 8, trying to be hosted on Hostinger)
The tutorial : https://dev.to/pushpak1300/deploying-laravel7-app-on-shared-hosting-hostinger-31cj

Why does this problem happen?
If you implement and need storage matter in your project then you need to link storage folder to the public folder for security reason and to make the URL simple, clean and readable by the users, so when you upload the laravel project to a server, you need to run the following command line to complete the linking process:
php artisan storage:link
and since you host the laravel project to a shared server, so you don’t have access to a terminal to run the above-mentioned command line . so I’ll show you a way to do that manually without using SSH or the terminal.
Steps to fix the problem
1- At localhost server-side (before uploading the project to the server), make sure that you have done filesystem configuration, then run the following command line:
php artisan storage:link
after that you will get a message “The links have been created.” and that is ok for now.
2- Upload the project to the server, the storage link will not work as you expected, so we need to start fixing this.
3- Go to the public folder you will find a folder called “storage”, delete it.
4- Go to routes folder and open “web.php” file, then copy & paste the following code at the top of the file:
Route::get('/linkstorage', function () {
Artisan::call('storage:link') // this will do the command line job
});
Don’t forget to save the changes.
Also, you can do the same process via “api.php” and using requests tools like postman.
5- Now we just need to run this code, so we need to do the GET request by entering the following URL at browser search bar:
“https://www.your-domain.com/public/index.php/linkstorage”
or
“https://www.your-domain.com/public/linkstorage”
this request will run the above code “Artisan::call('storage:link')” which is, in turn, will run the command line
PHP artisan storage: link
now you can go to the public folder and you will see the “storage” folder created again and marked as a shortcut folder and that means the public storage folder now is linked to the storage folder of the project.
6- Now if you upload or create a file to the storage folder, then it will appear in the public/storage folder too, now you can hit the URL of the file at the search bar of the browser and you will get the file successfully :).

Ok guys i found the solution !
Here is how to deploy your Laravel project on one shared hosting using public_html folder : https://dev.to/pushpak1300/deploying-laravel7-app-on-shared-hosting-hostinger-31cj
This will work but you can have a problem (like me) with the storeAs() method if you deal with file uploads.
To solve this problem, I edited the MyProject/config/filesystem.php by adding this in the available disks :
'public_folder' => [
'driver' => 'local',
'root' => 'PATH',
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
]
Replace PATH with the complete path to your public storage (for example /home/you/domains/mydomain.com/public_html/storage/).
Now, open the controller which manage file upload and edit it like this :
request()->image->storeAs('/uploads', 'filename.png', 'public_folder');
This will upload the request()->image in public_html/storage/uploads/filename.png.
I hope it will help you if you had the same problem as me.

Related

Redirect to public/ in php artisan serve

I have a laravel application that I made changes to the folder structure, I have been working with laragon and everything works fine but on my local environment and live server.
However, when i user php artisan serve, the generated url doesn't load assets in the public folder.
E.g
https://livewebsite.com // [live server] works.
https://myproject.local // [laragon] works.
http://localhost/myproject // [laragon /xampp] works
http://127.0.0.1:8000 // artisan [doesn't load assets, assets in the public directory returns 404
//e.g http://127.0.0.1:8000/public/assets/themes/cryptic/style/bgs.css would return 404
Changes I made,
|-core
|-public
|-.htaccess
|-index.php
I have moved all laravel core folders and files to the core folder,
moved the .htaccess and index.php to the root directory.
From my debugging so far, I understand that laravel built in server redirects requests to the public folder where the index.php file is located.
What changes can I make so that the request is not sent to the public folder,
i.e http://127.0.0.1:8000/public/assets/themes/cryptic/style/bgs.css should just be allowed to be without be redirected.
The entire thing works on various environments except when I'm using laravel built-in PHP server with the artisan command.
EDIT
Folder structure
|-project
|-core
|-app
|-bootstrap
|-config
|-database
|-lang
|-etc
|-public
|-assets
|-test-folder
|-img.png
|-.htacess
|-index.php
in this setup, laravel base_path() is project/core . This where all laravel core files and folders are stored.
Now I have folder test-folder with an image img.png . If i go to http://localhost/project/new-folder/img.png it will return the image but if i go http://127.0.0.1:8000/new-folder/img.png will return 404. If i use a live server and go http://livewebsite.com/new-folder/img.png , it loads.
I can't comment due to reputation, but what you're doing might be unsafe!
This way all your project files will be public, which can expose credentials and exposes Composer packages to the public as well. This means any PHP file in any Composer package can be executed, which can lead to remote code execution, which has happened before here and is described here.

Laravel Voyager image broken after uploading in server

Laravel Version: 5.5
Voyager Version: 1.0
PHP Version: 7
I have uploaded my laravel project in cPanel. Previous images are shown successfully but the newly added images are not showing.
Here last 2 images are already in the project before uploading in cPanel. After uploading the project successfully in cPanel I have try to upload an image but it is not shown which is first one.
Anybody help ?
i tryed with change in config/filesystem.php
Change the path from storage_path() to public_path().
'public' => [ 'driver' => 'local', 'root' => public_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', ],
but it not worked. please help me!
broken image url- http://example.com/storage/products/December2018/QIDyzoFg1aAf6NUGMJtZ.jpg
i found the solution ! the promblem was in the symlink(storage symbolic link).
in the localhost we can easily create the symlink from voyager adminpannel or in terminal
php artisan storage:link
in that case in shared hosting we cannot do that .see below what i do.
1.log in to the cpannel
2.go the project folder then go public->storage folder then rename it to storage old or somthing.
3.come back to the cpannel main menu and select the cron job
4.in common settings --> select *once per 5 minutes
5.in the command field add this
ln -s /home/cpanel_username/project_name/storage/app/public /home/cpanel_sername/project_name/public/storage
(my site was in subdomain) example-ln -s /home/your_cpannel_user name/public_html/subdomain_foldername/storage/app/public /home/cpanel_username/public_html/subdomain_foldername/public/storage
syntax-->ln -s target_path link_path
6.type your email in the cron email and update email(when the job was done email notification wiil come to your inbox check the spam folder)
6.create new cronjob
7.wait few minutes you almost done.! after the execution delete the cronjob
8.log and check upload path working correctly!
Assuming that your Laravel project "public" directory and "public_html" directory are different, please run the following command:
php artisan storage:link
This command will create symlink to "public" directory to your Laravel project, not inside the "public_html". Next we'll need to move the "storage" link to "public_html" directory, for this you can move directly. If it doesn't work then go inside the "public" directory and run the below command according to your public_html directory location:
mv storage /home/*yourHostinInfo*/domains/*domainName*/public_html
The path might be different based on your hosting information.

Storage in laravel says symlink - no such file

I deployed laravel app on shared hosting in public_html/app folder. Here is everything from public folder. In /../../files I have rest of files. When I do php artisan storage:link in files folder my console says
[ErrorException]
symlink(): No such file or directory
On localhost I upload files to storage/uploads folder. What to do now? I tried to change links but nothing works for me...
Go to /public directory and run:
rm storage
Go to Laravel root directory and run:
php artisan storage:link
Edited on May 1st 2018
This problem comes when laravel project is moved/copied to some other folder.
The storage link is still there thus causing the exception error. public/storage folder exists and points to wrong location and it needs to be deleted with rm storage command.
After that run php artisan storage:link in terminal and it will create the storage link.
This needs to be done EVERY time when laravel is moved/copied/deployed!
I'm face same error when use share hosting and my public directory move to public_html or different directory
like :
project directory in root name "project"
and public directory in root name "public_html"
when run artisan command by Artisan::call('storage:link'); then face this error.
Solution:
1st need to bind your public directory in app/Providers/AppServiceProvider register method
$this->app->bind('path.public', function() {
return base_path('../public_html');
});
Now run the command its working fine
Just in case your down here still without an answer.
I had trouble because I did the symlink locally, then copied the files to the server. In order to make it work I did the following:
$ cd path/to/laravel/root
// if public does not exist, first create it.
$ cd public
// if public/storage does not exist, first create it.
$ rm -r storage
$ cd ..
// Now it should work
$ php artisan storage:link
This usually happens after moving Laravel app to another directory
The actual storage directory is "/AppName/storage/app/public/"
Laravel creates a symbolic link pointing to actual storage dir "/AppName/public/storage"
Other meaning
"/AppName/public/storage" points to => "/AppName/storage/app/public/"
On changing root app directory to "/AnotherAppName/" symlink will still point to the old path
"/AnotherAppName/public/storage" => "/AppName/storage/app/public/"
my solution is to manually update the symlink using
ln -sfn /AnotherAppName/storage/app/public/ /AnotherAppName/public/storage
Anyone coming in the future using Laravel Forge. I had this error when I renamed my domain name in Forge.
The solution was to go into the public directory and delete the existing symlink which had been copied over from the original domain.
After this symlink had been deleted, I was able to run php artisan storage:link again and this worked correctly.
create new php file and put this code on the file:
<?php
symlink('/home/CpanelUser/storage/app/public', '/home/CpanelUserpublic_html/storage');
?>
"CpanelUser" change to youre cpanel user name or host name.
Upload this file to public_html folder (www) of site
execute file with write site name+this file in browser
done!
Example:
My file name is symlink.php and site name is www.anysite.com
upload symlink.php to public_html folder in host and get web address in browser
http://www.anysite.com/symlink.php
after execute this file storage folder creite in public folder in laravel and link to storage folder in app.
To fix this error on your server, change directory to the public and remove the symbolic link for the storage folder.
The following commands will help you remove the symbolic link from the public folder:
cd public
rm storage
After removing the symbolic link go back to the root folder using with the command below:
cd ..
Now create the symbolic link with the following command:
php artisan storage:link
After running the command successfully, you should get the following message
The [public/storage] directory has been linked.
I hope this post helps you.
SYMLINK(): No Such File or Directory Laravel
Follow these three steps:
Remove storage file from public folder.
rm public/storage
If storage folder is there in your root directory, remove public file inside app folder.
rm storage/app/public
Run link command
php artisan storage:link
Make sure the APP_URL configuration in .env file is set correctly. after that run following command line:
php artisan config:cache
php artisan storage:link
Go to config/filesystem.php in the symbolic links section in my case I removed public_path function and wrote my own path in it then run php artisan storage:link command again.
'links' => [
'/var/www/storage' => storage_path('app/public'),
],
Worked for me.
if issue is not fixed yet.
Do These Steps:
Delete storage link from public folder or run these commands.
a)
cd public
b) rm storage
Goto storage folder and check if app/public
folder exists otherwise create new folder.
Check if the error is fixed.
If these steps not fixed your issue delete storage folder and create new storage folder containing all necessary folders on it.
storage folder contains:
app, framework,logs
app contains: public
framework contains: cache, data,sessions,testing, views
Add this inside web.php and then hit this 'BASE_URL/linkstorage' URL once.
Now check the storage folder will be created inside the public folder. This will resolve your issue.
Route::get('/linkstorage', function () {
$targetFolder = base_path().'/storage/app/public';
$linkFolder = $_SERVER['DOCUMENT_ROOT'].'/storage';
symlink($targetFolder, $linkFolder);
});
My problem was that te symlink not was placed in /localhost/public/ but in /localhost/storage/app/
When i removed the symlink in /localhost/storage/app/ the artisan command works like a charm
In my code i placed this to prevent creating the wrong symlink
Route::get('/clear', function () {
Storage::deleteDirectory('public');
Storage::makeDirectory('public');
Artisan::call('route:clear');
Artisan::call('storage:link', [] );
});
If you are using shared hosting or you have deployed your project on a server with cPanel or DirectAdmin, you probably have a public_html instead of a public folder.
So one thing we usually do is change the Laravel public folder to public_html.
and then we go to our AppServiceProvider and bind the new path with the help of code below:
$this->app->bind('path.public', fn() => base_path('/public_html'));
But you should know the configuration files load before these register methods at your providers, so you have also to bind this before your kernel bootstrap your config files.
in order to do that, open index.php and write the code bellow after the $app variable defined:
$app->bind('path.public', fn() => base_path('/public_html'));
I know this might not seem a standard way, but It is working perfectly fine, and I haven't found any critical issue for it yet!
Add this to index.php
$app->bind('path.public', function() { return __DIR__; });
then on routes/web.php
add this
Route::get('/linkstorage', function () {
Artisan::call('storage:link');
});
Then run the link
I was using Vagrant and had the same problem. I removed to storage directory in public/storage but couldn't resolve the problem when using the command php artisan storage:link.
Therefore I connected with ssh to my vagrant box and ran the command there. It worked, so if you are running Vagrant and have the same problem this might help.
Delete the existing storage symbolic link (public/storage) and then run
php artisan storage:link command again.
In my case, I found that because I had moved all of the /public Laravel files to public_html (on my shared server), that the /public Laravel directory no longer existed.
After making a new "public" directory, I was able to successfully run the 'php artisan storage:link' command.
more instant i improve the answer of #suresh-pangeni
mv storage storage.bak // just for backup
mkdir -p storage/{app/public,framework/{cache,data,sessions,testing,views},logs}
php artisan storage:link
now its work
dont forget to
Go to /public directory and run:
then
rm storage before run on above command.
☺ pa storage:link
production 9999 ✗ The [public/storage] directory has been linked.
The solution is above but in separate parts, do one and two. Adding the route makes it easier for use case on external servers like shared hosts for example, thanks everyone
Go to config/filesystem.php in the symbolic links section in my case I removed public_path function and wrote my own path in it then run php artisan storage:link command again.
'links' => [
'/var/www/storage' => storage_path('app/public'),
],
For create storage link without terminal command(get at url)
Route::get('/linkstorage', function () {
$targetFolder = base_path().'/storage/app/public';
$linkFolder = $_SERVER['DOCUMENT_ROOT'].'/storage';
symlink($targetFolder, $linkFolder);
});
The issue normally happens when you changed the folder location after you generated your first symbolic link, I solved this isse by following the below steps:
Go in to the public folder and delete the storage folder(It will be labeled with red flag)
After deleting the storage folder, run php artisan storage:link and the issue will be solved
Follow these steps:
Step-1: server.php
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* #package Laravel
* #author Taylor Otwell <taylor#laravel.com>
*/
$uri = urldecode(
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
// built-in PHP web server. This provides a convenient way to test a Laravel
// application without having installed a "real" web server software here.
if ($uri !== '/' && file_exists(__DIR__.'/public_html'.$uri)) {
return false;
}
require_once __DIR__.'/public_html/index.php';
Step-2: App\Providers\AppServiceProvider.php
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//Public folder name changed with public_html
$this->app->bind('path.public', function(){
return base_path().'/public_html';
});
}
It is allow you to run the usual command php artisan serve
Step-3: config\filesystems.php
'links' => [
base_path('public_html/storage') => storage_path('app/public'),
],
To get the storage symbolic link properly with php artisan storage:link
Remember to change the path if is not public_html like for me
If someone faces the same error in Docker and Laravel9, try by deleting storage file in public folder and executing php artisan storage:link again. In my case it is 0KB.
In my case, I had added more than one symbolic link added to config/filesystems, one of the links is meant to be created in a subfolder but the parent folder doesn't exist ie the link leads to public/users/uploads but public/users folder does not exist.
So the first step was to create public/users folder before running php artisan storage:link
If you deleted public/storage file and has not fixed, yet. Try this composer dump-autoload.

Laravel Subfolder directory issues

My Laravel Project works fine on my local machine but not on my online server .
On my Online server i have created a directory called dev and pasted entire laravel project inside it , so now the url to access routes are domain-name/dev/profile
but fetching an uploaded image which reside inside my public/storage/upload/image is giving me an error that image could not be found !!
Any Kind of Help is Appreciated !!
I think the issue could be with the Symbolic link. Run command php artisan storage:link using CLI.
If you don't have CLI access with your c-panel, you can run the command programmatically. Add below code in your routes/web.php file:
Route::get('/sym-link', function () {
Artisan::call('storage:link');
});
And visit YOUR-DOMAIN/sym-link once.
More info: https://laravel.com/docs/master/structure#the-storage-directory
If you are using Share Hosting First Check Link Path using
readlink -f storage
and if path is incorrect remove storage from public and create new symbolic link using :
ln -s ../storage/app/public storage
To Make sure link is created use ls and see if storage is in red color or not .if it is in red color then link created successfully. :)

Move Laravel to another server error

I am trying to move a laravel project to a new server. Before moving on to the new server I am testing it on localhost.
I am getting the error like this: file_put_contents(/megashopping_dk_files/storage/framework/views/d2f79fe2bf4361439b4c43509087ad6167dfffd9.php): failed to open stream: No such file or directory
The original path in config.php was
0 => '/var/zpanel/hostdata/zadmin/public_html/megashopping_dk_files/resources/views',
which I have changed to
0 => '/megashopping_dk_files/resources/views',
I have already deleted all the files in the folders cache sessions and views in storage/framework
Again I have got two root folders with file structure like this:
1st root Folder - megashopping_dk
backend
compaign
css
fonts
img
js
library
....
2nd Root Folder - megashopping_dk_files
app
bootstrap
config
database
public
resources
storage
....
From the above what I understand is that the
contents of the First Root Folder should go in the root
and the contents of the second Root Folder should go alongwith the folder in contains.
Please advise me the right path?
TRY chmod -R guo+w storage
Few explanations
chmod -R guo+w storage : Whenever we add new service provider the cache folder for that service provider will be created in inside storage/framework . we need to make them writable from our application
php artisan optimize : to reuse all frequently used classes php will make an cached class in cache/service.php. So we if add new service we need to run it. We need to use it whenever we add new dependency without using composer.
php artisan cache:clear : clear all the above cache and remap everything
For more information read https://sentinelstand.com/article/laravel-5-optimization-commands
Remove the cached data. Go to storage\framework and remove all the files in sessions, cache and views
Once you are done with that, give proper permissions to your storage folder recursively.

Categories