使用 OpenWrt 软路由搭建一个低成本/单硬盘/增量备份的 Nextcloud

24 天前(已编辑)
53
2

使用 OpenWrt 软路由搭建一个低成本/单硬盘/增量备份的 Nextcloud

我在当年中考之后就了解到了 Nextcloud 这个开源的网盘,在自托管部署带来的丰盈成就感下,自己仗着一台 HK 的小鸡和阿里云 SSO 的 10G 免费空间额度,便飘飘然尝试部署了一次 Nextcloud 。

初试 & 背景

好在当时我的专业天赋并没有拖文档 Google 翻译的后腿,还是能勉强地知道哪些命令是要 Copy 的,哪些命令是不能 Copy 的,最后搞出来的 Nextcloud 也算是能成功使用的。但是使用效果非常受限于服务器的可怜带宽和空间,当时的服务器带宽为 30M 独享,剩余可用空间大约为 20G ,整体下载速度也就 4Mb/s 左右。嗯🤔,突然想起来,当时是没有使用阿里云 SSO 来扩展可用空间的,因为 Nextcloud 使用外部存储的话(如果我没理解错),外部存储的文件也必须要走 Nextcloud 的服务器分发出去,无法直接从对象存储直链下载。所以如果使用外部存储的话,多少还是有点愚蠢了,一份文件的下载不仅受到服务器带宽的限制,其下载流量消耗也是双倍的,更不用说对象储存还存在一定的延迟性能之类的问题。除这些以外,对象储存还有高昂的空间和流量费用,唯一优势也就是不会丢数据了。


新的思路

从部署背景来看,全部使用上云方案还是太吃经济了,那么有没有什么更加“简单”又经济的部署方案呢?有的兄弟,有的 所以肯定是只能使用本地机器部署更加性价比了,刚好家里网络环境需求比较多样,正好需要买一个软路由。这样加个硬盘自建网盘也就刚好是顺手的事情了。

部署过程

软路由

软路由我选择购置还算挺新的 N100 平台(康耐信 4 x 2.5G 网口),毕竟需要安装的程序也算多,所以就上了 16G 内存 + 256 固态的系统配置,外加 SATA 4T 机械硬盘挂载。系统我就选择了 ImmortalWrt ,听说软件包源更丰富一点(似乎极限条件下的网络性能也会更好一点,但是我感觉绝大部分情况下并不会达到那种极限网络负载)。

在 OpenWrt 上我必须要吐槽一下,当时我是年前安装的系统,我看 24.10版本还属于 Release Candidate 的状态,想着 docker 部署应该用不上什么很新的特性,于是自然而然就选择上了 Stable 23.05 版本。但是直到我最后把网络完全配置好、Nginx 、DDNS 以及各种杂七杂八的环境配置好后,甚至是已经进行到 docker compose up -d 的最后一部 Nextcloud 部署了,docker pull 直接报错:

docker: failed to register layer: lsetxattr security.capability /usr/bin/caddy: operation not supported.

最后,查到了相关的 PR 修复:

https://github.com/openwrt/openwrt/commit/2a1dd184b7d78d5c37a0c9a34b13ec69a4b16e04

问题大概是 OpenWrt 在编译的时候精简了或没有启用一些特性,所以导致对 EXT4 文件系统的一些特性支持不善。该 PR 在 24 年 9 月 7 日被合并,并且应该已经在 10 月 2 日 v23.05.5 Release 中修复了这一问题。可惜的是,ImmortalWrt 并没有跟进 v23.05.5 的 OpenWrt 的版本。也就导致了我在年前刷到的“最新”版 ImmortalWrt 是由 v23.05.4 版本衍生而来的。非常小的一个 0.0.1 的版本更新,导致我不得不重刷软路由系统,所有配置一切重来。😭

虽然如此,在微信上和朋友分享抱怨了几句后,当晚就把系统刷到最新的 ImmortalWrt v24.10.0 版本了,第二次重新配置也不算很慢,当天从晚上 12 点一直配置到凌晨 4 点,差不多基本环境也还原到几个小时前的状态了。顺带一提,v24.10.0 版本还更新了核显驱动一类的支持,以前的 v23.x 版本如果需要使用 CPU 核显之类的话,只能自行编译。而有核显的好处,自然就是转码一类的操作可以硬解实现了,效率提升不止一点半点。

其他基础配置

由于我这边的电信宽带并没有开放 80 443 等常规端口,所以只能不太优雅地通过非常规端口访问家庭 Web 服务。配置好 Nginx 、 DDNS 、MySQL 等基本服务,基本 Web 能力就配置好了。

另外还要把硬盘分区和挂载搞定,固态硬盘似乎有留 10%~20% 剩余空间来延长固态寿命的说法,所以我就手动保持 20% 的空间处于未分配的状态(或者也可以空间全分配,然后自己保证存在剩余空间)。

机械硬盘方面,由于 MBR 分不了大于 2T 的分区,所以在分区的时候记得在 fdisk 中使用 GPT 分区(fdisk 默认为 MBR)。RAID 阵列方面,由于是低成本,并且 Nextcloud 可以自行配置 BorgBackups 增量备份,所以就直接使用单硬盘方案了。对个人来说,4T 硬盘只要不放影视资料,基本完全满足个人资料的放置和存储备份 需求。

Nextcloud All in One

然后终于到了 Nextcloud AIO 的部署环节。因为官方做测试的环境,是直接使用 443 端口这样的常规情况,然而当像大陆家庭网络环境下要使用特殊网络端口的话,部分默认配置可能就会出错。

首次安装 AIO 容器

本人使用 Docker Compose 部署,方便后续调整配置。

第一次部署容器前,一定要修改的就是 DATA_FOLDER 的环境变量,因为我们需要把数据存储在机械硬盘,而非固态硬盘。

还有个参数似乎叫 MNT_FOLDER ,用来挂载外部存储的硬盘。实际上,使用 SATA 挂载的机械硬盘不属于外部存储,因此该环境变量不必填写。

社区容器方面,可以按需添加一个 Jellyfin 和 Memories 转码容器。

PHP 拓展的环境变量注释也可以去掉,具体拓展名我忘了,但是用处是用来在线查看图片的,还是有必要加上。

KEEP_DISABLED_APP 可以选择修改为 True ,这个的作用等会一起说。

首次启动 AIO 容器

AIO 启动后,进入相关地址进行基本配置。注意 Nextcloud 域名访问地址的填写,像我这种使用特殊端口的,需要填写 nextcloud.example.com:1111 为域名,否则未来访问会出错。这个 1111 端口相当于是 Web 服务器的 443 端口,需要根据自己的 Web 服务器配置修改。

首次安装可以选择是否开启一些官方的功能支持容器,例如 ClamAV(检测病毒,但是可能导致破解版 exe 应用无法上传)、Collabora(在线 Office 功能)等,具体配置按需自行配置。其中,在使用单服务器域名+端口的部署环境下,我不太建议直接使用 AIO 配置的 Collabora 功能。具体原因会在下一部分讲述。

Nextcloud Office (Collabora)配置

Nextcloud AIO 自动配置的 Collabora 容器中,会把 Nextcloud 的域名地址设置为 {NEXTCLOUD_DOMAIN}:443,默认使用 443 端口配置的 Nextcloud 能被正确配置,但是在本文讨论的环境下(域名+非常规端口),会被设置为 nextcloud.example.com:xxxx:443 ,从而导致 Collabora 容器无法正常运行。因此我们需要手动配置部署 Collabora 容器。

Nextcloud 实现在线 Office 功能,需要一个满足以下的通讯关系:(官方论坛的指导

可以看出 Client 需要能直接与 Collabora 服务通讯,而 Nextcloud 和 Collabora 之间也需要能直接服务通讯,并且他们通讯之间使用的域名无法改变(即 Client 访问 Nextcloud 必须通过 https://nextcloud.example.com:xxx ,Collabora 与 Nextcloud 通讯也必须通过 https://nextcloud.example.com:xxx

所以现在就出现了一个问题,即 Nextcloud 与 Collabora 都是使用 docker 容器在同一服务器进行部署的。然而容器内部的 DNS 会把 Nextcloud 和 Collabora 的域名全部解析为外部 IP 访问地址,但是容器内直接使用外部 IP 访问宿主机上的服务是无法进行通讯的。容器内访问另一容器的服务或者宿主机上的服务,只能通过 docker 容器内部 IP 地址才能进行通讯。因此我们调整容器内的 DNS 解析,来实现容器内的正确通讯。

具体配置仅需单独设置 Collabora 容器的 docker-compose.yml 配置,笔者样例配置如下:

services:
  collabora:
    image: collabora/code
    container_name: collabora
    environment:
      - domain=nextcloud\.example\.com # Nextcloud 域名正则表达式(根据实际修改)
      - extra_params=--o:ssl.enable=false --o:ssl.termination=true
      - server_name=your-collabora.example.com:xxxx # Collabora 域名(根据实际修改)
      - username=${USERNAME} # 在此配置USERNAME / PASSWORD 或在本 compose.yml 同目录创建 .env 文件储存该信息
      - password=${PASSWORD}
    cap_add:
      - MKNOD
    restart: unless-stopped
    networks:
      - nextcloud-aio
    extra_hosts:
      - "nextcloud.example.com:host-gateway" # 指向宿主机的 Nextcloud 反代服务,由于 Nextcloud 容器的内部 IP 会在每日备份后被重置而改变
                                                                                                       # 因此直接指向宿主机,使其与反代服务通讯更为合适 (根据实际修改域名)

# Nginx 反代
  nginx: 
    image: nginx:alpine
    container_name: collabora-nginx
    ports:
      - "xxxx:19080" # (根据实际修改)
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ../../nginx-proxy-manager/letsencrypt/live/npm-1/fullchain.pem:/etc/nginx/ssl/cert.crt # SSL 证书(根据实际修改)
      - ../../nginx-proxy-manager/letsencrypt/live/npm-1/privkey.pem:/etc/nginx/ssl/priv.key # SSL 证书(根据实际修改)
    depends_on:
      - collabora
    networks:
      nextcloud-aio:
        aliases:
          - your-collabora.example.com # 网络别名,让 Nextcloud 容器能 DNS 解析到 Collabora 容器地址
                                                                               # Nextcloud 容器为什么不也使用这个网络别名来实现正确解析?
                                                                               # 因为 Nextcloud 容器被 AIO 主容器配置部署,难以像 compose.yml 这样直接配置网络别名

networks:
  nextcloud-aio:
    external: true

此外,我们需要在 Nextcloud AIO Master Container 的控制面板中关闭 Collabora 的自动部署选项,然后在 docker-compose.yml 设置 NEXTCLOUD_KEEP_DISABLED_APPS: true ,如果不把这个设置为 True,Nextcloud 会在每天备份后的容器重制过程中,卸载 Nextcloud Office 应用,因此导致每次重制后都要手动重新安装 Nextcloud Office 。

最后只需要使用管理员账户在 Nextcloud Office 配置中,把 Collabora 的服务器地址配置为 https://your-collabora.example.com:xxxx 即可。

低成本的增量备份方案:BorgBackup

既然我们使用了单 4T 硬盘进行 Nextcloud 的数据储存,那么一般来说我们基本上也至少要使用一个有 4T 大小的空间来进行备份。那么思来想去,低成本的方法只能想到 Onedrive 5T 账号来实现数据的备份了。同时,Nextcloud 本身也支持一个非常优雅的增量备份方案:BorgBackup。

而 Borgbackup 主要增量备份思路为保存很多小的数据块元数据和大的压缩过后的数据块。真正备份的数据会被压缩保存为大块的数据块,然后每次增量备份进行时,仅需检索元数据(小文件)来计算新一次备份相比旧的所有备份数据需要备份的新数据。

未完待续......

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...