I am trying to display an image in my Laravel application. The image comes from another disk which is a samba share. I followed the configuration instructions from the Laravel Doc, here is my setup:
filesystems.php
'shop_storage' => [
'driver' => 'local',
'root' => env('SHOP_STORAGE_PATH', base_path('shop_storage')),
'dir' => [
'public' => 0777,
'private' => 0777,
]
],
My samba share is mounted into the root folder /shop_storage inside my Laravel application with the following command:
sudo mount.cifs //PATH_TO_FILE_SHARE/ARMMAG ./shop_storage -o credentials=$HOME/.smbcredentials,rw,file_mode=0777,dir_mode=0777,mfsymlinks
I correctly see all files when I open the folder.
Then, I added a Symlink from /public/storage to /shop_storage with the following command:
sudo ln -s /shop_storage /public/storage (Using full path starting at /home, removed here for privacy)
When I open /public/storage, I correctly see the symlink pointing to the samba share. If I click to open it, I see all the files. The file I am looking for exists.
The problem is when I am trying to display it in my webpage, the request return a 404.
Here is some of the things that I have tried:
<img src="{{\Storage::disk('shop_storage')->url('products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png')}}">
<img src="http://localhost:8000/shop_storage/products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png">
<img src="{{asset('products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png')}}">
<img src="{{asset('storage/products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png')}}">
What am I doing wrong?
Edit
After some try/error, I managed to get a different response with the following syntax:
<img src="{{asset('storage/shop_storage/products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png')}}">
Now, I am getting the foloowing error
You don't have permission to access /storage/shop_storage/products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png on this server.
My permission are set to 777, what could cause this?
What I ended up doing to make this work is mount my share directly into public/storage instead of using symlinks. Then any I could access the file using the laravel asset helper:
<img src="{{asset('storage/products/16/MAZJKj59EY0XQ57oKIibKr33eZ5dsqAPx44MCHHJ.png')}}">
Related
On Windows I have Xampp. My application is in Anuglar and Laravel 8
I add files to folder public in storage folder.
Configuration in filesystem.php:
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
In .env file:
APP_URL=http://localhost:8082/prftbx-crm-api/public
File in public folder:
Directory of C:\xampp\htdocs\crm-api\storage\app\public
06/25/2021 11:01 AM <DIR> .
06/25/2021 11:01 AM <DIR> ..
04/26/2021 10:57 PM 14 .gitignore
06/25/2021 11:01 AM 510 381787c3ad1442cc882ee427e93af805.txt
In Laravel I return url using method:
$fileDTO->filePath = Storage::url($fileEntity->file_name);
And in view I have address:
/storage/381787c3ad1442cc882ee427e93af805.txt
When I type url in the browser:
http://localhost:8082/crm-api/public/storage/381787c3ad1442cc882ee427e93af805.txt
I get 404, file not found
First run following command
php artisan storage:link
then you can
http://localhost:8082/storage/381787c3ad1442cc882ee427e93af805.txt
keep app url as
APP_URL=http://localhost:8082
As document says
The public disk included in your application's filesystems
configuration file is intended for files that are going to be publicly
accessible. By default, the public disk uses the local driver and
stores its files in storage/app/public.
To make these files accessible from the web, you should create a
symbolic link from public/storage to storage/app/public. Utilizing
this folder convention will keep your publicly accessible files in one
directory that can be easily shared across deployments when using zero
down-time deployment systems like Envoyer.
To create the symbolic link, you may use the storage:link Artisan
command:
php artisan storage:link Once a file has been stored and the symbolic
link has been created, you can create a URL to the files using the
asset helper:
Ref:https://laravel.com/docs/8.x/filesystem#the-public-disk
I am using Laravel 7 on Direct admin. I don't actually have access to Command Line/Terminal, and I need a Symbolic link of Storage.
I have Tried:
Route::get('/foo', function () {
Artisan::call('storage:link');
});
and also:
symlink('/domains/MyProject.com/LaravelFolder/storage/app/public', '/domains/MyProject.com/public_html');
But I am receiving this Error:
symlink() has been disabled for security reasons
My LaravelFolder is Placed before public_html.
UPDATE: I realized that the Hosting company disabled this function; I asked them to enable it, But They say: it is impossible. Do you know an alternative way to do that?
Old Solution
But I finally Solved This, It seems little bit stupid but it works:
In Ubuntu Linux I tried to create a symlink like the storage symbolic link in Laravel, with the following Command:
ln -s ../laravelFolder/storage/app/public storage
and then I compressed this symbolic link and uploaded to my public_html Folder and it works.
I hope it will be Helpful..
2022 UPDATE (New Solution)
In such cases that your projects production environment is a Linux server and you are developing your project on Windows I offer you to set up a WSL (Windows Subsystem for Linux) development environment.
This way you can simply use Linux terminal to creating a symbolic link with the following command:
// change laravelFolder with your laravel folder name
ln -s ../laravelFolder/storage/app/public storage
Here is Microsoft's quick guide to install and use WSL.
You can modify the public disk's root path to point directly public folder. Consider the below snippet;
/** /config/filesystems.php */
'disks' => [
// ...
'public' => [
'driver' => 'local',
'root' => public_path('storage'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
// ...
],
Note that this is not a best practice.
I've been trying to deploy my Laravel 6 App to the standard environment of Google App Engine the whole day, but seems like I'm just stuck at how to make cache and some "local" files to work.
This is the error I get when I try to load any page:
(1/1) InvalidArgumentException
Please provide a valid cache path.
in Compiler.php line 36
at Compiler->__construct(object(Filesystem), false)
in ViewServiceProvider.php line 92
at ViewServiceProvider->Illuminate\View\{closure}(object(Application), array())
in Container.php line 799
at Container->build(object(Closure))
in Container.php line 681
at Container->resolve('blade.compiler', array(), true)
in Application.php line 785
(...)
I followed every tip at this question, this tutorial and this issue, but anything seemed to help me.
As CACHE_DRIVER, for convenience, I'm trying to just use file, instead of database or any other else. So, my app.yaml, have the additional env_variables :
CACHE_DRIVER: file
SESSION_DRIVER: cookie
APP_STORAGE: /tmp
VIEW_COMPILED_PATH: /tmp
APP_SERVICES_CACHE: /tmp/services.php
APP_PACKAGES_CACHE: /tmp/packages.php
APP_CONFIG_CACHE: /tmp/config.php
APP_ROUTES_CACHE: /tmp/routes.php
I know that the /tmp folder is the only writable folder for the App Engine Standard Environment. With that in mind, I put the above at app.yaml, and even tried renaming /storage folder to /tmp.
I've added the following line to my bootstrap/app.php file:
$app->useStoragePath(env('APP_STORAGE', base_path() . '/tmp'));
At my composer packages, I made sure that it doesn't have facade/ignition. Also, as I can't run any command after deploy my app to Google App Engine, at composer.json I have:
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
],
"post-install-cmd": [
"composer dump-autoload",
"php artisan config:clear",
"php artisan view:clear",
"php artisan cache:clear"
]
I also tried to put at post-install-cmd php artisan storage:link, while using $app->useStoragePath(env('APP_STORAGE', base_path() . '/storage')); and the /storage folder as storage itself, but nothing worked.
I have the whole folder tree for caching at my /temp (or /storage, if this is the right way) folder:
/tmp
/framework
/cache
/data
/sessions
/testing
/views
/logs
/medialibrary
/temp
Also, besides the views not rendering, I noticed that when trying to load the favicon.ico, located at /public folder, it returns an 500 error. I am new to AppEngine, but even reading everything I can find I've been struggling to make it work. I really appreciate any help.
I figured out I had some config files published at /config, and besides changing /bootstrap/app.php, some of them had their own path to /storage folder. So, my solution was just gave up on using files cache, and for the views cache, and some other packages I had, use the path /tmp, at their respective config files. Also, I removed all cache cleaning artisan commands from composer, as I wasn't sending any cache files to deploy.
Also, I needed to make some changes in order to be able to access /public files, like some local css and js. For this, I followed these docs.
I was struggling with the same problem today and the solution was I changed the 'compiled' value in config/view.php to a root folder:
Go to root directory.
mkdir compiled_views
Change 'compiled' value to 'compiled' => realpath(base_path('compiled_views/')),
I solved it by explicitly adding the APP_STORAGE env in config/view.php:
'compiled' => realpath(env('APP_STORAGE', realpath(storage_path('framework/views')))),
(which surprises because I do have $app->useStoragePath(env('APP_STORAGE', base_path() . '/storage')); added to app.php - but it seems that it didn't yet(?) override storage_path )
I hosted laravel application on shared hosting server.
on server there are 2 folders :
1) laravelapp -> contains (app,config,database,vendor...etc folders)
2) public_html -> contains (css,js,images,storage folders)
I use below code to upload image :
if($request->hasFile('file')){
$filenameWithExt=$request->file('file')->getClientOriginalName();
$filename=pathinfo($filenameWithExt,PATHINFO_FILENAME);
$extension=$request->file('file')->getClientOriginalExtension();
$fileNameToStore=str_slug($filename,'_').'_'.time().'.'.$extension;
request()->file->move(public_path('storage/profile'), $fileNameToStore);
$image="/storage/profile/".$fileNameToStore;
}
It is successfully upload file to laravelapp/public/storage/profile folder
I have created symlink to laravelapp/public/storage with public_html/storage
in database : imagepath is saved as /storage/profile/user1.png
in blade template i use : <img src="{{$img}}" />
but imageurl :
www.mydomain.com/storage/profile/user1.png redirect to 404 page and image not displaying .
anyone please help me to solve problem.
This worked for me on a shared hosting server:
edit your config/filesystems.php and modify the public part like this
'public' => [
'driver' => 'local',
'root' => storage_path(),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
]
Notice that the storage_path() does not take any argument. Now remove storage folder from your public directory if already exists, then do:
php artisan storage:link
So, as per our discussion in comments and according to Laravel 5.5 docs, your publicly accessible files should be put in directory storage/app/public To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public.
ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage
Now you can create in your view an URL to the files using the asset helper:
echo asset('storage/file.txt');
Hope this will helps you and other users!
1) To store file in laravelapp/storage/app/public/cover/ folder
use Illuminate\Support\Facades\Storage;
$path=$request->file('cover_image')->storeAs('public/cover_images',$fileNameToStore);
2) To store file in laravelapp/public/cover/ folder
$path=request()->cover_image->move(public_path('storage/profile'), $fileNameToStore);
in shared hosting server there are 2 folders :
laravelapp and public_html
As im using 2nd way to upload image , I have solved this issue by creating symlink from laravelapp/public/storage folder to public_html/
ln -s /home/username/laravelapp/public/storage /home/username/public_html/
is posible that the symlink of your storage/public folder was wrong, you can review if this is pointing to the correct folder Use the ls -l command to check whether a given file is a symbolic link, and to find the file or directory that symbolic link point to.
ls -l /usr/bin/python
lrwxrwxrwx 1 root root 9 Apr 16 2020 /usr/bin/python -> python2.7
The first character ālā, indicates that the file is a symlink. The ā->ā symbol shows the file the symlink points to.
The rm command removes given files and directories. To delete a symlink, invoke the rm command followed by the symbolic link name as an argument:
rm symlink_name
create a new symlink to the storage public folder
php artisan storage:link
In cPanel or any live server make sure your storage folder and subfolders have the correct permission right. It should be 644, 755 or 777
I have some troubles running artisan commands in my Laravel project.
I had to change the storage directory location in my project and now, when I try to run any artisan command, it output this error :
{"error":{"type":"ErrorException","message":"file_put_contents(\/meta\/services.json):
failed to open stream: No such file or directory"
I changed the storage path in the bootstrap/path.php file and the application works just fine. (I can see the view, logs, sessions generated in my custom storage directory)
But artisan cannot find the storage/meta/services.json file.
I checked and the file exists in my storage directory.
If I create a storage/meta directory in the /appfolder it's working, but I need to use a custom storage directory.
Does artisan need a special configuration file? Am I missing something?
Thanks.
This is what contains my path file:
'app' => 'C:/wamp/www/myproject/app/',
'public' => 'C:/wamp/www/myproject/public',
'base' => __DIR__.'/..',
'storage' => 'C:/wamp/www/storage',
Are you using laravels storage_path() function to determine the path?
Before creating the file, maybe do:
$path = storage_path() . '/meta';
if (!File::exists($path)) {
File::makeDirectory($path, $mode = 0755, true, true);
}