Ubuntu 上用 Docker + rclone 部署 alist:夸克网盘 WebDAV 挂载菜鸟教程

这篇教程解决什么问题

想在 Ubuntu 上下载夸克网盘(Quark)的资源,但夸克官方没有 Linux 客户端,网页端下载大文件又慢又容易被限速。这篇教程带你用 alist + rclone(WebDAV) 的方案,把夸克网盘像本地磁盘一样挂载到 /mnt/quark,cp 一条命令就能下载。

适合人群:第一次在 Linux 上折腾网盘挂载、被网络环境卡住下载源的同学。

教程里的部署流程全部在一台 Ubuntu 24.04 实机上验证通过,包括中间踩过的坑。

背景:为什么选 alist

alist 是一个开源的「网盘中转站」:把夸克、阿里云盘、百度网盘等几十种云存储统一挂进来,对外提供 Web 界面 + WebDAV 接口。它的好处:

  • 夸克的下载链接会过期,alist 会自动刷新,你不用管
  • 多个网盘统一成一个界面管理
  • 提供 WebDAV,可以被 rclone / davfs2 等工具挂载成本地目录

踩坑记录(这部分比教程本身更值钱)

坑 1:npm 上的 alist 是「假的」

最开始的思路是从 npm 装(因为当时 GitHub 被墙,只有 npmmirror 能访问):

1
npm install -g alist --registry=https://registry.npmmirror.com

装完发现 which alist 找不到命令。查看包信息才发现,npm 上的 alist@1.0.0 是一个完全无关的旧占位包(依赖里是 core-js 和 opencollective-postinstall,跟 alist 服务端没有半点关系)。结论:npm 这条路走不通,真 alist 只在 Docker Hub / GitHub Releases。

坑 2:GitHub 全家桶被墙

逐一探测后发现这个网络环境下以下地址全部不通:

被墙 ❌ 说明
github.com alist 二进制和源码都在这
所有 ghproxy 代理 ghproxy.net、mirror.ghproxy.com 等全 000
gitee.com 想从 Gitee 镜像拉源码,也不通
goproxy.cn 想本地编译,Go 模块代理也不通

坑 3:Docker Hub 镜像源的「证书错配」

Docker 镜像不来自 GitHub,理论上能绕过。但探测各镜像源时发现更隐蔽的问题:

  • docker.m.daocloud.io(DaoCloud):镜像元数据能取到,但拉 blob 时报错
    x509: certificate is not valid for any names —— 它的 blob 存储主机证书 SAN 里只有 IP,不含主机名
  • hub.uuuadc.top:直接返回空描述符(空字符串的 SHA256),根本没在真正代理 Docker Hub,是死源
  • registry-1.docker.io(Docker Hub 直连):被墙

用 openssl s_client 看证书确认了根因:网络层 TLS 拦截导致返回的证书和主机名对不上,Docker 严格校验必然失败。把镜像主机加进 insecure-registries 也绕不过去——因为 blob 是 S3 地址,不走这个豁免。

破局点:本机有代理(Clash),给 Docker 守护进程也配上代理,直连 Docker Hub。

坑 4:davfs2 列目录报 Invalid argument

WebDAV 挂载最初用 davfs2,能挂上、cat 文件正常,但 ls 一直报:

1
ls: reading directory '/mnt/quark': Invalid argument

用 curl -X PROPFIND 直接请求 alist 发现服务端正确返回了目录列表(207 Multi-Status,子项都在),问题出在 davfs2 端解析。这是 alist WebDAV 和 davfs2 的已知兼容问题。换 rclone 后彻底解决,rclone lsd / rclone mount 列目录完全正常。

正确的部署流程

第 1 步:安装 Docker(走 Ubuntu 官方源,不碰 GitHub)

1
2
3
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y docker.io
docker --version # 验证,输出类似 Docker version 29.1.3

注意装的是 docker.io(Ubuntu 仓库里的包),不是 docker-ce(要走 Docker 官方 apt 源)。前者完全不需要访问 download.docker.com,在被墙环境更稳。

第 2 步:给 Docker 守护进程配代理(关键一步)

Docker 拉镜像的是守护进程,不是你终端里的命令。终端里 export HTTPS_PROXY 对 docker pull 无效,必须给 systemd 服务配:

1
2
3
4
5
6
7
8
9
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null <<'EOF'
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7892"
Environment="HTTPS_PROXY=http://127.0.0.1:7892"
Environment="NO_PROXY=localhost,127.0.0.1"
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

7892 是本机 Clash 的 HTTP 代理端口,按你自己的代理端口改。NO_PROXY 务必包含 localhost,否则 alist 容器间的本地通信也会被送进代理。

验证代理是否生效:

1
2
3
4
docker info --format 'HTTPProxy={{.HTTPProxy}} HTTPSProxy={{.HTTPSProxy}}'
# 应输出你配置的代理地址

docker pull hello-world # 能拉下来说明 Docker Hub 通了

第 3 步:拉取并启动 alist

1
2
3
4
5
6
7
8
sudo docker pull xhofe/alist:latest

sudo docker run -d \
--name alist \
--restart=always \
-p 5244:5244 \
-v /opt/alist:/opt/alist/data \
xhofe/alist

参数说明:

  • --restart=always:开机 / 崩溃自动重启
  • -p 5244:5244:Web 界面和 WebDAV 都走这个端口
  • -v /opt/alist:/opt/alist/data:数据持久化到宿主机

第 4 步:获取管理员密码

密码只在首次启动的日志里打印一次,之后只存哈希:

1
2
sudo docker logs alist 2>&1 | grep -i password
# Successfully created the admin user and the initial password is: xxxxxxxx

忘了也没关系,可以随时重置:

1
sudo docker exec alist ./alist admin set 你的新密码

浏览器打开 http://localhost:5244,用 admin + 上面拿到的密码登录。

第 5 步:添加存储(API 方式,不用点网页)

在网页「管理 → 存储 → 添加」里操作当然可以,但用 API 更适合脚本化。有个大坑要注意:addition 字段必须是字符串化的 JSON,传对象会报 400:

1
model.Storage.Addition: ReadString: expects " or n, but found {

正确姿势(以添加一个本地目录做测试为例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1) 登录拿 token
TOKEN=$(curl -s -X POST http://localhost:5244/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"你的密码"}' \
| python3 -c "import sys,json;print(json.load(sys.stdin)['data']['token'])")

# 2) 添加 Local 存储,挂载路径 /test
# 注意 addition 的值是一个"字符串",里面才是 JSON
BODY=$(python3 -c "
import json
add = {'root_folder_path': '/opt/alist/data/webdav_test', 'show_hidden': True}
print(json.dumps({'mount_path': '/test', 'driver': 'Local',
'addition': json.dumps(add), 'disabled': False}))")

curl -s -X POST http://localhost:5244/api/admin/storage/create \
-H "Authorization: $TOKEN" -H 'Content-Type: application/json' \
-d "$BODY"
# {"code":200,"message":"success","data":{"id":1}}

验证 WebDAV 是否通了:

1
2
3
curl -u admin:你的密码 -X PROPFIND -o /dev/null -w "%{http_code}\n" \
http://localhost:5244/dav/test
# 输出 207 就说明 WebDAV 正常

小知识:/dav 根路径在没有添加任何存储时 PROPFIND 会返回 404,这是正常的;要访问具体存储的路径,如 /dav/test。

第 6 步:用 rclone 挂载(别用 davfs2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo apt-get install -y rclone fuse3

# 允许 FUSE 挂载对其他用户可见
sudo sed -i 's/^#user_allow_other/user_allow_other/' /etc/fuse.conf

# 生成 rclone 配置(pass 字段必须用 rclone obscure 加密,不能明文)
RP=$(rclone obscure 你的密码)
mkdir -p ~/.config/rclone
cat > ~/.config/rclone/rclone.conf <<EOF
[alist]
type = webdav
url = http://localhost:5244/dav
vendor = other
user = admin
pass = $RP
EOF

先验证列表是否正常(这一步能过,说明之前 davfs2 的问题彻底绕开了):

1
2
rclone lsd alist:      # 列出所有存储,应看到 test
rclone ls alist:test # 列出 test 里的文件

挂载到本地目录:

1
2
3
4
5
6
7
8
9
sudo mkdir -p /mnt/quark
sudo rclone mount alist: /mnt/quark \
--config ~/.config/rclone/rclone.conf \
--allow-other \
--vfs-cache-mode writes \
--daemon

df -h /mnt/quark # 应看到 alist: 文件系统
ls /mnt/quark/test # 能看到 hello.txt,列表正常!

第 7 步:注册 systemd,开机自动挂载

--daemon 方式重启后会丢,做成系统服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
sudo tee /etc/systemd/system/rclone-alist.service > /dev/null <<'EOF'
[Unit]
Description=rclone mount alist WebDAV at /mnt/quark
After=network-online.target docker.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/rclone mount alist: /mnt/quark \
--config /home/你的用户名/.config/rclone/rclone.conf \
--allow-other --vfs-cache-mode writes --poll-interval 30s
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now rclone-alist
systemctl is-active rclone-alist # 输出 active 即成功

注意 --config 要写绝对路径,因为服务以 root 运行,不会去读你家目录下的默认配置。

接入夸克网盘

上面的 Local 存储只是用来验证链路。真正接入夸克:

  1. 浏览器登录 https://pan.quark.cn
  2. F12 → 网络(Network) → 随便点一个请求 → 复制请求头里 Cookie: 的完整字符串
  3. alist 网页 → 管理 → 存储 → 添加 → 驱动选 夸克网盘
  4. 挂载路径填 /quark,粘贴 Cookie,保存

之后文件就出现在 /mnt/quark/quark:

1
2
3
4
ls /mnt/quark/quark                      # 浏览
cp /mnt/quark/quark/某文件 ~/Downloads # 下载
# 或纯命令行:
rclone copy alist:quark/远程路径 ~/Downloads

Cookie 是登录凭证,不要发到公开场合;失效了去网页里重新粘贴即可。

总结

步骤 关键点
装 Docker 用 Ubuntu 源的 docker.io,别用 docker-ce
拉镜像 Docker Hub 被墙时,给守护进程配代理(systemd drop-in)
添加存储 API 的 addition 必须是字符串化 JSON
挂载 选 rclone 不选 davfs2,后者列目录有兼容问题
持久化 rclone mount 写成 systemd 服务,--config 用绝对路径

整个过程最花时间的不是部署本身,而是确认哪个下载源可达。遇到类似问题,建议先用 curl -sI 逐个探测候选源,再用 openssl s_client 看证书是否正常——很多「神秘失败」其实都是网络层的证书错配。