现在的网盘越来越辣鸡,倒不是说体验不好,天朝带宽这么贵的情况下,30 一个月也还算划算暗示,但天天扫描网盘上的文件就不能忍了😕,毕竟不是每个人都愿意用隐私换取便利再次暗示,因此剁手购入大盘独服,自己搭建一个网盘使用。在平台的选择过程中最后纠结于 Nextcloud 和 Seafile,都搭建体验之后最终选择了 Seafile,比较 PHP 的文件管理性能略显拉跨。
Seafile 是一款开源的企业云盘,注重可靠性和性能。支持 Windows, Mac, Linux, iOS, Android 多平台文件同步或者直接挂载到本地访问。专业版也免费支持最多三个用户,足以满足要求,顺便试一下用 Docker 部署,第一次使用 Docker 也遇到了一些坑,也作为记录。
安装 Docker
可以查看官方文档说明,推荐直接使用仓库安装。
添加 Docker 的仓库:
yum install -y yum-utils
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装最新的版本 Docker:
yum install docker-ce docker-ce-cli containerd.io
运行 Docker,并用 helloworld 测试是否正确:
systemctl start docker
docker run hello-world
输入命令后将会自动运行测试镜像并打印退出
为了方便部署项目,再安装 docker-compose:
yum install docker-compose -y
部署 Seafile 专业版
从 Seafile 官网下载 docker-complse.yml 修改后上传到服务器上。
特别注意的是要修改以下几项配置:
- MySQL root 用户的密码
- 持久化存储 MySQL 数据的 volumes 目录
- 持久化存储 Seafile 数据的 volumes 目录
- 持久化存储 Elasticsearch 索引数据的 volumes 目录
接着在 docker-compose.yml
目录下使用以下命名启动 Seafile:
docker-compose up -d
按照官方文档的说法是现在就可以的输入地址访问了,可是却发现一直 502,最后使用 docker logs --since 30m [CONTAINER_ID]
查看日志,发现数据库一直连不上,连接一直被拒绝,研究了半天,这是因为在 CentOS7 上部署 Docker,网络模式采用的是 bridge
模式,启动 Docker 时,会创建一个名为 docker0
的虚拟网桥,用于宿主机与容器之间的通信。
如果 Docker 容器访问宿主机,那么 docker0
网桥将报文直接转发到本机,报文的源地址是 docker0
网段的地址。而如果 docker 容器访问宿主机以外的机器,docker 的 SNAT 网桥会将报文的源地址转换为宿主机的地址,通过宿主机的网卡向外发送。因此,当 Docker 容器访问宿主机时,如果宿主机服务端口会被防火墙拦截,那么就无法连通宿主机。
为了解决这个问题,首先使用 ifconfig
查看网络地址,编辑 /etc/firewalld/zones/public.xml
文件,添加 docker0
和使用 docker-compose
命令生成的地址段:
<rule family="ipv4">
<source address="172.18.0.0/16"/>
<accept/>
</rule>
之后使用 docker ps
查看安装的镜像,卸载 seafile 镜像重新运行 docker-comple up -d
:
docker stop [seafile ID]
docker rm [seafile ID]
docker rmi [seafile ID]
docker-comple up -d
等待安装完成之后就可以正常访问了
使用 https 访问
Seafile 自带了开启 https 的选项,用的是 Let’s encryption,这里选择使用自己的证书通过外部 Nginx 反代
server {
listen 80;
server_name domain.com;
rewrite ^(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl http2;
server_name domain.com;
ssl_certificate /[path]/full_chain.pem;
ssl_certificate_key /[path]/private.key;
#TLS 版本控制
ssl_protocols TLSv1.3;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256;
ssl_prefer_server_ciphers on;
# 开启 1.3 0-RTT
ssl_early_data on;
ssl_stapling on;
ssl_stapling_verify on;
location / {
proxy_pass https://127.0.0.1:[port]; # 设置为docker seafile映射出来的https端口
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
client_max_body_size 10m;
}
}
接下来修改 Docker 中 Nginx 的配置,如果持久化存储 Seafile 数据的目录为 /opt/seafile-data
创建 /opt/seafile-data/ssl
目录,然后拷贝证书文件和密钥文件到 ssl 目录下
接着修改配置文件 /opt/seafile-data/nginx/conf/seafile.nginx.conf
注意不要更改该配置文件的文件名:
server {
listen 80;
server_name domain;
rewrite ^ https://$host$request_uri? permanent;
server_tokens off;
}
server {
listen 443 ssl http2;
server_name domain;
ssl on;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate /shared/ssl/full_chain.pem;
ssl_certificate_key /shared/ssl/private.key;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS';
ssl_prefer_server_ciphers on;
proxy_set_header X-Forwarded-For $remote_addr;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
server_tokens off;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_read_timeout 310s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 0;
access_log /var/log/nginx/seahub.access.log seafileformat;
error_log /var/log/nginx/seahub.error.log;
}
location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://127.0.0.1:8082;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 0;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_request_buffering off;
access_log /var/log/nginx/seafhttp.access.log seafileformat;
error_log /var/log/nginx/seafhttp.error.log;
}
location /seafdav {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1200s;
client_max_body_size 0;
access_log /var/log/nginx/seafdav.access.log seafileformat;
error_log /var/log/nginx/seafdav.error.log;
}
location /media {
root /opt/seafile/seafile-server-latest/seahub;
}
# For letsencrypt
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
}
重启两处 Nginx:
systemctl restart nginx.service
docker exec -it seafile /usr/sbin/nginx -s reload
之后就可以通过 https 访问了,然后发现上传不了文件,又研究了半天,需要修改 系统管理 -> 设置
页面中的两个 url 设置的地址才行。
然后又发现登陆后就提示不安全,证书正常加载,Chrome 中查看发现引用了错误的 http 地址导致,试了很多方法都不行,最后试了下使用 rm -rf /tmp/seahub_cache
删除 seahub 的缓存文件才解决,然后又发现头像一直无法加载,发现头像的地址为 https://domian:8080
,又回头看设置中的 home-url 后面多了 8080。。去掉之后重启 docker-compose restart
后终于正常了QAQ
最后值得一提的是在 Seafile 中,当文件被删除时,组成这些文件的块数据不会立即删除,因为可能有其他文件也会引用这些块数据(用于去重功能的实现)。为了真正删除无用的块数据,还需要额外运行 “GC” 程序。GC 会自动检测到哪些数据块不再被任何文件所引用,并清除它们。
docker exec seafile /scripts/gc.sh
如果你认为这篇文章还不错,可以考虑为我充电 ⚡️