akmolina28 / last-watch-ai

Self-hosted computer vision automation application
MIT License
64 stars 9 forks source link

Interface returning error code 500 #2

Closed depuits closed 3 years ago

depuits commented 3 years ago

After running the setup and browsing to the url on port 8080 the server returns error 500. The body is empty and the nginx and php container logs only log the return without error message.

What could this issue be and where can I find a more detailed log for to debug this problem?

akmolina28 commented 3 years ago

Check ./src/storage/logs/laravel.log

In the php container it would be /var/www/app/storage/logs/laravel.log

You can also turn on debugging to show the error page instead of getting a blank response. To do that you have to set APP_DEBUG=true in ./src/.env. After you set the flag you may have to clear the config cache by running docker-compose run --rm artisan config:clear

depuits commented 3 years ago

This is what this log says. But only after placing an image in the directory. When enabling the APP_DEBUG I still don't get any errors visualized in the browser.

I did notice that the directory doesn't match the one set in the .env file so something might be wrong there. The path set is /mnt/cctv.

[2020-11-06 09:01:28] production.ERROR: getimagesize(/var/www/app/storage/app/public/events/frontGate/2020-11-06/15-01-23.jpg): failed to open stream: No such file or directory {"exception":"[object] (ErrorException(code: 0): getimagesize(/var/www/app/storage/app/public/events/frontGate/2020-11-06/15-01-23.jpg): failed to open stream: No such file or directory at /var/www/app/app/Factories/DetectionEventModelFactory.php:24)
[stacktrace]
#0 [internal function]: Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(2, 'getimagesize(/v...', '/var/www/app/ap...', 24, Array)
#1 /var/www/app/app/Factories/DetectionEventModelFactory.php(24): getimagesize('/var/www/app/st...')
#2 /var/www/app/app/Jobs/ProcessWebhookJob.php(21): App\\Factories\\DetectionEventModelFactory::createFromImageFile('frontGate/2020-...', Object(Illuminate\\Support\\Carbon))
#3 [internal function]: App\\Jobs\\ProcessWebhookJob->handle(Object(Illuminate\\Support\\Carbon))
#4 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): call_user_func_array(Array, Array)
#5 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#6 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#7 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(39): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#8 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(596): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#9 /var/www/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(94): Illuminate\\Container\\Container->call(Array)
#10 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Bus\\Dispatcher->Illuminate\\Bus\\{closure}(Object(App\\Jobs\\ProcessWebhookJob))
#11 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(App\\Jobs\\ProcessWebhookJob))
#12 /var/www/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php(98): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#13 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(83): Illuminate\\Bus\\Dispatcher->dispatchNow(Object(App\\Jobs\\ProcessWebhookJob), false)
#14 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Queue\\CallQueuedHandler->Illuminate\\Queue\\{closure}(Object(App\\Jobs\\ProcessWebhookJob))
#15 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(App\\Jobs\\ProcessWebhookJob))
#16 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(85): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#17 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(59): Illuminate\\Queue\\CallQueuedHandler->dispatchThroughMiddleware(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Object(App\\Jobs\\ProcessWebhookJob))
#18 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(98): Illuminate\\Queue\\CallQueuedHandler->call(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Array)
#19 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(356): Illuminate\\Queue\\Jobs\\Job->fire()
#20 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(306): Illuminate\\Queue\\Worker->process('database', Object(Illuminate\\Queue\\Jobs\\DatabaseJob), Object(Illuminate\\Queue\\WorkerOptions))
#21 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(132): Illuminate\\Queue\\Worker->runJob(Object(Illuminate\\Queue\\Jobs\\DatabaseJob), 'database', Object(Illuminate\\Queue\\WorkerOptions))
#22 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(112): Illuminate\\Queue\\Worker->daemon('database', 'default', Object(Illuminate\\Queue\\WorkerOptions))
#23 /var/www/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(96): Illuminate\\Queue\\Console\\WorkCommand->runWorker('database', 'default')
#24 [internal function]: Illuminate\\Queue\\Console\\WorkCommand->handle()
#25 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): call_user_func_array(Array, Array)
#26 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(37): Illuminate\\Container\\BoundMethod::Illuminate\\Container\\{closure}()
#27 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(95): Illuminate\\Container\\Util::unwrapIfClosure(Object(Closure))
#28 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(39): Illuminate\\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\Application), Array, Object(Closure))
#29 /var/www/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(596): Illuminate\\Container\\BoundMethod::call(Object(Illuminate\\Foundation\\Application), Array, Array, NULL)
#30 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(134): Illuminate\\Container\\Container->call(Array)
#31 /var/www/app/vendor/symfony/console/Command/Command.php(258): Illuminate\\Console\\Command->execute(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#32 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(121): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Illuminate\\Console\\OutputStyle))
#33 /var/www/app/vendor/symfony/console/Application.php(916): Illuminate\\Console\\Command->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#34 /var/www/app/vendor/symfony/console/Application.php(264): Symfony\\Component\\Console\\Application->doRunCommand(Object(Illuminate\\Queue\\Console\\WorkCommand), Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#35 /var/www/app/vendor/symfony/console/Application.php(140): Symfony\\Component\\Console\\Application->doRun(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#36 /var/www/app/vendor/laravel/framework/src/Illuminate/Console/Application.php(93): Symfony\\Component\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#37 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(129): Illuminate\\Console\\Application->run(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#38 /var/www/app/artisan(37): Illuminate\\Foundation\\Console\\Kernel->handle(Object(Symfony\\Component\\Console\\Input\\ArgvInput), Object(Symfony\\Component\\Console\\Output\\ConsoleOutput))
#39 {main}
"} 
akmolina28 commented 3 years ago

Ok this looks to be a new issue. The detection job can't see the file. This might have something to do with using a mount folder, or with the permissions on that folder.

In my experience with Windows, the first time I run the containers it pops up a prompt to give docker access to the folders that need to be shared. I recall in another version of Docker I had to go into the settings and explicitly share each folder. Without knowing much about what docker looks like in linux, I would suggest looking at your settings to see if you can share the paths that docker needs access to, like ./src, ./mysql, and your mounted directory.

When I have some time this weekend I'll spin up a new debian install and try to get it working. I'm pretty sure there are just some quirks in the Linux file system that have to be accounted for.

akmolina28 commented 3 years ago

This is definition a file permission problem. I ran into the same issue on a fresh Ubuntu install. I did a chmod 777 on the src folder just to see what happened, and it fixed the problem.

Once I figure out the correct permission structure I'll write up some install instructions for Ubuntu.

akmolina28 commented 3 years ago

@depuits I was able to get everything working in Ubuntu. Here are the steps:

  1. Download/unzip latest release
curl -s https://api.github.com/repos/akmolina28/last-watch-ai/releases/latest \
| grep "browser_download_url" \
| cut -d : -f 2,3 \
| tr -d \" \
| wget -qi -

unzip [zip file] -d .

cd last-watch-ai
  1. Configure input folder
mkdir ~/aiinput

nano .env

Set WATCH_FOLDER to /home//aiinput

  1. Set file permissions for the web server. This will fix the 500 errors.
sudo chown -R www-data:www-data src
sudo find src -type f -exec chmod 644 {} \;
sudo find src -type d -exec chmod 755 {} \;
  1. Start the containers
sudo docker-compose up -d --build site
  1. Recreate the symlink for the public storage folder to fix an issue with serving the public image files. This is a temporary workaround until I can create a new release that fixes this problem.
sudo docker exec -it lw_php rm /var/www/app/public/storage
sudo docker exec -it lw_php php artisan storage:link

Now you should be able to visit the website on port 8080 and you can drop images into ~/aiinput to test the AI. I set up the aiinput folder as a samba share to make testing easier.

depuits commented 3 years ago

Thanks, using these steps the web interface is now working.

depuits commented 3 years ago

In one of my install is had to use sudo chmod -R 777 src in stead of sudo chown -R www-data:www-data src

because I did not have a www-data user on that install.

akmolina28 commented 3 years ago

Which OS are you using? I'd like to see if I can reproduce this. I tested using a fresh Ubuntu install and I didn't run into this problem. I know installing Nginx will create the www-data user, so I'm thinking maybe my version of Ubuntu included Nginx out of the box?

I'm still new to docker but I know it's common to set up users and roles for docker images. This is something I plan on looking in to... eventually :)

depuits commented 3 years ago

For my production I'm using debian (which had the www-data user) and for testing I am running on manjaro.

akmolina28 commented 3 years ago

Ok, I figured this out. Adding this line to the php dockerfile

RUN usermod -u 1000 www-data && groupmod -g 1000 www-data

completely removes the need to do any chown or chmod on the files.

Now you can just clone, build, and bring up the containers and everything works. I tested in debian and arch linux.

depuits commented 3 years ago

This works perfectly on my debian install