V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
mouyase
V2EX  ›  分享创造

更简单的部署 AnyType 同步服务器的方案

  •  
  •   mouyase ·
    mouyase · 96 天前 · 3198 次点击
    这是一个创建于 96 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文地址: https://yojigen.tech/33.html

    前言

    之前折腾了使用 Docker 在 NAS 里部署桌面版 AnyType 客户端,用来局域网同步数据。

    但是我还是不死心,还是想试试部署官方的同步服务。于是又研究了一天,得出了这个新的方案。

    分析官方 docker 结构

    官方是有着一个github 仓库用来部署 docker 的。

    配置很复杂,而且一些服务的设置有些迷惑,类似redismongominio之类的服务其实都没必要把端口映射出来,一些官方的镜像也完全没有必要用Dockerfile自己编译,直接用官方的镜像就行。

    于是我就想能不能把他的镜像优化一下,所以先看看他的镜像都有什么。

    源文件: https://github.com/anyproto/any-sync-dockercompose/blob/main/docker-compose.yml

    根据源文件的 service 字段,从上到下的服务一共有这些。

    • generateconfig-anyconf
    • generateconfig-processing
    • mongo-1
    • redis
    • minio
    • create-bucket
    • any-sync-coordinator_bootstrap
    • any-sync-coordinator
    • any-sync-filenode
    • any-sync-node-1
    • any-sync-node-2
    • any-sync-node-3
    • any-sync-consensusnode
    • netcheck

    generateconfig-anyconf是用于创建配置的。 generateconfig-processing是用来判断配置是否创建完成的。 any-sync-coordinator_bootstrap也是用来判断配置是否正确的。 netcheck是检测配置和网络是否正确的。

    换句话说其实上面这 4 个镜像都没有必要启动,是完全可以去掉的。

    创建正确的配置

    AnyType 官方的 docker 配置,是要用户使用make start命令来自动创建出来一些配置,然后再将client.yml导入到客户端,实现私有化部署。

    那么如何才能创建出来正确的配置呢?

    官方实际上有另一个工具https://github.com/anyproto/any-sync-tools。这个库内含两个二进制程序。any-sync-network用于创建网络配置,any-sync-netcheck用于检查网络配置。

    我们可以下载any-sync-tools二进制文件,里面内含了一个defaultTemplate.yml文件。这是网络配置的模板参数,我们可以修改其中的一部分 IP 和端口配置,然后用这个模板创建自己的配置。

    # 这里添加你的同步服务的地址/域名,可以填写多个
    # 同时需要填写一个 docker 宿主的可访问 IP ,用于让镜像内部可以访问到其他镜像的端口
    external-addresses:
     - 172.123.234.1
     - 127.0.0.1
    
    any-sync-consensusnode:
      listen: any-sync-consensusnode
      yamuxPort: 4530
      quicPort: 5530
      mongo:
        # 这里修改了 mongo 的地址
        connect: mongodb://mongo:27017/?w=majority
        database: consensus
    
    any-sync-coordinator:
      listen: any-sync-coordinator
      yamuxPort: 4630
      quicPort: 5630
      mongo:
        # 这里修改了 mongo 的地址
        connect: mongodb://mongo:27017
        database: coordinator
      defaultLimits:
        spaceMembersRead: 1000
        spaceMembersWrite: 1000
        sharedSpacesLimit: 1000
    
    any-sync-filenode:
      listen: any-sync-filenode
      yamuxPort: 4730
      quicPort: 5730
      s3Store:
        # 这里修改了 minio 的地址
        endpoint: http://minio:9000
        bucket: minio-bucket
        indexBucket: minio-bucket
        region: us-east-1
        profile: default
        forcePathStyle: true
      redis:
        # 这里修改了 redis 的地址
        url: redis://redis:6379?dial_timeout=3&read_timeout=6s
      defaultLimit: 1099511627776
    
    any-sync-node:
      listen:
      - any-sync-node-1
      - any-sync-node-2
      - any-sync-node-3
      yamuxPort: 4430
      quicPort: 5430
    

    修改完成后,在当前目录执行。

    any-sync-network create --auto
    

    可以一键创建配置,配置文件在etc目录下,其中client.yml就是给客户端用的配置文件。

    本以为配置到这里就结束了,但是实际上还有一个隐藏的关于 s3 的配置,我最开始就是因为没有注意这个配置,导致一开始文件都不能同步,只能同步文本。

    etc目录下,需要创建一个.aws目录,然后在.aws目录中,创建一个credentials文件,文件内容如下。这个文件的内容是和后面的docker-compose.yml对应的,可以酌情修改。

    [default]
    aws_access_key_id=user
    aws_secret_access_key=password
    

    部署 docker

    我创建了一个新的docker-compose.yml文件,里面的配置和端口是和上面的配置对应的,如果你有自己的想法,可以酌情修改。

    services:
      mongo:
        image: mongo:4
        restart: unless-stopped
        command: ["--replSet", "rs0", "--port", "27017"]
        volumes:
          - ./storage/mongo/:/data/db
        networks:
          - network
        healthcheck:
          test: mongo --port 27017 --eval 'rs.initiate({"_id":"rs0","members":[{"_id":0,"host":"mongo:27017"}]})'
          interval: 10s
          start_period: 30s
    
      redis:
        image: redis/redis-stack-server:latest
        restart: unless-stopped
        command: ["redis-server", "--port", "6379", "--dir", "/data/", "--appendonly", "yes", "--maxmemory", "256mb", "--maxmemory-policy", "noeviction", "--protected-mode", "no", "--loadmodule", "/opt/redis-stack/lib/redisbloom.so"]
        volumes:
          - ./storage/redis/:/data/
        networks:
          - network
        healthcheck:
          test: [ "CMD", "redis-cli", "--raw", "-p", "6379", "incr", "ping" ]
          interval: 10s
          timeout: 30s
          retries: 3
    
      minio:
        image: minio/minio:latest
        restart: unless-stopped
        command: ["server", "/data", "--console-address", ":9001", "--address", ":9000"]
        environment:
          MINIO_ROOT_USER: "user"
          MINIO_ROOT_PASSWORD: "password"
        volumes:
          - ./storage/minio:/data
        healthcheck:
          test: bash -c ':> /dev/tcp/127.0.0.1/9000' || exit 1
          interval: 5s
          timeout: 10s
          retries: 3
        networks:
          network:
            aliases:
              - "minio-bucket.minio"
    
      create-bucket:
        image: minio/mc:latest
        depends_on:
          - minio
        networks:
          - network
        entrypoint: >
          /bin/sh -c "
          until (/usr/bin/mc alias set minio http://minio:9000 'user' 'password') do echo '...waiting...' && sleep 1; done;
          /usr/bin/mc mb minio/minio-bucket;
          exit 0;
          "
    
      any-sync-consensusnode:
        image: ghcr.io/anyproto/any-sync-consensusnode:latest
        depends_on:
          any-sync-coordinator:
            condition: service_started
        ports:
          - "4530:4530"
          - "5530:5530/udp"
        volumes:
          - ./etc/any-sync-consensusnode/:/etc/any-sync-consensusnode/
          - ./storage/networkStore/any-sync-consensusnode/:/networkStore/
        networks:
          - network
        deploy:
          resources:
            limits:
              memory: 500M
        restart: unless-stopped
    
      any-sync-coordinator:
        image: ghcr.io/anyproto/any-sync-coordinator:latest
        depends_on:
          mongo:
            condition: service_healthy
        ports:
          - "4630:4630"
          - "5630:4630/udp"
        volumes:
          - ./etc/any-sync-coordinator/:/etc/any-sync-coordinator/
          - ./storage/networkStore/any-sync-coordinator/:/networkStore/
        networks:
          - network
        deploy:
          resources:
            limits:
              memory: 500M
        restart: unless-stopped
    
      any-sync-filenode:
        image: ghcr.io/anyproto/any-sync-filenode:latest
        depends_on:
          redis:
            condition: service_healthy
          minio:
            condition: service_healthy
          any-sync-coordinator:
            condition: service_started
        ports:
          - "4730:4730"
          - "5730:5730/udp"
        volumes:
          - ./etc/any-sync-filenode/:/etc/any-sync-filenode/
          - ./etc/.aws:/root/.aws:ro
          - ./storage/networkStore/any-sync-filenode/:/networkStore/
        networks:
          - network
        deploy:
          resources:
            limits:
              memory: 500M
        restart: unless-stopped
    
      any-sync-node-1:
        image: ghcr.io/anyproto/any-sync-node:latest
        depends_on:
          any-sync-coordinator:
            condition: service_started
        ports:
          - "4430:4430"
          - "5430:5430/udp"
        volumes:
          - ./etc/any-sync-node-1/:/etc/any-sync-node/
          - ./storage/any-sync-node-1/:/storage/
          - ./storage/networkStore/any-sync-node-1/:/networkStore/
        networks:
          - network
        deploy:
          resources:
            limits:
              memory: 500M
        restart: unless-stopped
    
      any-sync-node-2:
        image: ghcr.io/anyproto/any-sync-node:latest
        depends_on:
          any-sync-coordinator:
            condition: service_started
        ports:
          - "4431:4431"
          - "5431:5431/udp"
        volumes:
          - ./etc/any-sync-node-2/:/etc/any-sync-node/
          - ./storage/any-sync-node-2/:/storage/
          - ./storage/networkStore/any-sync-node-2/:/networkStore/
        networks:
          - network
        deploy:
          resources:
            limits:
              memory: 500M
        restart: unless-stopped
    
      any-sync-node-3:
        image: ghcr.io/anyproto/any-sync-node:latest
        depends_on:
          any-sync-coordinator:
            condition: service_started
        ports:
          - "4432:4432"
          - "5432:5432/udp"
        volumes:
          - ./etc/any-sync-node-3/:/etc/any-sync-node/
          - ./storage/any-sync-node-3/:/storage/
          - ./storage/networkStore/any-sync-node-3/:/networkStore/
        networks:
          - network
        deploy:
          resources:
            limits:
              memory: 500M
        restart: unless-stopped
    
    # gateway 的 IP 需要添加到之前配置模板里面,我上面已经添加过了
    # 如果有 IP 地址冲突,请自行修改
    networks:
      network:
        ipam:
          driver: default
          config:
            - subnet: 172.123.234.0/24
              gateway: 172.123.234.1
    

    然后将etc复制到同目录下,启动镜像即可。

    现成的配置

    我把我的配置放在了 github 库里。你可以直接使用我的配置(但是还是要添加你的服务器 IP )。

    仓库地址: https://github.com/mouyase/anytype-docker-compose

    客户端使用提示

    如果你现在已经有了一个 AnyType 的库,记得先把库导出,然后切换私有化部署方案,创建新的库,再导入。

    一个其他服务上的旧的库,是没有办法直接在另一个服务中打开的,每一个服务都需要创建一个新的库,再导入旧数据才能正常使用。请一定要注意。

    尾声

    我在 NAS 上部署了这套服务,然后再用 frp 做了内网穿透。局域网下走本地 IP ,在外网则使用 frp 转发 IP 。同时内网客户端还能 P2P 同步。这下终于可以稳妥的做到私有化同步了。

    接下来该试着学一学 AnyType 的体系,看看能不能彻底替换掉 Notion 使用啦。

    21 条回复    2024-10-21 08:42:37 +08:00
    0o0O0o0O0o
        1
    0o0O0o0O0o  
       95 天前 via iPhone
    官方的自建方案真的有点乱糟糟,你这个还不够轻,需要更轻量可以看看(纯自用,风险被我的其它备份策略承担了)
    https://github.com/orgs/anyproto/discussions/17#discussioncomment-9921389

    > 看看能不能彻底替换掉 Notion 使用

    目测在未来相当长一段时间内都不能,降低预期比较好。他们开发人手不足——最活跃的主要是前端,而事实上 protocol 才是核心的。因为它既 local-first 又 E2EE ,所以许多别的同类产品的特性它就很难很难做到。
    mouyase
        2
    mouyase  
    OP
       95 天前 via Android
    @0o0O0o0O0o 这个方案我看了,本质就是把 minio 和 mango 给换成了别的,然后减少了两个 sync-node ,我个人更倾向于用官方套件,至少能保证兼容。
    官方的那个 make start 的模式我是真不喜欢,明明就是生成个配置的事情,弄那么复杂。
    至于替代 notion ,其实我基本没用什么高级功能,基本就是一些常用的功能,前段时间用 obsidian 了,但是 obsidian 的编辑界面属实难受,表格功能也太烂,稍微有点接受不了了,也不想装太多插件,所以才考虑要不要换一个。
    wdxbb
        3
    wdxbb  
       95 天前 via iPhone
    楼主厉害👍🏻,折腾 any type 同步好久了,一开始在虚拟机中安装 anytype 客户端我也想过 哈哈
    0o0O0o0O0o
        4
    0o0O0o0O0o  
       95 天前 via iPhone
    @mouyase #2 追求不 patch 可以关注 light node ,会是把这些 node 都集合在一起的轻量节点,尽管我也不知道他们什么时候开始。
    https://github.com/anyproto/any-sync-coordinator/issues/80#issuecomment-2220554099

    列一些我体验中的不足:
    - 它的编辑界面对习惯写类 markdown 的不太友好
    - 它倒是不用装插件,因为它根本没插件
    - 它的默认格式不是开放格式,未来迁移一定会踩坑
    - 它的所有客户端都不是真正开源的
    - 它涉及核心的特性推进得非常慢,甚至停滞不前
    qweruiop
        5
    qweruiop  
       95 天前
    已经弃坑 anytype 了,他们团队感觉前端人员多点,后端和 ai 的人少点。这个东西,做到后面,就更新越来越慢了。
    mouyase
        6
    mouyase  
    OP
       95 天前 via Android
    @wdxbb 上一篇文章就是用客户端同步的,但是会有点问题
    mouyase
        7
    mouyase  
    OP
       95 天前 via Android
    @0o0O0o0O0o 只论体验,这些笔记都没法和 Notion 比,AnyType 已经是这些矮子里的高个子了。
    SenLief
        8
    SenLief  
       95 天前
    官方的不是挺好用的吗
    mouyase
        9
    mouyase  
    OP
       95 天前 via Android
    @SenLief 不开会员仅限 1g 同步量
    LavaC
        10
    LavaC  
       95 天前
    官方的自部署年初我自己玩了一下没玩懂就弃了,搞得也太麻烦了。
    LavaC
        11
    LavaC  
       95 天前
    看了下之前的文章,虚拟局域网方案我倒是试过,ZeroTier 自建 plant ,同步倒是能同步。但是这软件里的文件和图片在局域网同步模式下是不会全量同步的,只有用的时候会同步。所以除非你有一台设备能保持 24 小时挂机,否则还是得走自部署这条路。
    mouyase
        12
    mouyase  
    OP
       95 天前 via Android
    @LavaC 我那个文章里说的就是用 Docker 部署到 NAS 上呀,NAS 就是 24 小时挂机的。私有部署不也是要服务器 24 小时挂机吗,没区别呀。
    Niphor
        13
    Niphor  
       94 天前
    anytype 和 affine 哪个好用
    mouyase
        14
    mouyase  
    OP
       94 天前
    @Niphor affine 客户端不支持私有部署,我就没试
    wdxbb
        15
    wdxbb  
       93 天前
    按楼主的方法部署了一下,成功同步,但是 P2P 同步功能好像没了,电脑连接手机热点也不能 P2P ,这是咋回事呀
    mouyase
        16
    mouyase  
    OP
       93 天前
    @wdxbb #15
    理论上这个和 P2P 同步没关系,P2P 同步是纯客户端行为,只要两个 ID 一样的客户端在内网他们就会尝试 P2P 同步。

    你换了同步服务器,理论上库的 ID 换了,你看看是不是别的客户端没有更新库的 ID 。
    SenLief
        17
    SenLief  
       93 天前
    @mouyase 活动的时候你没升级吗?可以升级到 10g
    mouyase
        18
    mouyase  
    OP
       93 天前
    @SenLief 我是最近才知道的这个软件
    SenLief
        19
    SenLief  
       93 天前
    @mouyase 不是太好用,但是它备份 notion 很好用
    MrLegend
        20
    MrLegend  
       62 天前
    这几个都整得好复杂啊,要是能在 Docker Hub 搞个服务端,一件创建,然后客户端里输个服务端的 IP 或者域名就可以同步就好了,就像 vaultwarden/server 之于 Bitwarden 那样
    mouyase
        21
    mouyase  
    OP
       61 天前 via Android
    @MrLegend 问就是官方没有独立镜像
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1112 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:38 · PVG 02:38 · LAX 10:38 · JFK 13:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.