facerecognition icon indicating copy to clipboard operation
facerecognition copied to clipboard

install doc for fpm-alpine

Open happyxhw opened this issue 1 year ago • 1 comments

any one can run this correctly ?

FROM nextcloud:18-fpm-alpine

RUN apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing dlib

RUN wget https://github.com/goodspb/pdlib/archive/master.zip \
  && mkdir -p /usr/src/php/ext/ \
  && unzip -d /usr/src/php/ext/ master.zip \
  && rm master.zip
RUN docker-php-ext-install pdlib-master

RUN apk add bzip2-dev
RUN docker-php-ext-install bz2

happyxhw avatar Jun 17 '23 16:06 happyxhw

I struggled with that yesterday as well, here's my Dockerfile to make it work on Nextcloud 26.

Note: I am using docker-compose, my Nextcloud container name is app, and you can assume every single occ command I show are ran with docker-compose exec -u www-data php occ -v.

Container

Nextcloud 26 is using PHP 8.2, and the alpine container is based on 3.18. My steps were the following:

  • Install php82-pdlib and php82-bz2 from Edge (since they are not available in 3.18)
  • Move the libraries modules .so files where the others PHP libraries are when you install them with docker-php-ext-install (in my case /usr/local/lib/php/extensions/no-debug-non-zts-20220829, that's why I'm using the find command to avoid hardcoding the timestamp in the Dockerfile)
  • Move the libraries configuration files to /usr/local/etc/php/conf.d
FROM nextcloud:26-fpm-alpine

# Add PDlib for Face Recognition
# - https://github.com/matiasdelellis/facerecognition/wiki/Docker#extend-nextcloud18-fpm-alpine
# - https://github.com/matiasdelellis/facerecognition/issues/221#issuecomment-1163527666
RUN apk add -X http://dl-cdn.alpinelinux.org/alpine/edge/testing php82-pdlib php82-bz2
RUN mv /usr/lib/php82/modules/pdlib.so $(find /usr/local/lib/php/extensions/ -type d -name 'no-debug-*' -print | head -n 1)/
RUN mv /usr/lib/php82/modules/bz2.so $(find /usr/local/lib/php/extensions/ -type d -name 'no-debug-*' -print | head -n 1)/
RUN mv /etc/php82/conf.d/pdlib.ini /usr/local/etc/php/conf.d/pdlib.ini
RUN mv /etc/php82/conf.d/00_bz2.ini /usr/local/etc/php/conf.d/bz2.ini

You can check that the extension is properly loaded with the two following commands:

  • php -v, if everything is properly loaded, you should not see any warning or error message in addition to the PHP version
# php -v
PHP 8.2.8 (cli) (built: Jul 10 2023 22:24:17) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.8, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.8, Copyright (c), by Zend Technologies
  • php -m to list all the loaded modules
# php -m | grep pdlib
pdlib

Memory and model

The other steps I had to take to make the app work where:

  • Bump the PHP memory limit. This is done through the PHP_MEMORY_LIMIT environment variable, used in the existing /usr/local/etc/php/conf.d/nextcloud.ini file.
# cat /usr/local/etc/php/conf.d/nextcloud.ini
memory_limit=${PHP_MEMORY_LIMIT}
upload_max_filesize=${PHP_UPLOAD_LIMIT}
post_max_size=${PHP_UPLOAD_LIMIT}

Check it is taken into account with php -i

# php -i | grep memory_limit
memory_limit => 2048M => 2048M
  • Set up the app memory limit with occ face:setup -M. Don't forget the unit otherwise you will be met with the error message Cannot assign less memory than the minimum.... For instance with -M 1024 instead of -M 1024M:
System memory: 31.3 GB (33617096704B)
Memory assigned to PHP: 2 GB (2147483648B)

Minimum value to assign to image processing.: 682.7 MB (715827882B)
Maximum value to assign to image processing.: 2 GB (2147483648B)

Cannot assign less memory than the minimum...
  • Set up the face recognition model with occ face:setup -m (see here https://github.com/matiasdelellis/facerecognition/wiki/Models for the models documentation. I selected model 1 because I have no clue what's better)

Temporary files

Upon checking if the background job works with occ face:background_job -t 900, I was met with the following error message:

1/8 - Executing task CheckRequirementsTask (Check all requirements)
	System: Linux
	System memory: 33617096704
	PHP Memory Limit: 2147483648
	Seems that still don't configured the image area used for temporary files.
Please read the documentation about this: https://github.com/matiasdelellis/facerecognition/wiki/Settings#temporary-files
and then configure it in the admin panel to continue

Fill an issue here if that doesn't help: https://github.com/matiasdelellis/facerecognition/issues
Task CheckRequirementsTask signalled we should not continue, bailing out

You need to configure the Temporary files value in the administration panel (https://cloud.example.com/settings/admin/facerecognition). It's subtle but when it is not configured, the page will display NaNxNaN on the right side of the slider. I picked a value in the middle, I will ajust it down if too long, or up if imprecise.

image

Local remote access and Imaginary

I'm using an Imaginary service to generate the thumbnails and testing again yielded a Host violates local access rules error. (Considering the stack trace I'm assuming this is the cause.)

yielding
	Processing image /var/www/html/data/path/to/my/image/IMG_20170416_122515.jpg
	Faces found: 0. Image will be skipped because of the following error: Host violates local access rules
	OCP\Http\Client\LocalServerException: Host violates local access rules in /var/www/html/lib/private/Http/Client/Client.php:191
Stack trace:
#0 /var/www/html/lib/private/Http/Client/Client.php(291): OC\Http\Client\Client->preventLocalAddress('imaginary:9000/...', Array)
#1 /var/www/html/custom_apps/facerecognition/lib/Helper/Imaginary.php(67): OC\Http\Client\Client->post('imaginary:9000/...', Array)
#2 /var/www/html/custom_apps/facerecognition/lib/Helper/TempImage.php(118): OCA\FaceRecognition\Helper\Imaginary->getInfo('/var/www/html/d...')
#3 /var/www/html/custom_apps/facerecognition/lib/Helper/TempImage.php(75): OCA\FaceRecognition\Helper\TempImage->prepareImage()
#4 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/ImageProcessingTask.php(200): OCA\FaceRecognition\Helper\TempImage->__construct('/var/www/html/d...', 'image/png', 710400, 512)
#5 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/Tasks/ImageProcessingTask.php(123): OCA\FaceRecognition\BackgroundJob\Tasks\ImageProcessingTask->getTempImage(Object(OCA\FaceRecognition\Db\Image))
#6 /var/www/html/custom_apps/facerecognition/lib/BackgroundJob/BackgroundService.php(137): OCA\FaceRecognition\BackgroundJob\Tasks\ImageProcessingTask->execute(Object(OCA\FaceRecognition\BackgroundJob\FaceRecognitionContext))
#7 /var/www/html/custom_apps/facerecognition/lib/Command/BackgroundCommand.php(171): OCA\FaceRecognition\BackgroundJob\BackgroundService->execute(900, true, NULL, NULL, false, false)
#8 /var/www/html/3rdparty/symfony/console/Command/Command.php(255): OCA\FaceRecognition\Command\BackgroundCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /var/www/html/3rdparty/symfony/console/Application.php(1009): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /var/www/html/3rdparty/symfony/console/Application.php(273): Symfony\Component\Console\Application->doRunCommand(Object(OCA\FaceRecognition\Command\BackgroundCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /var/www/html/3rdparty/symfony/console/Application.php(149): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 /var/www/html/lib/private/Console/Application.php(211): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 /var/www/html/console.php(100): OC\Console\Application->run()
#14 /var/www/html/occ(11): require_once('/var/www/html/c...')
#15 {main}

The fix for that was too add allow_local_remote_servers to the config.php file.

  'allow_local_remote_servers' => true,

Working setup

Finally after all those step the background job seems to run smoothly now

1/8 - Executing task CheckRequirementsTask (Check all requirements)
	System: Linux
	System memory: 33617096704
	PHP Memory Limit: 2147483648
2/8 - Executing task CheckCronTask (Check that service is started from either cron or from command)
3/8 - Executing task DisabledUserRemovalTask (Purge all the information of a user when disable the analysis.)
yielding
yielding
yielding
yielding
yielding
4/8 - Executing task StaleImagesRemovalTask (Crawl for stale images (either missing in filesystem or under .nomedia) and remove them from DB)
	Skipping stale images removal for user user1 as there is no need for it
	Skipping stale images removal for user user2 as there is no need for it
	Skipping stale images removal for user user3 as there is no need for it
	Skipping stale images removal for user user4 as there is no need for it
	Skipping stale images removal for user user5 as there is no need for it
5/8 - Executing task CreateClustersTask (Create new persons or update existing persons)
	Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
	* have 1000 faces already processed
	* or you need to have 95% of you images processed
	Use stats command to track progress
yielding
	Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
	* have 1000 faces already processed
	* or you need to have 95% of you images processed
	Use stats command to track progress
yielding
	Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
	* have 1000 faces already processed
	* or you need to have 95% of you images processed
	Use stats command to track progress
yielding
	Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
	* have 1000 faces already processed
	* or you need to have 95% of you images processed
	Use stats command to track progress
yielding
	Skipping cluster creation, not enough data (yet) collected. For cluster creation, you need either one of the following:
	* have 1000 faces already processed
	* or you need to have 95% of you images processed
	Use stats command to track progress
yielding
6/8 - Executing task AddMissingImagesTask (Crawl for missing images for each user and insert them in DB)
	Skipping image scan for user user1 that has disabled the analysis
	Skipping image scan for user user2 that has disabled the analysis
	Skipping image scan for user user3 that has disabled the analysis
	Skipping full image scan for user user4
	Skipping image scan for user user5 that has disabled the analysis
7/8 - Executing task EnumerateImagesMissingFacesTask (Find all images which don't have faces generated for them)
yielding
8/8 - Executing task ImageProcessingTask (Process all images to extract faces)
	NOTE: Starting face recognition. If you experience random crashes after this point, please look FAQ at https://github.com/matiasdelellis/facerecognition/wiki/FAQ
yielding
	Processing image /var/www/html/data/path/to/my/image/IMG_20171126_102907.jpg
	Faces found: 0
yielding
	Processing image /var/www/html/data/path/to/my/image/IMG_20170416_120413.jpg
	Faces found: 0
yielding
	Processing image /var/www/html/data/path/to/my/image/IMG_20170416_080703.jpg
	Faces found: 0
yielding
	Processing image /var/www/html/data/path/to/my/image/IMG_20170527_215050.jpg
	Faces found: 1

Background job

I haven't done this step yet but it's the next one: adding a background job: https://github.com/matiasdelellis/facerecognition/wiki/Schedule-Background-Task

My method for that is to reuse the Nextcloud cron Dockerfile and mangle it. For instance this is what I did for the previews every 30 minutes.

FROM nextcloud:26-fpm-alpine

# Change crontab content
RUN set -ex; \
    echo '*/30 * * * * php occ preview:pre-generate' > /var/spool/cron/crontabs/www-data

Simply changing the command and interval will give you a standalone container that will handle this cron task.

(@matiasdelellis if you want to integrate this into the docs you can go ahead)

gregoo avatar Aug 02 '23 09:08 gregoo