Zhi Wei 的个人博客
在OpenWRT上使用docker实现NextCloud
在OpenWRT上使用docker实现NextCloud

在OpenWRT上使用docker实现NextCloud

在不同设备之间共享文件,一直是让人头疼的问题。如果仅仅只有几台Windows那么SMB就可以完美解决,但是当你同时拥有多台不同操作系统的智能设备,那么这一切就开始变得恶心了起来。尤其是Apple与Windows,诚然苹果生态系统的AirDrop、HnadOff的体验实在是丝滑到家。但唯一的问题是iMac和Macbook对我的吸引力并不大。

国内几大网盘,不是限速就是卡空间,数据安全也得不到保障(隐私)。不如利用闲置带宽搭建私有云,数据存在本地也方便进行更加精细的管理。初步了解了一圈以后,把方向定在了NextCloud上。https://nextcloud.com/

测试部署

测试安装

通过测试,简单了解一下几种部署方式的区别,还有后期运维的复杂程度,包括https,反向代理和本地数据相关的配置,顺便学习下docker基本使用方法。

AIO docker image

我在一台Centos8虚拟机上测试了 AIO的docker镜像,确实很方便只需要跟着步骤把走就行了。通过观察docker容器可以发现,AIO是通过一个nextcloud-aio-mastercontainer容器和多个配套容器实现的。配置完成以后访问loaclhost:8080进行Setup,然后选择相关的功能,比如会提供一个反病毒的功能。

但是这个方法有个致命缺点是,你必须拥有一个在互联网可解析的域名,并且开放80,否则Setup步骤是无法进行下去的。而且在github上冗长的帮助文档让人看了头疼。

传统部署

安装基础环境apache php php-fpm mysql redis,其中比较麻烦的是配置NextCloud的php依赖模块,文档中也有详细介绍使用remi repository源对php进行安装。部署好环境时候,下载NextCloud放到apache的www目录下,然后进入Setup页面就差不多了。

客户端

NextCloud有Windows和IOS以及安卓的客户端,在Windows上安装好以后,可以看到类似OneDrive文件夹的效果(可选完全同步),IOS客户端使用起来也没有什么明显诟病。

小结

NextCloud的AIO docke耦合度太高,镜像之间的关系和配置需要花费学习成本,如果你的设备上没有部署web应用,而且有域名和SSL证书的话,部署起来还是比较省心的。而一般家庭宽带的80和443都是被严格限制的,所以我选择使用传统的方式进行部署,自己搭建环境,考虑到后期可能会需求更高的性能而更换设备,所以我打算利用docker搭建基础环境。

部署方法

考虑到功耗以及目前的数据量,我打算将NextCloud部署在我的OpenWRT上,并且使用HTTPS协议在外网访问。所以需要给OpenWRT安装docker服务,从docker hub上获取mysql、php、redis镜像进行配置,将我的数据存放在容器以外,即使后期进行迁移,或者改用Nginx只需要对容器进行调整。

关于OpenWRT

我的OpenWRT(21.02)是基于一台Intel D525的X86瘦客户机,4G/1TB存储空间,如果你的OpenWRT底层是路由器的话,不建议在上面部署,因为实际整个程序+环境跑起来,会使用接近1G内存。

如果你的OpenWRT运行在基于PVE/ESXI的虚拟环境,也不建议在上面部署,因为考虑到运行效率,多层的嵌套虚拟化不如直接新建一个虚拟机直接部署LAMP/LNMP环境。

部署NextCloud

首先创建docker、mysql和NextCloud(apache/www)的存储空间。添加mysql对应的账户权限,然后安装docker,从docker hub上拉去镜像,配置镜像然后完成安装。

划分空间&安装docker

root@OpenWrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/sda5                 7.3G     33.8M      6.8G   0% /tmp/docker_data
/dev/sda6                 1.8G      5.6M      1.7G   0% /tmp/mysql_data
/dev/sda7               356.5G     68.0M    338.3G   0% /www/nextcloud
root@OpenWrt:~# opkg update && opkg install docker dockerd luci-app-dockerman luci-i18n-dockerman-zh-cn luci-lib-docker
root@OpenWrt:~# groupadd --system --gid 999 mysql
root@OpenWrt:~# useradd --system --uid 999 --gid 999 --home-dir /tmp/mysql_data --no-create-home mysql
root@OpenWrt:~# usermod -s /bin/false mysql
root@OpenWrt:~# chown -R mysql:mysql /tmp/mysql_data/
root@OpenWrt:~# chmod -R 750 /tmp/mysql_data/
root@OpenWrt:~# useradd --system --uid 33 --gid 33 --home-dir /tmp/mysql_data --no-create-home www-data
root@OpenWrt:~# usermod -s /bin/false www-data
root@OpenWrt:~# chown -R mysql:mysql /www/nextcloud/
root@OpenWrt:~# chmod -R 750 /www/nextcloud/

拉取镜像&创建网络

根据官方给出的环境信息,在docker hub上查找对应环境的镜像,我这边采用的是php:8.2.9-apache、mysql:8.1.0、redis:7.2.0。

PlatformOptions
Operating System (64-bit)Ubuntu 22.04 LTS (recommended)Ubuntu 20.04 LTS
Red Hat Enterprise Linux 8 (recommended)
Debian 11 (Bullseye)
SUSE Linux Enterprise Server 15
openSUSE Leap 15.4CentOS Stream
DatabaseMySQL 8.0+ or MariaDB 10.3/10.4/10.5/10.6 (recommended)
Oracle Database 11g (only as part of an enterprise subscription)
PostgreSQL 10/11/12/13/14/15
SQLite (only recommended for testing and minimal-instances)
WebserverApache 2.4 with mod_php or php-fpm (recommended)
nginx with php-fpm
PHP Runtime8.0 (deprecated)
8.1
8.2 (recommended)
https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server

修改docker根目录路径到/tmp/docker_data,编辑/var/dockerd/daemon.json,或者直接在luci-docker中编辑,修改完成以后重启docker,然后拉取镜像,然后给docker配置一个新的桥接网络,名称叫做nextcloud,设置网络范围172.18.8.0/24,网关为172.18.8.1。

root@OpenWrt:~# cat /var/dockerd/daemon.json 
{ "data-root": "\/var\/docker_data\/", "log-level": "warn", "iptables": true }
root@OpenWrt:~# service dockerd restart
root@OpenWrt:~# docker pull php:8.2.9-apache && docker pull mysql:8.1.0 && docker pull redis:7.2.0
root@OpenWrt:~# docker images
REPOSITORY   TAG            IMAGE ID       CREATED       SIZE
php          8.2.9-apache   2d1146630e0c   9 days ago    503MB
redis        7.2.0          506734eb5e71   9 days ago    138MB
mysql        8.1.0          99afc808f15b   2 weeks ago   577MB
root@OpenWrt:~# docker network create --subnet=172.18.8.0/24 --gateway=172.18.8.1 nextcloud
root@OpenWrt:~# docker network ls
NETWORK ID     NAME                DRIVER    SCOPE
9e4b7f073333   bridge              bridge    local
6793e16f3437   host                host      local
6d0f11886770   nextcloud           bridge    local
b69da7f5d942   none                null      local

配置容器php-apache

创建容器,指定ip地址,在/www/nextcloud/中创建一个php测试页,并且挂载到容器的/var/www/html,创建端口映射8443和8080。先使用8080进行安装和配置,安装完成以后再配置https。

docker run \
--detach \
--volume /www/nextcloud/:/var/www/html/ \
--network nextcloud \
--ip 172.18.8.10 \
--publish 8080:80 \
--publish 8443:8443 \
--name apache \
apache:8.2.9-apache
root@OpenWrt:~# cat /www/nextcloud/index.php
<?php

phpinfo();

?>

访问http://192.168.0.1:8080,检查Apache和php是否工作正常,然后进入容器修改php参数和模块支持https://hub.docker.com/_/php,nextcloud的依赖模块可以参照https://github.com/nextcloud/documentation/blob/master/admin_manual/installation/source_installation.rst,为什么这边是github的链接?因为写到这里的时候,docs.nextcloud.com挂了,好在github上有doc仓。

下载https://github.com/mlocati/docker-php-extension-installer,使用这个项目可以轻松安装php拓展。将install-php-extensions复制到容器的/usr/local/bin/。添加alias apache=”docker exec -it apache /bin/bash”到/etc/profile,然后直接在shell中使用apache进入容器,修改php.ini的memory_limit字段,然后根据nextcloud的配置文档添加模块,打开opcache。

root@OpenWrt:~# docker cp /root/install-php-extensions apache:/usr/local/bin/
root@OpenWrt:~# apache
root@9237ba7c0d75:/var/www/html# chmod +x /usr/local/bin/install-php-extensions
root@9237ba7c0d75:/var/www/html# cd /usr/local/etc/php/conf.d
root@9237ba7c0d75:/usr/local/etc/php/conf.d# cp ../php.ini-production ./php.ini
root@9237ba7c0d75:/usr/local/etc/php/conf.d# install-php-extensions ctype curl dom gd libxml mbstring posix session SimpleXML XMLReader XMLWriter zip zlib sodium
root@9237ba7c0d75:/usr/local/etc/php/conf.d# install-php-extensions pdo_mysql bz2 intl  imap bcmath gmp exif  sysvsem imagick 
root@9237ba7c0d75:/usr/local/etc/php/conf.d# install-php-extensions apcu  memcache redis
root@9237ba7c0d75:/usr/local/etc/php/conf.d#  a2enmod rewrite
root@9237ba7c0d75:/var/www/html# cat /usr/local/etc/php/conf.d/php.ini | grep -v ";" | grep -E "memory_limit|opcache"
memory_limit = 768M
zend_extension=opcache
[opcache]
opcache.enable=1
opcache.enable_cli=1
root@9237ba7c0d75:/usr/local/etc/php/conf.d# service apache2 restart

配置容器mysql

创建容器,在docker日志查找随机密码,创建数据库nextcloud,当然你也可以指定mysql密码。参考https://hub.docker.com/_/mysql

docker run \
--detach \
--env MYSQL_RANDOM_ROOT_PASSWORD=yes \
--network nextcloud \
--ip 172.18.8.11 \
--publish 3306:3306 \
--volume /tmp/mysql_data/:/var/lib/mysql/ \
--name mysql \
mysql:8.1.0
bash-4.4# mysql -u root -p
Enter password: 
mysql> CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
mysql> quit

配置容器redis

redis基本不用配置,只需要创建容器给定ip地址即可。个人觉得可以考虑将redis直接安装在OpenWRT以提升性能。https://hub.docker.com/_/redis

docker run \
--detach \
--network nextcloud \
--ip 172.18.8.12 \
--name redis \
redis:7.2.0

安装nextcloud

将安装包解压到/www/nextcloud,注意这里不要直接出现/www/nextcloud/nextcloud/的情况,然后修改/www/nextcloud/config/config.php加入redis配置,然后进入apache容器修改默认站点配置。然后就可以通过8080进行安装了。nextcloud下载地址https://download.nextcloud.com/server/releases/latest.zip

root@9237ba7c0d75:/var/www/html# cat /etc/apache2/sites-available/nextcloud.conf   
<VirtualHost *:80>
  DocumentRoot /var/www/html/
  ServerName 172.18.8.10

  <Directory /var/www/html/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    <IfModule mod_dav.c>
      Dav off
    </IfModule>

  </Directory>
</VirtualHost>
root@9237ba7c0d75:/var/www/html# a2ensite nextcloud
Enabling site nextcloud.
To activate the new configuration, you need to run:
  service apache2 reload
root@OpenWrt:/www/nextcloud/config# cat config.php 
<?php
$CONFIG = array (
  'instanceid' => 'occqfc7uo423',
  'memcache.distributed' => '\OC\Memcache\Redis',
  'memcache.locking' => '\OC\Memcache\Redis',
  'memcache.local' => '\OC\Memcache\APCu',
  'redis' => array(
    'host' => '172.18.8.12',
    'port' => 6379,
  ),
);

如果安装完成发现nextcloud无法打开,先尝试取消redis设置,然后检查php插件是不是都安装了!尤其是redis和memcache。安装完成进入点击右上角自己的头像,选择管理设置,程序会自动检测一些安装问题。我这边显示未安装一个插件,进到apache容器安装一下就可以了。

接下来将http改成https,这里apache有一个自签的证书是没有用的,必须换成自己的域名证书。修改/etc/apache/ports.conf,修改ssl.conf,最后在修改nextcloud的配置文件/var/www/html/config/config.php加入自己的域名。

root@9237ba7c0d75:/var/www/html# a2enmod ssl
root@9237ba7c0d75:/var/www/html# cat /etc/apache2/sites-available/nextcloud-ssl.conf | grep -v "#" 
<VirtualHost *:8443>
        ServerAdmin webmaster@localhost
        ServerName 172.18.8.10:8443
        DocumentRoot /var/www/html
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
        SSLEngine on
        SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
        SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key
        <FilesMatch "\.(?:cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>
        <Directory /var/www/html/>
                Require all granted
                AllowOverride All
                Options FollowSymLinks MultiViews
                <IfModule mod_dav.c>
                        Dav off
                </IfModule>
        </Directory>
        Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>
root@9237ba7c0d75:/var/www/html# a2ensite nextcloud-ssl.conf
root@9237ba7c0d75:/var/www/html# cat /etc/apache2/ports.conf 
# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80

<IfModule ssl_module>
        Listen 8443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 8443
</IfModule>
root@9237ba7c0d75:/var/www/html# cat /etc/apache2/mods-enabled/ssl.conf | grep SSLCipherSuite
#SSLCipherSuite HIGH:!aNULL
SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM

root@9237ba7c0d75:/var/www/html# cat config/config.php 
<?php
$CONFIG = array (
  'trusted_domains' => 
  array (
    0 => '192.168.0.1:8080',
    1 => '你的域名.com:8443',
  ),

不出意外的话,这个时候你就可以使用https访问你的私有云盘了。

最后

目前使用下来,唯一的缺点就是暂时没有在apache容器中安装FFmpeg,视频的缩略图没有,其他还是挺不错,后面使用稳定了,把容器重新打包,就可以实现迁移还是很不错的。就我目前的数据量来说D525还是能应付的,等到后期明显卡顿了,就可以考虑更换设备了。

参考资料:

https://docs.nextcloud.com/

https://github.com/nextcloud/documentation

https://hub.docker.com/

https://chat.openai.com/

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注