3
votes

my production server is ubuntu Ubuntu 16.04.3 LTS and I have laravel 5.5 In the route:

/var/www/forumb

my public folder is in the directory:

/var/www/forumb/public

users upload images and these are saved in:

/var/www/forumb/public/uploads/images

the images folder has 777 permissions in the images folder there are images that use the cover and these are shown normal from the views

the problem is that the images that upload the users are not seen from the views and these are in the same folder images

the cover images I can see directly from the browser like this:

http://forumb.com/uploads/images/banner1.jpeg

the user images

http://forumb.com/uploads/images/5fa7385e1542a31ab9c34419b4d914fe81a11449.jpeg

but these can not be seen, laravel returns 404 error

the only images that can be seen from the views are the ones that came up together with the framework and that are in the images folder

all the others can not be seen until I uploaded an image from filezilla to the server but can not see either

this only happens on the production server, on my localhost everything works normal

this is mi code in the view

<img class="card-img-top border-bot" src="{{ !is_null(user()->image) ? $profile_image : '/uploads/images/facebook-default-no-profile-pic.jpg' }}" class="img-fluid rounded mx-auto d-block" alt="{!! user()->nombre_empresa !!}">

this my controller

public function index()
{
    $perPage = 6;
    $page = input('page', 1);
    $baseUrl = config('app.url') . '/news-and-events';
    $items = News::whereHas('photos')->with('photos')->active()->orderBy('active_from', 'DESC')->select('news.*')->get();
    $profile_image = profile_image();
    $total = $items->count();

    // paginator
    $paginator = new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(),
        $perPage, $page, ['path' => $baseUrl, 'originalEntries' => $total]);

    // if pagination ajax
    if (request()->ajax()) {
        return response()->json(view('website.news_events.pagination')
            ->with('paginator', $paginator)
            ->render());
    }

    return $this->view('news_events.news_events')->with('paginator', $paginator)->with('profile_image', $profile_image);
}

profile_image() function

function profile_image()
{
    $image = user()->image;
    $gender = user()->gender;
    if ($image && strlen($image) > 5) {
        return '/uploads/images/' . $image;
    }
    else {
        return "/images/admin/$gender.png";
    }
}

the images are uploaded normally but not shown

3
Please post your controller function which handles the upload. - user320487
Can you verify, by looking at the filesystem in your hosting, where the files actually end up? Are you sure you're saving the images in public/uploads/images and not somewhere in the storage folder? - sisve
if I'm sure because I can see from the terminal that the files that users upload are in the images folder - jhoss
show us your <img src=" usage. - Set Kyar Wa Lar
Did you try replacing relative path to absolute with asset helper? - Ajay Makwana

3 Answers

4
votes

When you save an uploaded file to disk, Laravel puts the file in storage/app/public and not in public. So, you need to create a symbolic link to have access to these files from the web.

the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public

To create the symbolic link, you may use the storage:link Artisan command:

php artisan storage:link

https://laravel.com/docs/5.5/filesystem#the-public-disk

1
votes

The reason you are not seeing images in production is well explained by @Alexey Mezenin, in reply to your question here,

in short in laravel you have to create link to your storage folder in public folder using command php artisan storage:link then you can see images,

But the problem in production is we can not run commands directly, but we can run it programmatically,

So edit your routes/web.php file and add below lines:

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

imp note: keep in mind that if you have ran that command locally, then the storage folder is already there in public folder, so first you have to delete the public/storage folder,

and then you can run that specified route /any-route stated as in above route file.

0
votes

I suffer from this issue too. On my localhost I could upload and view images. On the server, i could upload images but can't view images on my browsers though i can see the image in public/storage. I later discover i was pointing to the image wrongly. I hope what worked for me will work for you. These are what i did.

  1. Upload project to server. In my case it was

    |-www |--laravelProject

  2. Run $ php artisan storage:link or run this script

    $exitCode = Artisan::call('storage:link', [] ); echo $exitCode; // 0 exit code for no errors.

  3. I upload my image

    $file = Storage::putFile('images', $request->file('my_image'));
    $baseUrl = url('/');
    $imagePath = $baseUrl.'/laravelProject/public/storage/'.$file;
    $input['image_path'] = $imagePath;
    $input['image_root'] = $file; //used when deleting
    MobileSlider::create($input);
    
  4. I confirm that my image is at

www/laravelProject/public/storage/images

yours could be

public_html/laravelProject/public/storage/images

  1. To access the image on my browser

http://yoursite.com/laravelProject/public/storage/images/dfdbfdbfdfdhfkhdfhnduok.png

I am not sure this is the best way, but it worked for me.