在不同设备之间共享文件,一直是让人头疼的问题。如果仅仅只有几台Windows那么SMB就可以完美解决,但是当你同时拥有多台不同操作系统的智能设备,那么这一切就开始变得恶心了起来。尤其是Apple与Windows,诚然苹果生态系统的AirDrop、HnadOff的体验实在是丝滑到家。但唯一的问题是iMac和Macbook对我的吸引力并不大。
国内几大网盘,不是限速就是卡空间,数据安全也得不到保障(隐私)。不如利用闲置带宽搭建私有云,数据存在本地也方便进行更加精细的管理。初步了解了一圈以后,把方向定在了NextCloud上。https://nextcloud.com/
测试部署
- NextCloud AIO
- 传统方法
测试安装
通过测试,简单了解一下几种部署方式的区别,还有后期运维的复杂程度,包括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。
Platform | Options |
---|---|
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 |
Database | MySQL 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) |
Webserver | Apache 2.4 with mod_php or php-fpm (recommended)nginx with php-fpm |
PHP Runtime | 8.0 (deprecated) 8.1 8.2 (recommended) |
修改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还是能应付的,等到后期明显卡顿了,就可以考虑更换设备了。