1 votes

Laravel Storage Link does not work in production

I am using storage_path to store my images and symbolically my storage folder for public_html

php artisan storage:link

On local, everything works fine, when I upload an image, it will upload to the storage folder and the link will appear in the public folder, but since I moved to host mode and live production, my images will upload to the storage folder, but there is nothing in my public_html/storage and I can't get them in my front-end.

/config/filesystems.php

'public' => [
  'driver' => 'local',
  'root' => storage_path('app/public/'),
  'url' => env('APP_URL').'/storage',
  'visibility' => 'public',
],

.env

FILESYSTEM_DRIVER=public

Controller Example

if ($request->hasFile('image')) {
  $image = $request->file('image');
  $filename = 'page' . '-' . time() . '.' . $image->getClientOriginalExtension();
  $location = storage_path('app/public/images/' . $filename);
  Image::make($image)->resize(1200, 600)->save($location);
  if(!empty($page->image)){
    Storage::delete('images/' . $page->image);
  }
  $page->image = $filename;            
}

1voto

Aarón Gutiérrez Points 1422

As you mentioned that you moved from one environment to another, and if for example, you compressed the project and uploaded it, unzipped it and that's it, you must create again the symbolic link from the new server:

php artisan storage:link

Since you probably now have a copy of the folder that the symbolic link was originally pointing to and not the link itself.

1voto

Bryro Points 4241

you can do it like this:
it is not necessary to define a storage for a public folder you can only reference the public_path()
this will return the path to the public folder which would be app/public now we only pass images to you public_path('/images/');
I also recommend using uniqid() in case 2 images are uploaded at the same time!

if ($request->hasFile('image')) {
  $image = $request->file('image');
  $filename = 'page' . '-' . uniqid() . time() . '.' . $image->getClientOriginalExtension();
  $location = public_path('/images/') . $filename;
  Image::make($image)->resize(1200, 600)->save($location);
  if(!empty($page->image)){
    Storage::delete('images/' . $page->image);
  }
  $page->image = $filename;            
}

0 votes

But the OP is not saving the files in the folder public rather, it is storing them in the storage/app/public that in my opinion, if they are files uploaded by users, it is better to organize the project that way and use the folder public only for files needed by the page, css, js, image assets, etc... But well, I guess that's up to each one's taste...

0 votes

@AarónGutiérrez the time to display them will be more complicated since you must first change the permissions to write in that folder after you must give access or make a get_content For security reasons I prefer to give only write permissions or public folder only!

0 votes

Not at all, when creating a project that folder public (for the sake of redundancy) within storage folder has the necessary permissions (755), so that it has access to the same as in the public which is located in root, to save images I would just record the disk in filesystems.php (or use storage_path() ) and using the facade Storage and specifying it saves you from having to indicate the complete path, to bring the image with the symbolic link it would only be necessary to use asset('storage/imagen.jpg') much more organized and uncomplicated.

0voto

You can make a path in your application where only this command is executed php artisan storage:link But first you must delete the symbolic link that you generated in your local environment. Once you delete the symbolic link access your path which should have the following code

Route::get('/turuta', function(){
  Artisan::call('storage:link');
});

HolaDevs.com

HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by:

X