IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    最小化部署自己的 Nostr Relay 和 Blossom 媒体上传服务

    Joomaen发表于 2025-06-08 06:18:54
    love 0

    Nostr 协议在我看来是很先进的,暂时使用的人还不多,不过相比 Fediverse 的 Mastodon 之类,自己部署 Nostr Relay 是成本很小的。Blossom 作为媒体上传服务是可选的,因为有几个公共服务器可用,但是大多数国内无法直连。我还发现部分客户端不支持自定义 Blossom 服务器,只有 Amethyst 和 Nostrmo 可以。

    我目前使用的是这个 nostr-relay 以及这个 blossom-server。


    nostr-relay

    这个用 Python 写的 nostr-relay 很不错。

    配置文件是这个:https://code.pobblelabs.org/fossil/nostr_relay/file?name=nostr_relay/config.yaml
    可以按需修改,自己用默认就够了。

    # 先安装 pipx
    apt install pipx
    # 再用 pipx 安装 nostr-relay
    pipx install nostr-relay
    # 选择一个目录运行以下命令启动默认配置,默认 SQLite 文件在当前目录
    nostr-relay serve
    # 后台运行
    (nostr-relay serve </dev/null &>>/var/log/nostr-relay.log &)
    # 查看 PID
    lsof -i :6969
    # 停止运行
    kill PID
    # 后台运行命令会调用 gunicorn 运行而不是nostr-relay,因此会搜不到 nostr-relay 进程,可以尝试这个命令
    ps -ef | grep gunicorn

    反代 127.0.0.1:6969 配置域名和 SSL 证书即可。

    保持简洁,不使用 Docker 和 systemd,后续迁移时只需复制整个文件夹即可。


    blossom-server

    clone 这个仓库 https://github.com/hzrd149/blossom-server.git

    git clone https://github.com/hzrd149/blossom-server.git

    克隆仓库是必要的,因为 blossom-server 的默认页面依赖 public/ 目录,请保留该目录。

    用以下 config.yml 和 docker-compose.yml 覆盖原仓库中的文件

    然后执行 docker compose up -d

    反代 127.0.0.1:3000 配置域名和 SSL 证书即可。

    config.yml

    按需修改,比如 Dashboard 密码、允许的 PubKey 等。

    # Override the domain thats is used in the blobs "url" field
    # By default it uses the domain the incoming HTTP request was made on
    publicDomain: ""
    
    databasePath: data/sqlite.db
    
    dashboard:
      # enable or disable the admin dashboard
      enabled: true
      # admin username
      username: admin
      # if password is left blank it will be generated each time the app starts
      password: "yourpasswd"
    
    # 文件发现机制,保持默认关闭
    discovery:
      # find files by querying nostr relays
      nostr:
        enabled: false
        relays:
          - wss://relay.example.com
      # find files by asking upstream CDNs
      # NOTE: do not set this to your own server, it will create an infinite loop
      upstream:
        enabled: false
        domains:
          - https://cdn.example.com
    
    storage:
      # local or s3
      backend: local
    
      # Imminently removes a blob when there are no owners
      removeWhenNoOwners: false
    
      # local storage
      local:
        dir: ./data/blobs
    
      # see minio docs for options:
      # https://min.io/docs/minio/linux/developers/javascript/API.html#new-minio-client-endpoint-port-usessl-accesskey-secretkey-region-transport-sessiontoken-partsize
      # s3:
      #   endpoint: https://s3.endpoint.com
      #   port: 443
      #   bucket: blossom
      #   accessKey: xxxxxxxx
      #   secretKey: xxxxxxxxx
      #   useSSL: true
      #   region: us-east-1
      #   If this is set the server will redirect clients when loading blobs
      #   publicURL: https://s3.region.example.com/
    
      # rules are checked in descending order. if a blob matches a rule it is kept
      # "type" (required) the type of the blob, "*" can be used to match any type
      # "expiration" (required) time passed since last accessed
      # "pubkeys" (optional) a list of owners
      # any blobs not matching the rules will be removed
      rules:
        - type: "*"
          expiration: 100 years
          pubkeys:
            - "change-to-your-pubkey-hex"
    
    # Config for the /upload endpoint
    upload:
      # enable / disable uploads (default false)
      enabled: true
      # require auth to upload
      requireAuth: true
      # only check rules that include "pubkeys"
      requirePubkeyInRule: true
    
    # Config for the /media endpoint
    media:
      # /media endpoint enabled (default false)
      enabled: true
      # require auth to upload to /media
      requireAuth: true
      # only check rules that include "pubkeys"
      requirePubkeyInRule: true
    
      # image optimization options
      image:
        # image quality 0-100 (default 90)
        quality: 90
        # create progressive jpeg / png images for large images > 1024x768 (default true)
        progressive: true
        # max width (default 1920)
        maxWidth: 1920
        # max height (default 1080)
        maxHeight: 1080
        # image format (default webp)
        outputFormat: "webp"
        # keep aspect radio when resizing (default true)
        maintainAspectRatio: true
        # keep EXIF metadata (default false)
        keepExif: false
        # fps for GIFs (default 30)
        fps: 30
    
      video:
        # video quality 0-100 (default 90)
        quality: 90
        # max height (default 1080)
        maxHeight: 1080
        # max fps (default 30)
        maxFps: 30
        # output format [mp4, webm, mkv] (default mp4)
        format: "webm"
        # audio codec [aac, mp3, vorbis, opus] (default aac)
        audioCodec: "aac"
        # video codec [libx264, libx265, vp8, vp9] (default libx264)
        videoCodec: "libx264"
    
    list:
      requireAuth: false
      allowListOthers: true
    
    tor:
      enabled: false
      proxy: ""

    docker-compose.yml

    services:
      blossom:
        image: ghcr.io/hzrd149/blossom-server:master
        ports:
          - 3000:3000
        volumes:
          # mount data volume
          - ./data:/app/data
          # mount config file
          - ./config.yml:/app/config.yml
          # mount custom www dir
          - ./public:/app/public

    其他

    我自己目前就是部署的这两个服务自用。主要是方便部署和维护,后续服务器迁移只需要复制文件夹即可。Blossom 媒体服务自用的话,默认使用服务器本地存储即可,就是在项目文件夹中的 ./data/blobs/,上传的图片和视频会被自动压缩,占不了多少存储空间。如果公开或多人使用也可以配置 S3 兼容的对象存储。

    除了我上面说的这个 nostr-relay,还有一个 Rust 写的 nostr-rs-relay,可以 Docker 一键部署,如果你偏好使用 Docker,也可以选择这个。

    如果你也对 Nostr 这个去中心化协议感兴趣,想拥有自己的 Nostr 服务,不妨参考本文试试,欢迎留言交流!


    推荐阅读

    • 欢迎加入 Nostr, 这是一份快速入门指南
    • Nostr!moe
    • Join Nostr
    • 运行自己的中继器,拥有自己的事件
    • 用自己域名认证 Nostr 的 NIP-05


沪ICP备19023445号-2号
友情链接