踩坑记之nextcloud安装face recognition插件


背景

在我的nas上跑着个运行了N年的nextcloud的docker镜像,这两天鼓捣插件,准备装个人脸识别耍一耍。

本文主要记录下踩坑过程,安装和使用方法在最后一节。

Nextcloud中直接安装

Nextcloud->apps->Multimedia->facerecognition,直接安装,会提示缺少相关组件。

•   This app cannot be installed because the following dependencies are not fulfilled:  

o   The library pdlib is not available.  

o   The library bz2 is not available.  

搜了下,这俩是php扩展,没法直接apt install,于是我们来到项目官方文档。

https://github.com/matiasdelellis/facerecognition/wiki/Installation

简单试了下裸机安装的方法,不出所料失败了。由于我是使用docker安装的,这里直接尝试使用docker build的方法安装依赖。

构建docker image

以前一直是直接用别人build好的image,对dockerfile这一套还真不熟。硬着头皮学习下,提高下姿势水平。

前面的官方文档里面提过可以使用docker way,我们就按他的文档来。

https://github.com/matiasdelellis/facerecognition/wiki/Docker

鉴于这个文档让我踩了不少坑,这里我一定要贴一份原文上来(无奈的笑

#
# Use a temporary image to compile and test the libraries
#
FROM nextcloud:apache as builder

# Build and install dlib on builder

RUN apt-get update ; \
    apt-get install -y build-essential wget cmake libx11-dev libopenblas-dev

ARG DLIB_BRANCH=v19.19
RUN wget -c -q https://github.com/davisking/dlib/archive/$DLIB_BRANCH.tar.gz \
    && tar xf $DLIB_BRANCH.tar.gz \
    && mv dlib-* dlib \
    && cd dlib/dlib \
    && mkdir build \
    && cd build \
    && cmake -DBUILD_SHARED_LIBS=ON --config Release .. \
    && make \
    && make install

# Build and install PDLib on builder

ARG PDLIB_BRANCH=master
RUN apt-get install unzip
RUN wget -c -q https://github.com/matiasdelellis/pdlib/archive/$PDLIB_BRANCH.zip \
    && unzip $PDLIB_BRANCH \
    && mv pdlib-* pdlib \
    && cd pdlib \
    && phpize \
    && ./configure \
    && make \
    && make install

# Enable PDlib on builder

# If necesary take the php settings folder uncommenting the next line
# RUN php -i | grep "Scan this dir for additional .ini files"
RUN echo "extension=pdlib.so" > /usr/local/etc/php/conf.d/pdlib.ini

# Install bzip2 needed to extract models

RUN apt-get install -y libbz2-dev
RUN docker-php-ext-install bz2

# Test PDlib instalation on builder

RUN apt-get install -y git
RUN git clone https://github.com/matiasdelellis/pdlib-min-test-suite.git \
    && cd pdlib-min-test-suite \
    && make

#
# If pass the tests, we are able to create the final image.
#

FROM nextcloud:apache

# Install dependencies to image

RUN apt-get update ; \
    apt-get install -y libopenblas-base

# Install dlib and PDlib to image

COPY --from=builder /usr/local/lib/libdlib.so* /usr/local/lib

# If is necesary take the php extention folder uncommenting the next line
# RUN php -i | grep extension_dir
COPY --from=builder /usr/local/lib/php/extensions/no-debug-non-zts-20180731/pdlib.so /usr/local/lib/php/extensions/no-debug-non-zts-20180731/

# Enable PDlib on final image

RUN echo "extension=pdlib.so" > /usr/local/etc/php/conf.d/pdlib.ini

# Increse memory limits

RUN echo memory_limit=1024M > /usr/local/etc/php/conf.d/memory-limit.ini

# Pdlib is already installed, now without all build dependencies.
# You could test again if everything is correct, uncommenting the next lines
#
# RUN apt-get install -y git wget
# RUN git clone https://github.com/matiasdelellis/pdlib-min-test-suite.git \
#    && cd pdlib-min-test-suite \
#    && make

#
# At this point you meet all the dependencies to install the application
# If is available you can skip this step and install the application from the application store
#
ARG FR_BRANCH=master
RUN apt-get install -y wget unzip nodejs npm
RUN wget -c -q -O facerecognition https://github.com/matiasdelellis/facerecognition/archive/$FR_BRANCH.zip \
  && unzip facerecognition \
  && mv facerecognition-*  /usr/src/nextcloud/facerecognition \
  && cd /usr/src/nextcloud/facerecognition \
  && make

开始前的小tips

开启详细输出

build的时候最好把详细输出打开,有什么错误可以一目了然。

方法如下:

export DOCKER_BUILDKIT=1

docker build的层缓存

docker build对image的每一个build成功的层,会将层缓存起来,下次build直接取build的结果。这很好理解,避免重复计算节约资源嘛。但是,这个build成功,是以命令返回值为0做判断的。

也就是说,如果在build时,某一层build失败了,恰巧这个dockerfile的作者又很坑爹的return了0,那很遗憾,你就永远会得到build失败的中间层,在后面的build中,极大概率会出现各种诡异的错误(我就莫名其妙的排查了好长时间)。

因此,在build后如果image不能正常工作,之前又进行过失败的build,这里可以清下image缓存试试。

方法如下:

docker builder prune

或者,强制指定build时不使用cache。

docker build --no-cache --tag myimage:version .

好了,下面开始现学现卖,开始踩坑之旅。

配置dockerfile

#创建个空白文件夹,把刚才的dockerfile贴进去  

mkdir richnextcloud  

cd nextcloud  

vi Dockerfile  

#开启build详细输出  

export DOCKER_BUILDKIT=1  

#开始build  

docker build --no-cache -t mynextcloud . 

报错1

=> ERROR [stage-1 4/7] COPY –from=builder /usr/local/lib/php/extensions/no-debug-non-zts-20180731/pdlib.so /usr/local/lib/php/extensions/no-de  0.0s  

——  

 > [stage-1 4/7] COPY –from=builder /usr/local/lib/php/extensions/no-debug-non-zts-20180731/pdlib.so /usr/local/lib/php/extensions/no-debug-non-zts-20180731/:  

——  

failed to compute cache key: failed to walk /mnt/docker_image/tmp/buildkit-mount691874994/usr/local/lib/php/extensions/no-debug-non-zts-20180731: lstat /mnt/docker_image/tmp/buildkit-mount691874994/usr/local/lib/php/extensions/no-debug-non-zts-20180731: no such file or directory  

研究了下,这个Dockerfile使用了multistage build的构建方法,先build一个叫builder的临时镜像,验证没问题后,把so文件单独copy到我们要构建的image里,避免空间的浪费。

这个报错信息是说,在builder这个image里面没找到“no-debug-non-zts-20180731/pdlib.so”这个文件。

这是为什么呢?我们回去翻翻,确实没有这个目录。难道现在so不在了?

找个空白的nextcloud镜像,根据Dockerfile,执行下安装命令试试。

export PDLIB_BRANCH=master  

apt-get install unzip  

wget -c -q https://github.com/matiasdelellis/pdlib/archive/$PDLIB_BRANCH.zip \  
    && unzip $PDLIB_BRANCH \  
    && mv pdlib-* pdlib \  
    && cd pdlib \  
    && phpize \  
    && ./configure \  
    && make \  
    && make install  

看到这里版本号有个master,就有种不祥的预感,搞不好人家更新了主版本,绝对路径变了。

果不其然,安装完输出如下。

  1. Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20200930/  

好吧破案了,确实是路径变了,不过变的是php的版本。php版本的变更又导致了extension的路径变更。靠!就为啥要写绝对路径嘛!

解决方法:将Dockerfile里面的no-debug-non-zts-20180731替换成no-debug-non-zts-20200930

报错2

执行到step15又出错了

  1. Step 15/19 : COPY –from=builder /usr/local/lib/libdlib.so* /usr/local/lib  
  2. When using COPY with more than one source file, the destination must be a directory and end with a /  

这个错误比较直白,把目录后面加个斜杠好了。

懒得研究为啥,就当作他们写这个文档时, Dockerfile对路径的校验不严格好了。

还是找不到bz2?

Build好了image,建一个新的nextcloud镜像试试水。

docker run -d --name='nextcloudtest' -p 19988:80 richnextcloud  

嗯?还是找不到bz2?

继续排查。前面折腾一通对这个Dockerfile大概也玩明白了,我们再来看一遍代码吧(简略版)。

FROM nextcloud:apache as builder

# ......省略

RUN apt-get install -y libbz2-dev
RUN docker-php-ext-install bz2

FROM nextcloud:apache

# ......省略

# Install dlib and PDlib to image

COPY --from=builder /usr/local/lib/libdlib.so* /usr/local/lib

# If is necesary take the php extention folder uncommenting the next line
# RUN php -i | grep extension_dir
COPY --from=builder /usr/local/lib/php/extensions/no-debug-non-zts-20180731/pdlib.so /usr/local/lib/php/extensions/no-debug-non-zts-20180731/
# ......省略

我们看到,作者的思路是在builder这个镜像里面编译测试,把so文件copy到新镜像里。

找到问题了吧。好嘛,你只复制了libp,根本没复制bz2.so!

前面那个版本号好说,就当是文档更新不及时。这个bz2没复制,根本就跑不起来嘛!

不得不吐槽下了,写到这里,我非常怀疑他们写这个文档有没有自己测试过……

解决方案:

添加如下两行到Dockerfile中。

# Copy bz2.so  
COPY --from=builder /usr/local/lib/php/extensions/no-debug-non-zts-20200930/bz2.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/  
# Enable PDlib and bz2 on final image  
RUN echo "extension=bz2.so" > /usr/local/etc/php/conf.d/bz2.ini  

完成构建&验证

配置php最大内存

按照官方文档(link)的说明,推荐的模型至少需要1G的内存。

这个好说,创建container的时候加上环境变量就行

-e PHP_MEMORY_LIMIT="1024M"   

安装插件

经过前面一番折腾,app里面的face recognition终于可以enable了

插件初始化

这里需要命令行下手动初始化插件内存和模型

# 使用模型1(默认模型)  
docker exec -it nextcloud php occ face:setup -m 1  
# 配置最大使用内存1G  
docker exec -it nextcloud php occ face:setup -M 1G  

手动扫描前,需要在配置页面配置下Temporary files大小。

Setting->Administration->Face Recognition

命令行扫描照片

# 手动扫描  
docker exec -u www-data nextcloud php -f occ face:background_job  

OK,终于没有报错信息了,我们也终于在UI里看到了扫描的进度。

扔着里慢慢扫吧,回头再看看效果

小结一下

OK,折腾一圈,终于跑通了。学习了一圈docker build的用法,顺便给facerecognition的文档捉了虫。

这个故事告诉我们,能用现成的就用现成的,别自己瞎折腾T.T

脱水版

安装方法

Build自己的docker image

#我把Dockerfile上传到github了,这里直接pull就好  
git pull https://github.com/utopiafar/nextcloud.git  
cd nextcloud
#开启build详细输出  
export DOCKER_BUILDKIT=1  
#开始build  
docker build --no-cache -t mynextcloud . 
# run一个container
docker run -d -e PHP_MEMORY_LIMIT="2048M" –name=’nextcloud’ mynextcloud

使用大神build好的image

懒得折腾的话,当然是直接使用别人build好的image了。

在网上google一番,发现这个老哥的github。

https://github.com/iamklaus/nextcloud/blob/main/apache/Dockerfile

老哥集成了不少使用的包,可以直接用了。

docker run -d -e PHP_MEMORY_LIMIT="2048M" –name=’nextcloud’iamklaus/nextcloud  

初始化插件&手动扫描

  1. # 初始化插件  
  2. # 使用模型1(默认模型)    
  3. docker exec -it nextcloud php occ face:setup -m 1    
  4. # 配置最大使用内存1G  
  5. docker exec -it nextcloud php occ face:setup -M 1G

手动扫描前,需要配置下Temporary files大小

Setting->Administration->Face Recognition

命令行手动扫描

# 手动扫描  

docker exec -u www-data nextcloud php -f occ face:background_job  


——此处是内容的分割线——

除非注明,否则均为广陌原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.utopiafar.com/2022/02/15/install_facerecognition_in_nextcloud/

码字不易,如果觉得内容有帮助,欢迎留言or点赞!

, ,

发表回复

您的电子邮箱地址不会被公开。