在v6下搞docker,别的还好,遇到anytype这种就炸了。
https://anytype.io/
https://github.com/grishy/any-sync-bundle/tree/main
测试了1G内存的🐥会非常勉强,需要做更精细的控制。(于是放弃)
而2G内存如果用官方的yml安装,也可能在大量同步笔记时候炸鸡。所以搞了这个‘高可用’方案。
【原项目建议最小内存1G--适用于非常轻量的个人使用,且限制了数据库缓存(WiredTiger Cache)的情况下。在这种规格下,建议通过 command 限制 MongoDB 的缓存大小】
为啥anytype这么特别? (踩了v6小鸡安装的坑)
- 协议偏好:TCP 稳健派 vs UDP 激进派
其他程序:几乎 100% 依赖 TCP。TCP 协议栈在内核层面已经进化了数十年,能够非常聪明地处理包大小(MSS 协商)、重传和排序。
Anytype:为了追求极速同步,它优先使用 QUIC (基于 UDP)。
IPv6 的致命点:IPv6 对 UDP 的包大小(MTU)极其敏感。
TCP 发现包太大会自动缩小(MTU 路径发现)。
UDP 发现包太大(比如图片切块),在 IPv6 下直接丢弃,且不一定会给发送端任何反馈。这就是为什么你发现“文字能通,图片永远转圈”。
- 身份绑定的复杂性 (Node Discovery)
其他程序:DNS 告诉你是哪个 IP,你连上就行了。
Anytype:服务器会生成一个 PeerID。它不只是看 IP,它会把 IP、端口、协议和 PeerID 全部打包在一起。
IPv6 的干扰:如果你的 VPS 有多个 IPv6 地址(这在 IPv6 环境中很常见),Anytype 可能会错误地选择了那个“不可达”的临时地址进行广播,导致客户端拿到了错误的联系方式。
...
最后还是用docker的host模式,加上一些限制内存的措施,确保在2G内存上安全稳定。
附上docker-compose.yml 再加个彩蛋。
version: '3.8'
services:
anytype-bundle:
image: ghcr.io/grishy/any-sync-bundle:minimal
container_name: anytype-bundle
restart: always
network_mode: "host"
environment:
- ANY_SYNC_BUNDLE_INIT_EXTERNAL_ADDRS=YOURdomain1.com,YOURDOMAIN2.com
- ANY_SYNC_BUNDLE_INIT_MONGO_URI=mongodb://127.0.0.1:27017/
- ANY_SYNC_BUNDLE_INIT_REDIS_URI=redis://127.0.0.1:6379/
- ANY_SYNC_BUNDLE_INIT_TCP_LISTEN_ADDR=[::]:33010
- ANY_SYNC_BUNDLE_INIT_UDP_LISTEN_ADDR=[::]:33020
- ANY_SYNC_BUNDLE_LOG_LEVEL=info
volumes:
- ./data:/data
# ─── 核心修改:等待数据库健康后再启动 ───
depends_on:
mongodb:
condition: service_healthy
mongodb:
image: mongo:6.0
container_name: anytype-mongodb
restart: always
network_mode: "host"
# 这里通过命令直接限制 WiredTiger 缓存为 512MB
command: ["mongod", "--replSet", "rs0", "--wiredTigerCacheSizeGB", "0.5", "--bind_ip_all"]
deploy:
resources:
limits:
memory: 1G # 容器总内存上限
volumes:
- ./mongo-data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 15s
timeout: 5s
retries: 5
redis:
image: redis/redis-stack-server:latest
container_name: anytype-redis
restart: always
network_mode: "host"
deploy:
resources:
limits:
memory: 256M
volumes:
- ./redis-data:/data
注意,用host模式必须做好防护。docker内部的端口尤其是数据库不能暴露在公网。
#手动运行下数据库初始化(手动激活副本集)
docker exec -it anytype-mongodb mongosh --eval "rs.initiate({_id: 'rs0', members: [{_id: 0, host: '127.0.0.1:27017'}]})"
结果应该是: { ok: 1 }
实时同步依赖 (Change Streams)
Anytype 是一个“实时协作”软件。当你在一台设备上修改笔记时,其他设备需要立刻收到通知。
Anytype 的机制:Anytype 的后端(Any-Sync)使用了 MongoDB 的 Change Streams(变更流) 功能。
这是一种允许应用程序“监听”数据库实时变化的机制。
MongoDB 的限制:MongoDB 规定,Change Streams 功能只能在“副本集(Replica Set)”模式下使用。
普通的“单机模式(Standalone)”是不支持监听实时变化的。
如果使用 All-in-One(全内置) 镜像),在内部有一个启动脚本,它会在后台悄悄帮你执行 rs.initiate(),
用户感觉不到它的存在。
但现在的情况是:为了适配你的 VPS 内存并保证稳定性,我们手动拆分了架构,
使用了 Minimal 镜像 + 官方 MongoDB 镜像。
官方标准 MongoDB 镜像(mongo:6.0)的设计原则是“纯净”,它不会自动帮你初始化副本集,
因为它不知道你是否想加入现有的集群。
nano /etc/default/ufw
确保其中的 IPV6=yes
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 33010/tcp
sudo ufw allow 33020/udp
sudo ufw allow ssh #或者sudo ufw allow 2222/tcp
sudo ufw enable
sudo ufw status verbose
#应该只有下面这几个
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere
33010/tcp ALLOW IN Anywhere
33020/udp ALLOW IN Anywhere
22/tcp (v6) ALLOW IN Anywhere (v6)
33010/tcp (v6) ALLOW IN Anywhere (v6)
33020/udp (v6) ALLOW IN Anywhere (v6)
多设备同步迅速!

好文。我都是用2c4g的机子部署的。

@Cosmossofa #1 mongo太炸内存了 我在1G上各种失去同步的响应 不知道官方指导说的1G内存怎么跑的(有swap也不行啊)
本地优先是我需要的。小鸡炸了也没事。
要保护好client-config文件和助记词 -- 千万不要泄露/丢失。
Anytype 的底层设计逻辑:“本地优先(Local-first)”。
是的,你的数据非常安全。 即使你的 VPS 彻底爆炸、硬盘报废且没有任何备份,你手机和电脑里的数据依然是完整且可用的。
🛡️ 为什么数据不会丢失?
Anytype 与 Notion 或 Slack 不同,它不是一个“云端应用”,而是一个 P2P(点对点)应用。
🔄 如果服务器彻底丢失,如何恢复?
如果你无法找回
./data(即丢失了服务器的PeerID和私钥),你无法让新服务器“伪装”成旧服务器。但你可以通过以下流程轻松恢复:1. 导出备份(最稳妥)
在服务器出问题期间,或者在尝试连接新服务器之前,在 Windows 客户端上执行:
Settings->Flow->Export Data。.anytype备份文件)。这会包含你所有的空间、页面和关联关系。2. 建立新“网络”
client-config.yml。3. 客户端切换
%AppData%/anytype2文件夹(注意:如果你有多个账户,确保备份了 Recovery Phrase)。Self-hosted,导入新服务器的配置文件。4. 数据重推
一旦你登录成功,由于你手里的 Recovery Phrase 没变,客户端会发现空间是空的,它会利用本地缓存的数据(或通过导入刚才的备份文件)重新将所有数据 Push 到新服务器上。
⚠️ 唯一需要保护的东西:Recovery Phrase
对于 Anytype 用户来说,唯一的致命损失是丢失“助记词(Recovery Phrase)”。
./data丢了:可以重申领身份证(New PeerID)。💡 建议的下一步:
既然你现在的服务器已经运行在双栈网络下,我建议你现在就去电脑端执行一次 Export Data,保存一个
.anytype文件到本地硬盘或 U 盘里。@tof #0
请教大佬:你的自托管方案在安卓客户端可以正常使用吗?
我在windows端正常,但是安卓客户端无法加载配置文件。。。
@Nodeseeker666 #4 肯定可以 我目前没有节点测试了 但之前全通
@tof #5
那可能是我的部署问题,我试一下你的方案吧,感谢
@Nodeseeker666 #6 我重新部署了 compose config应该差不多。修改后的--这次我没考虑v6