Search code examples
phplaravelnginxvpslaravel-livewire

Livewire image upload fails on production server


I've deployed my laravel project to vps server(ubuntu) on top of LEMP stack. Everything works fine with livewire, except image uploading.

Image uploading itself works fine on my local environment

When I try to upload image Livewire throws validation error saying The icon failed to upload.

This is becuse of Livewire can't create livewire-tmp folder. I've created that folder myself and gave it 755 permission, but still it's not working. I've also published livewire config file and changed some configurations, but still the same.

I don't know why Livewire can not create livewire-temp folder and store temporary files in it. Maybe it's something to do with nginx server configuration. So I am sharing my ngnix configuration:

server {
    listen 80 default_server;
    #listen [::]:80 default_server;

    root /var/www/html/west-hospital-admin/public;
    #root /home/west/west-hospital-admin/public;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html index.php;
    server_name _;

    location / {
        try_files $uri $uri/ /index.php$query_string;
    }
    # pass PHP scripts to FastCGI server

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
    }
}

I'm placing my project's folder and file permissions if in case is needed. It's likely to be a permission issue.

enter image description here

storage/app/public folder

Note, that Livewire itself didn't create the livewire-tmp folder. I created it and gave 755 permission to it.

enter image description here

public folder, with symbolic link to storage/app/public folder

enter image description here

I would very appreciate it if someone who knows why Livewire can not handle uploading can share their knowledge with me. 🙂


Solution

  • Solution

    1. Go to the vendor/livewire/livewire/src/Controllers/FileUploadHandler.php and comment this line abort_unless(request()->hasValidSignature(), 401);

    2. Go to the vendor/livewire/livewire/src/TemporaryUploadedFile.php and instead of this $tmpfile = tmpfile();, write this:

       $tmpfname = tempnam(sys_get_temp_dir(), '');
       $tmpFile = fopen($tmpfname, 'w');
      
    3. Go to public folder of your application and create livewire folder.(mkdir livewire) After that, go to that directory and from there you will create a symbolic link, pointing from public/livewire/preview-file to your application's storage/app/public/livewire-tmp folder:

    ln -s preview-file ../../storage/app/public/livewire-tmp

    And remember, you need to give 755 permissions to folders, that are inside storage/app/public folder.

    Explanation

    1. We need to comment that line, because it checks whether you have a ssl certificate or not. If not, it will abort the request. If you have a ssl certificate, you can skip this step.

    2. In this step, we create temporary file and give write access.

    3. Final step is just creating a symbolic link. We need to create this symbolic link because, when uploading a file, Livewire creates a temporary file with that url.