why
在日常生活中我们经常需要填写一些表单,里面会有两类头疼的字段
- 不容易记住的文本字段:比如身份证有效时间、学位证编号等,这些文本我们很少使用,因此很难记忆
- 无法当场找到的文件:比如学生证、身份证等……一般是要求文件形式,如果手边刚好没有这些文件,只能对着这个字段干瞪眼了
因此一个自然的想法是:我们是否可以将这些数据结构化的存储到一个位置,需要的时候再去查找呢?那么就先梳理一下需求,看一下哪些服务符合
- 保密性:因为要存储密码还有身份证照片等信息,保密性是不可以妥协的,因此暂时不考虑现有的网盘产品
- 安全性:存储的数据必须保证安全,除了防止泄露外,还要避免因为意外消失,这么看本地的服务在安全性上稍逊一筹,同时 iCloud 就不考虑了,这个感觉不那么可靠……
- 便携性:我有很多设备,我希望他们都能够访问这些数据,因此本地存储这条路就走不通,即使使用移动硬盘也会因为文件系统不同造成很多障碍
- 低成本:当时看了一下市面的网盘产品,年费会员大多在 150-200r 之间,因此希望花费尽可能年花费少于 150r,云服务器在这方面就有点小劣势
综上所述,我打算用我的 MacBook Air 搭服务,首先数据是存储在本地硬盘上的,因此安全性应该没问题(硬盘应该不会炸吧……),其次就是公司发了新电脑,这台 MacBook Air 落灰了一段时间,搭建服务刚好产生点剩余价值🤣
开始之前

其实在这之前,我根本没接触过自建服务,不过抱着试试的心态去问了 Claude,她给出了两个解决方案,第一个是使用 Nextcloud 存储文件,第二个是使用 Vaultwarden 存储密码等信息,还给出了具体的解决方案,我会以她给出的教程为模板,写出我这次搭建的过程
顺便一提,如果你搭建时遇到了问题,也可以向 Claude 大小姐提问,这里有一个提问的小心得:如果只是将报错信息发送给她,她可能会一下子回答很多步骤,这不仅浪费 token(Claude code 和 chat 是共用额度的),还让我们不得不阅读大段文字,去里面捞取可能有价值的信息。你可以在 prompt 加上一段话:
请不要一口气给很多建议, 请你一条一条交互式的指导我, 我会给你执行结果和反馈,你再根据执行结果给出下一步建议
这个 prompt 亲测有效,不过也有弊端,我们成了终端和 Claude 的黏合剂,一直在两个窗口不停地搬运信息……因此,也许使用 Claude code 或者其他 agent 工具处理这种问题会更有效且方便,大家有兴趣可以尝试一下
搭建 Nextcloud 服务
环境准备
经过测试,这两个服务总共会占用大概 270 MB 的内存,不算很大,因此哪怕是最丐版 MacBook Air 8G 都可以轻松运行,我们只需要关注硬盘空间即可
bash
# 检查可用磁盘空间
df -h
# 安装Homebrew(如果未安装)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 安装Docker Desktop
brew install --cask docker
# 安装其他必要工具
brew install git
brew install wget
启动Docker Desktop
- 从Applications文件夹启动Docker Desktop
- 等待Docker完全启动(状态栏显示Docker图标)
- 验证Docker安装:
bash
docker --version
docker-compose --version
创建项目目录
bash
# 创建主目录
mkdir ~/nextcloud-server
cd ~/nextcloud-server
# 创建数据目录结构
mkdir -p data/nextcloud
mkdir -p data/db
mkdir -p data/backup
mkdir -p config
mkdir -p logs
# 设置权限
chmod 755 data/nextcloud
chmod 700 data/db
创建Docker Compose文件
bash
# 创建docker-compose.yml文件
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
nextcloud:
image: nextcloud:latest
container_name: nextcloud
ports:
- "8080:80"
environment:
- POSTGRES_DB=nextcloud
- POSTGRES_USER=nextcloud
- POSTGRES_PASSWORD=your_secure_password_here
- POSTGRES_HOST=db
- NEXTCLOUD_ADMIN_USER=admin
- NEXTCLOUD_ADMIN_PASSWORD=admin_password_here
- TRUSTED_DOMAINS=localhost,127.0.0.1,cloud.yourdomain.com
volumes:
- ./data/nextcloud:/var/www/html
depends_on:
- db
restart: unless-stopped
networks:
- nextcloud-network
db:
image: postgres:13
container_name: nextcloud-db
environment:
- POSTGRES_DB=nextcloud
- POSTGRES_USER=nextcloud
- POSTGRES_PASSWORD=your_secure_password_here
volumes:
- ./data/db:/var/lib/postgresql/data
restart: unless-stopped
networks:
- nextcloud-network
networks:
nextcloud-network:
driver: bridge
EOF
修改配置文件中的密码
bash
# 使用文本编辑器修改密码
nvim docker-compose.yml
# 需要修改的地方:
# - POSTGRES_PASSWORD=your_secure_password_here (两处)
# - NEXTCLOUD_ADMIN_PASSWORD=admin_password_here
# - TRUSTED_DOMAINS=localhost,127.0.0.1,cloud.yourdomain.com (替换为您的域名)
这里的编辑器可以任选,不过我就夹带点私货,使用 Neovim 谢谢喵
启动服务
bash
# 确保在项目目录中
cd ~/nextcloud-server
# 启动服务
docker-compose up -d
# 查看启动状态
docker-compose ps
# 查看日志
docker-compose logs -f nextcloud
验证安装
bash
# 等待几分钟后检查服务状态
docker-compose ps
# 检查容器日志
docker-compose logs nextcloud | tail -20
# 在浏览器中访问
open http://localhost:8080
首次登录配置
- 打开浏览器访问
http://localhost:8080
- 如果自动安装成功,使用配置的管理员账号登录
- 管理员用户名:admin
- 管理员密码:您在这一步设置的密码
至此,我们就完成了 Nextcloud 服务的搭建!(并没有)
内网穿透
上一步搭建其实只是最基本的启动服务,我们只能在局域网下通过 http://localhost:8080
来访问,毫无疑问这是很不实用的,因此我们还需要进行内网穿透,让我们的服务可以间接暴露在公网,同时分配一个域名,让访问更加简单!
首先说一下我的情况,我只有一个在 NameSilo 购买的域名,并将他分配给了我的静态博客,博客是托管在 Vercel 上的,DNS 解析在 Cloudflare 管理。
内网穿透的方法有很多,比如自己买个云服务器,或者去一些平台合租,又或者用 Cloudflare tunnel,我最开始尝试的方法是 Cloudflare tunnel
配置 Cloudflare tunnel
bash
# 安装cloudflared
brew install cloudflared
# 登录Cloudflare
cloudflared tunnel login
# 创建隧道
cloudflared tunnel create nextcloud-tunnel
# 配置路由
cloudflared tunnel route dns nextcloud-tunnel cloud.yourdomain.com(替换为您的域名)
# 启动隧道
cloudflared tunnel run nextcloud-tunnel
执行 cloudflared tunnel create nextcloud-tunnel
命令后,会输出类似的信息
bash
Tunnel credentials written to /Users/xxx/.cloudflared/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.json
Created tunnel nextcloud-tunnel with id: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
其中XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX就是 Tunnel ID。我们下一步创建配置文件时会用到
创建配置文件
# 创建配置文件(使用您的实际隧道ID)
cat > ~/.cloudflared/config.yml << 'EOF'
tunnel: c85a31c9-ce40-486f-b286-bbae1629cebe
credentials-file: ~/.cloudflared/c85a31c9-ce40-486f-b286-bbae1629cebe.json
ingress:
- hostname: cloud.yourdomain.com (替换为您的域名)
service: http://localhost:8080
- service: http_status:404
EOF
验证配置
浏览器访问 https://cloud.yourdomain.com
,如果看到 Nextcloud 登录页面,说明配置成功
后续优化
强制 HTTPS
bash
# 进入容器
docker exec -it nextcloud bash
# 配置强制HTTPS
php occ config:system:set overwriteprotocol --value=https
php occ config:system:set overwrite.cli.url --value=https://cloud.yourdomain.com
exit
端到端加密
bash
# 进入容器
docker exec -it nextcloud bash
# 启用端到端加密应用
php occ app:enable end_to_end_encryption
exit
创建新用户(可选)
我自己不想用默认的 admin 作为用户名,因此会删除旧有的账户,创建一个全新的 shellRaining 账户
bash
# 进入容器
docker exec -it nextcloud bash
# 创建新的管理员用户(替换 shellRaining 为您想要的用户名)系统会提示输入密码
php occ user:add shellRaining --display-name="shellRaining" --group="admin"
删除默认 admin 账户
bash
# 确认新账户正常工作后,删除admin账户
docker exec -it nextcloud bash
# 删除admin用户(谨慎操作!)
php occ user:delete admin
exit
双因素认证
在 Nextcloud Web 界面中:
- 点击右上角头像 → 设置
- 在"安全"部分启用双因素认证
- 使用你最喜欢的软件来设置,这里推荐一波 2FAS,在 Google Play 就可以搜到
使用其他内网穿透服务
Cloudflare 的隧道服务限速有点狠,我记得当时只有 200KB/s,这个速度可以跟百度网盘掰掰手腕了(笑),而且 SSL 握手时间会很长,让我们每次执行操作都要等一小段时间,使用体验很差,因此可以换用其他内网穿透服务,我这里选择合租,因为自己搭建实在是太奢侈了,而且如果买了云服务器,那我为什么还要做内网穿透……
我最终选择合租了香港的服务器,因为使用我的域名指向这里不需要备案,后续测试速度也可以跑满给定的限额,nice catch!!! 😄
搭建 Vaultwarden 服务
上面我们跑通了全套的 Nextcloud 服务,现在开始搭建 Vaultwarden 服务,之所以不使用 Nextcloud 管理密码,是出于专业的活就交给专业的工具来干的心理,Claude 大小姐提到:
Vaultwarden:专门管理密码、2FA密钥
Nextcloud:管理文档、照片、其他文件
这样我们就可以同时享受到文件和密码存储的服务了!
环境准备
bash
# 创建项目目录
mkdir ~/vaultwarden-server
cd ~/vaultwarden-server
# 创建数据和配置目录
mkdir -p data config backup
# 查看目录结构
ls -la
创建 Docker Compose 文件
bash
# 创建docker-compose.yml文件
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
# 基础配置
WEBSOCKET_ENABLED: "true"
SIGNUPS_ALLOWED: "true"
ADMIN_TOKEN: "your_admin_token_here"
DOMAIN: "https://cloud.yourdomain.com"
# 安全配置
ROCKET_PORT: "80"
ROCKET_WORKERS: "10"
volumes:
- ./data:/data
ports:
- "8081:80"
networks:
- vaultwarden-network
networks:
vaultwarden-network:
driver: bridge
EOF
# 查看文件内容
cat docker-compose.yml
生成随机令牌
bash
# 生成随机的管理员令牌
openssl rand -base64 48
更新配置文件中的管理员令牌
bash
# 替换配置文件中的管理员令牌
sed -i '' 's/your_admin_token_here/Q9nkRVq0PcSMa5OeWlTNqeer5dS2l\/4EV62vFFcv6v+OzAEBR2XDHh0JNxZE2XGh/' docker-compose.yml
# 验证替换是否成功
grep "ADMIN_TOKEN" docker-compose.yml
启动 Vaultwarden 服务
bash
# 启动服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看启动日志
docker-compose logs vaultwarden | tail -10
测试本地访问
bash
# 测试Vaultwarden Web界面是否可访问
curl -I http://localhost:8081
# 在浏览器中打开Vaultwarden
open http://localhost:8081
经过上面的步骤,我们成功启动了 Vaultwarden 服务,后面还需要域名指向,这部分和上面讲到的内容重叠,除了域名指向,为了方便使用,我们需要配置 Vaultwarden 的客户端 Bitwarden
配置 Bitwarden
安装浏览器插件和桌面应用(可选),比方说已经安装好了插件,我们点刚安装好的插件,可以看到底部有个选择器组件,我们点击其中“自托管”的选项,输入上面配置的服务位置和密码等信息,就可以正常使用!
应用集成
Nextcloud 有手机客户端,但是只保证了最基础的文件访问,一些应用没有集成,比如 tasks、notes 等,我们需要使用第三方的应用来连接
tasks 可以使用 tasks.org 这个应用,他支持与 Nextcloud 集成,就是需要付费,花的不多,任意等级的赞助都可以,你甚至可以选择每年 0.99 刀,为了开源生态发展,希望大家不要吝惜!
notes 可以使用 obsidian 替代,说实话 notes 这个应用真的很难用,编辑体验和 Typora、obsidian 差远了,甚至不如配置好的 Neovim(笑)
我们集成应用时,一般需要输入 WebDAV 地址,注意这里不要输入我们的域名地址,而应该加上一些后缀。假设我们的域名是 https://cloud.yourdomain.com
,那么我们就应该填入 https://cloud.yourdomain.com/remote.php/webdav/
,为什么要这么输入呢?Claude 说到:
Nextcloud 为不同的协议提供了不同的访问端点:
bashhttps://cloud.yourdomain.com/ # Web 界面 https://cloud.yourdomain.com/remote.php/webdav/ # WebDAV 协议 https://cloud.yourdomain.com/remote.php/dav/ # CalDAV/CardDAV 协议 https://cloud.yourdomain.com/ocs/v2.php/ # OCS API
在这里可以看到有两种路径
/remote.php/webdav/
:相当于一个快捷方式,会自动重定向到下面的路径/remote.php/dav/files/[用户名]/
:这是完整的 CalDAV/WebDAV 标准路径,直接指向用户文件根目录
我们一般来说选用前者即可,以 cherry studio 为例:
可以看到图中有一个 WebDAV 密码,注意这里的密码不是我们 Nextcloud 的密码,而是应用密码,具体设置位置见下图:
域名备案
上面内网穿透我使用的是香港的服务器,访问需要科学上网,而众所周知,一年中经常会有那么几段时间,梯子不是很好使,这让我们服务的稳定性大打折扣,因此我就寻思使用国内的服务器进行穿透,这就要求我们做好备案的手续
但是备案要求填写的手续非常多,我感觉折腾下来头都会大一圈,就看了一下阿里云的备案管家,我敲,好贵……
本来都快死心了,偶然看到 Linux Do 论坛里面提到可以使用备案码,这样即使不购买服务器也能拜托备案,于是着手准备,去淘宝上买了个腾讯云的备案码。
填写信息后第二天,我就收到腾讯云的电话,说是域名没有进行主体备案,需要转移到腾讯云(原来是在 NameSilo 下购买的,因为是境外服务,因此没进行主体备案),这部分花了五天时间。
域名成功转移后,重新提交被驳回的申请,又过了一天,腾讯云这边审核通过,提交管局备案,这部分又花了八天左右,最终成功管局备案!
管局备案后,收到腾讯云的邮件,说是要在二十天内进行公安备案,询问论坛中的大佬得知无须公安备案,原文如下:
GA 备案,一般都是各地通管局把 ICP 备案信息下发到备案主体所在县区 GA 局网安大队,然后网安大队工作人员会主动跟你打电话确认,有些地区是提交资料后直接通过,有些地区是要本人到网安大队参加网络培训之后才通过。
GA 备案,是被动备案的,如果没人联系你,不用理会就是了。其实比 ICP 备案更简单、快速,通过后,除非有人举报,否则一般没人管的。
备案完成后,将穿透的服务器切换到大陆,能够非常明显的感受到服务稳定性的提高!前几天一直出现的 503 错误在切换后几乎没有出现了!
总结
折腾完这一套下来,算一下成本
- 时间成本,总共 15 小时左右
- 合租内网穿透服务,每月 10 元
- 备案码,总共 8 元
- 域名转移,重新购买一年,花费 88 元
- MacBook 功耗,一般低于 10 瓦
致谢
- Linux Do 论坛
- @calm66
- @popfish
- @sakuraikaede
- CC98 论坛
- @絢瀬絵里
- @h272377502