之前自己组装了一台 NAS,用作私有云,解决大容量网盘,自己跑的一些小应用的问题,还计划作为软路由。 当时对网盘的选择是 NextCloud,最主要的原因就是这是有名气的 Self Hosted 网盘里,最开源的选项, 而这周末,我还是决定更换到 Seafile。
NextCloud 与 Seafile 简单体会
换到 Seafile 之后,简单用了一下,有一下几点体会:
- iOS 相册内有 10000+ 张照片,同步到网盘上
- Seafile 每次尝试同步是,会认为全部已经同步完成,然后逐步检测到未同步照片后同步
- NextCloud 每次打开,都会有大量的同步任务,然后这一万张就一直同步不完
- iOS 端用户体验
- Seafile 感觉是原生 iOS App
- NextCloud 感觉是网页版套壳
- iOS 端上传 6G+ 大文件
- Seafile 迟迟不开始,估计是在分块
- NextCloud 一直在尝试上传,但是一直失败,最后任务找不到了
- 历史版本
- 这个是意外收获,以前都不知道 NextCloud 有历史版本,用了 Seafile 之后,发现两家都有
- 文件管理
- Seafile 中有一个
资料库
的概念,目前还没体会到用处 - NextCloud 直接就是一个网盘,用起来比较简单
- Seafile 中有一个
- 元文件
- Seafile 把文件分块后存储,但是提供 fuse 和 WebDAV 用于查看文件
- NextCloud 直接存储文件,可以直接在 data 目录看到元文件和目录结构
- 部署
- Seafile 总共 3 个容器,用 Docker-compose 一起拉起来
- NextCloud 两个容器,一个 NextCloud,一个 Postgres 单独部署
最主要影响我的是第一点,同步照片,NextCloud 我尝试过一个晚上没关屏幕,NextCloud 在前台运行, 但是一晚上过去了,没传上去太多,Seafile 反而可以一次次检查,慢慢把所有照片同步上去。
另外 NextCloud 还出现一些登录失败等小问题,目前主观感觉 Seafile 会更稳定一些, 感觉 C+Python 的 Seafile 在性能上,还是比 php 的 NextCloud 性能要高一些。
最后,元文件这个问题,我主要是想把文件都放到 OneDrive
上作为云上备份,Seafile 通过 Fuse,
或者导出备份文件的方式,倒也能解决。
另外,看到一个 Issue 也蛮有意思的,主题大致是有人提出 OwnCloud 开始开发 Golang 版本的 Server 端, 用于替换以前的 php 技术栈,但是看 NextCloud 维护者们还是比较倾向与保护好当前 php 生态, 觉得目前性能上还是足够大部分人使用的。
作为 Golang 开发者,这当然不是我希望看到的
所以,后续会迁移到 Seafile,也会关注 OwnCloud 的 NG 。
Seafile 安装
作为一名容器开发,我当然是选择通过 Docker 安装,
Docker-compose
Arch Linux 直接
sudo pacman -S docker-compose
当然,Golang 的优秀体质,也可以直接在 Docker compose Release 页面直接下载二进制,
放到 PATH
下就好了。
再下载对应 docker-compose.yaml
文件,就可以启动多个容器了。
启动 Seafile
在通过 Docker 安装教程里,能看到给出的 Docker compose 配置文件,
简单说明一下,这个 docker-compose.yaml
配置了 3 个容器,分别是:
- mariadb: 开源版 MySQL
- Memcached: 加速缓存
- Seafile: 本体
我稍微修改了一下:
version: '2.0'
services:
db:
image: mariadb:10.1
container_name: seafile-mysql
restart: always
environment:
- MYSQL_ROOT_PASSWORD=Password # Requested, set the root's password of MySQL service.
- MYSQL_LOG_CONSOLE=true
ports:
- "13306:3306"
volumes:
- /host/dir/mysql:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store.
networks:
- seafile-net
memcached:
image: memcached:1.5.6
restart: always
container_name: seafile-memcached
entrypoint: memcached -m 256
networks:
- seafile-net
seafile:
image: seafileltd/seafile-mc:latest
container_name: seafile
restart: always
ports:
- "10050:80"
- "10058:8080"
# - "10053:443" # If https is enabled, cancel the comment.
volumes:
- /host/dir/seafile/:/shared # Requested, specifies the path to Seafile data persistent store.
# - /cabin/umbrella/seafile/seafdav.conf:/opt/seafile/conf/seafdav.conf
environment:
- DB_HOST=db
- DB_ROOT_PASSWD=Password # Requested, the value shuold be root's password of MySQL service.
- TIME_ZONE=Etc/GMT+8 # Optional, default is UTC. Should be uncomment and set to your local time zone.
- [email protected] # Specifies Seafile admin user, default is '[email protected]'.
- SEAFILE_ADMIN_PASSWORD=adminPassword # Specifies Seafile admin password, default is 'asecret'.
- SEAFILE_SERVER_LETSENCRYPT=false # Whether to use https or not.
- SEAFILE_SERVER_HOSTNAME=hostname.com # Specifies your host name if https is enabled.
depends_on:
- db
- memcached
networks:
- seafile-net
networks:
seafile-net:
主要修改的地方是:
- 三个容器,都加了
restart: always
: 用于每次开机,容器自启动 - 数据库容器,加了
ports: - "13306:3306"
: 用于我在宿主机上访问数据库,备份数据库 - seafile 容器,
ports
增加"10058:8080"
用于暴露webdav
端口
另外,我没有暴露 443
端口,但是作为全民 https
时代,我当然也不能拖后腿,后面会说到。
修改完配置文件之后,就可以使用命令启动 Seafile 服务端:
docker-compose up -d
-d
作为可选项,意思是后台运行,一般配置文件写的有问题的时候,
不带 -d
,前台运行能看到日志,排查错误,还是很方便的,
我们配置文件没问题,当然是直接后台启动。
WebDAV
WebDAV
简单的说,就是把文件读写都转成 HTTP
请求,然后当成一个磁盘挂载到机器上。
端口
如上文提到,在 seafile
容器里,我多暴露了一个端口 8080
,主要用户 WebDAV
,
因为 Seafile 在存储文件时,会把文件分割,再将元信息存储到数据库中,主要为了:
- 加密
- 增量同步
- 历史版本
但是带来另一个不便,就是哪怕在机器上,也没法访问备份的文件,
所以在宿主机上就需要通过 WebDAV
或者 fuse
挂载之后访问,
fuse
的话,目前是只读的,所以就用 WebDAV
了。
启用 WebDAV
Seafile 默认不启用 WebDAV
,我们需要修改配置文件:
volumes:
- /host/dir/seafile/:/shared # Requested, specifies the path to Seafile data persistent store.
这是 docker-compose.yaml
中,seafile 容器的 volumes
配置,就是把 seafile 配置文件和数据存储挂到机器上的。
在 /host/dir/seafile
这个文件夹下面, seafile/conf/seafdav.conf
这个配置文件就是 WebDAV
的配置文件,
改成:
[WEBDAV]
enabled = true
port = 8080
fastcgi = false
share_name = /seafdav
主要是:
- enabled: 开关
- port: 端口
- fastcgi: 使用进程/线程池来处理多个请求的协议,看起来我没用应该是不应该的
- share_name: http 的 uri,就是端口号后面的路径。
修改配置文件之后,重启一下容器,就可以了:
docker-compose restart seafile
HTTPS
全民 HTTPS 时代,当时不能落后,考虑到我机器上有一个 Nginx 做网关, 所以我决定在 Nginx 做 HTTPS 卸载,再把服务以 HTTP 挂到 Nginx 后面,就是这样:
申请泛域名证书
Let’s Encrypt 支持泛域名证书,可真是太方便了,如果域名托管在有插件支持的托管商,就更方便了, 就像我现在放在 Cloudflare,几个命令就能申请下来。
在官方教程这里选择用的软件,如 Nginx
,和系统,如 ArchLinux
,就能看到详细教程,
当然,下面还要选一下 wildcard
,就是通配符证书。
-
检查 DNS 托管商是否支持,cloudflare, cloudxns, linode, google 都是支持的,不支持的就得另找,或者手配了。
-
安装 certbot:
sudo pacman -S certbot certbot-nginx
-
安装 DNS 修改插件:
sudo pacman -S certbot-dns-cloudflare
,其他家的,把插件名的cloudflare
换了就可以。 -
配置 key, 这个可以在插件的说明上看到方法,如 certbot-dns-cloudflare,注意,由于 Cloudflare API 不够灵活,必须要所有 Zone 的
Zone:Zone:Read
和Zone:DNS:Edit
权限才行。- 在 API Token 页面,点
新建 Token
- 输入名字
- 选择权限
Zone:Zone:Read
和Zone:DNS:Edit
- 选择所有 Zone
- 下一步,确定,就可以了
- 在 API Token 页面,点
-
把 Token 按下面格式放到文件里
# Cloudflare API token used by Certbot dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
-
修改一下 token 文件的权限:
chmod 600 token
-
申请证书,注意
*.example.com
的*
就是泛域名certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \ -d *.example.com
配置 Nginx
上文中,已经申请到了泛域名证书,我们配置到 Nginx 上:
# seafile
upstream seafile {
server 127.0.0.1:10080;
}
server {
listen 10088 ssl;
# listen [::]:443 ssl http2 default_server;
server_name seafile.example.com;
ssl_certificate "/etc/letsencrypt/live/example.com-0001/fullchain.pem";
ssl_certificate_key "/etc/letsencrypt/live/example.com-0001/privkey.pem";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
client_max_body_size 10000m;
location / {
proxy_pass http://seafile;
add_header Real-Server $upstream_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
配置中,有几个地方是需要注意一下:
listen 10088 ssl;
中的ssl
参数标志这是个 HTTPS 端口。ssl_certificate
和ssl_certificate_key
: letsencrypt 生成的证书对client_max_body_size
客户端请求 body 大小,这个参数限制了上传文件的大小,直接配置成10G
了。
配置域名解析
目前我只在局域网里用,所以我直接把域名解析成内网地址了,简单直接, 如果家里有公网地址,seafile 需要公网访问,可以配置成 DDNS,动态配置域名地址。