MoreRSS

site iconLala | 荒岛修改

一个应用分享、教程类的博客,主要是那些需要自部署的。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

Lala | 荒岛的 RSS 预览

Docker部署Zulip团队协作平台

2026-04-19 15:54:12

Zulip是完全开源的,但是自托管版本有一些限制,详细对比可浏览这个网页查看。似乎只有移动推送通知限制10个用户有点蛋疼,其他的都不怎么影响体验。实际上如果配置了SMTP,离线用户是可以收到邮件通知的。

安装Docker:

apt -y update
apt -y install curl git
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

克隆存储库:

cd /opt
git clone https://github.com/zulip/docker-zulip.git
cd docker-zulip

Zulip的compose编排使用了docker secrets来存储敏感数据。我们需要新建一个.env文件:

nano .env

至少写入以下内容,这里包括但不限于PG数据库密码、REDIS密码、您的SMTP邮件密码等:

ZULIP__POSTGRES_PASSWORD=example_postgres_password
ZULIP__MEMCACHED_PASSWORD=example_memcached_password
ZULIP__RABBITMQ_PASSWORD=example_rabbitmq_password
ZULIP__REDIS_PASSWORD=example_redis_password
ZULIP__SECRET_KEY=example_django_secret_key
ZULIP__EMAIL_PASSWORD=example_outgoing_email_password

编辑compose.override.yaml覆盖文件:

nano compose.override.yaml

在这个覆盖文件内至少需要修改以下内容:

services:
  zulip:
    environment:
      SETTING_EXTERNAL_HOST: "zulip.example.com"
      SETTING_ZULIP_ADMINISTRATOR: "[email protected]"
      TRUST_GATEWAY_IP: True
      SETTING_EMAIL_HOST: "mail.example.com"
      SETTING_EMAIL_HOST_USER: "smtp"
      SETTING_EMAIL_PORT: "587"
      SETTING_EMAIL_USE_SSL: False
      SETTING_EMAIL_USE_TLS: True
      SETTING_ZULIP_SERVICE_PUSH_NOTIFICATIONS: True
      SETTING_ZULIP_SERVICE_SUBMIT_USAGE_STATISTICS: False

编辑compose.yaml基础文件:

nano compose.yaml

我们使用反向代理,所以在这里注释掉Zulip容器的443端口,同时将对外暴露的80端口改为8089:

---
services:
  zulip:
    image: "ghcr.io/zulip/zulip-server:11.6-1"
    restart: unless-stopped
    build:
      context: .
    ports:
      - name: smtp
        target: 25
        published: 25
        app_protocol: smtp
      - name: http
        target: 80
        published: 8089
        app_protocol: http
#      - name: https
#        target: 443
#        published: 443
#        app_protocol: https

拉取镜像并初始化Zulip:

docker compose pull
docker compose run --rm zulip app:init

如果一切正常,您应该看到类似下图的回显:

如果输出结果并非以该内容结尾:

=== End Initial Configuration Phase ===

请仔细阅读输出结果以查找警告或错误。

现在就可以启动Zulip了:

docker compose up zulip --wait

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

zulip.example.com {
   proxy "http://127.0.0.1:8089/"
   proxy_request_header_replace "Host" "{header:Host}"
}

重载Ferron:

systemctl reload ferron

生成一个链接,在浏览器访问该链接创建新组织:

docker compose exec -u zulip zulip \
    /home/zulip/deployments/current/manage.py generate_realm_creation_link

如图所示:

效果:

关于移动推送通知,除了设置SETTING_ZULIP_SERVICE_PUSH_NOTIFICATIONS: True,还需要执行如下命令注册才能使用:

docker compose exec -u zulip zulip \
    /home/zulip/deployments/current/manage.py register_server

如果您的hostname(完全限定域名fqdn)之前已经注册过,可以使用下面的命令迁移注册:

docker compose exec -u zulip zulip \
    /home/zulip/deployments/current/manage.py register_server --registration-transfer

排查错误:

docker compose exec zulip bash
cat /var/log/zulip/errors.log

sing-box服务端中转+wireguard解锁DMMTV配置

2026-04-18 19:55:32

起因:一台落地用的日本鸡DMMTV解锁掉了,但是套WARP又可以解锁,然后落地鸡直连太慢,所以用别的小鸡中转一下,就有了下面的配置。这两台机器到期我不打算续费了,所以把配置贴上来备份一下,以备不时之需= =以下配置全部基于sing-box 1.12。如sing-box更新不保证这些配置一直正确无误。

中转鸡配置:

{
  "log": {
    "level": "info"
  },
  "dns": {
    "servers": [
      {
        "type": "tls",
        "server": "8.8.8.8"
      }
    ]
  },
  "inbounds": [
    {
      "type": "anytls",
      "listen": "0.0.0.0",
      "listen_port": 8443,
      "users": [
        {
          "name": "fuckccp",
          "password": "hidden"
        }
      ],
      "padding_scheme": [
        "stop=8",
        "0=30-30",
        "1=100-400",
        "2=400-500,c,500-1000,c,500-1000,c,500-1000,c,500-1000",
        "3=9-9,500-1000",
        "4=500-1000",
        "5=500-1000",
        "6=500-1000",
        "7=500-1000"
      ],
      "tls": {
        "enabled": true,
        "server_name": "fuckccp.example.com",
        "alpn": [
          "h2"
        ],
        "acme": {
          "domain": [
            "fuckccp.example.com"
          ],
          "dns01_challenge": {
            "provider": "cloudflare",
            "api_token": "hidden"
          }
        }
      }
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "shadowsocks",
      "tag": "unlock-out",
      "server": "1.2.3.4",
      "server_port": 8081,
      "method": "chacha20-ietf-poly1305",
      "password": "hidden"
    }
  ],
  "route": {
    "rules": [
      {
        "action": "sniff"
      },
      {
        "protocol": "dns",
        "action": "hijack-dns"
      },
      {
        "rule_set": [
          "geosite-dmm",
          "geosite-dmm-porn",
          "geosite-abema",
          "custom-mgstage"
        ],
        "outbound": "unlock-out"
      }
    ],
    "rule_set": [
      {
        "type": "local",
        "tag": "custom-mgstage",
        "format": "binary",
        "path": "/root/mgstage.srs"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm-porn",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm-porn.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-abema",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-abema.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      }
    ]
  }
}

落地鸡配置:

{
  "log": {
    "level": "info"
  },
  "dns": {
    "servers": [
      {
        "type": "tls",
        "server": "8.8.8.8"
      }
    ]
  },
  "endpoints": [
    {
      "type": "wireguard",
      "tag": "wg-unlock",
      "system": true,
      "name": "wg0",
      "mtu": 1280,
      "address": [
        "10.0.0.2/32"
      ],
      "private_key": "hidden",
      "peers": [
        {
          "address": "engage.cloudflareclient.com",
          "port": 2408,
          "public_key": "hidden",
          "allowed_ips": [
            "0.0.0.0/0"
          ],
          "persistent_keepalive_interval": 30,
          "reserved": [0, 0, 0]
        }
      ]
    }
  ],
  "inbounds": [
    {
      "type": "shadowsocks",
      "listen": "::",
      "listen_port": 8081,
      "method": "chacha20-ietf-poly1305",
      "password": "hidden"
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ],
  "route": {
    "rules": [
      {
        "action": "sniff"
      },
      {
        "protocol": "dns",
        "action": "hijack-dns"
      },
      {
        "rule_set": [
          "geosite-dmm",
          "geosite-dmm-porn",
          "geosite-abema",
          "custom-mgstage"
        ],
        "outbound": "wg-unlock"
      }
    ],
    "rule_set": [
      {
        "type": "local",
        "tag": "custom-mgstage",
        "format": "binary",
        "path": "/root/mgstage.srs"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-dmm-porn",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-dmm-porn.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      },
      {
        "type": "remote",
        "tag": "geosite-abema",
        "format": "binary",
        "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-abema.srs",
        "download_detour": "direct",
        "update_interval": "7d"
      }
    ]
  }
}

mgstage.srs是我自定义的一个规则,用于解锁MGSTAGE,不需要可以移除,需要的话可以新建一个json文件:

nano mgstage.json

写入如下内容:

{
  "version": 3,
  "rules": [
    {
      "domain_suffix": [
        "mgstage.com"
      ]
    }
  ]
}

编译成srs格式:

sing-box rule-set compile mgstage.json

然后落地鸡解锁用到的wiregurad配置我是使用wgcf生成的,先安装wgcf:

wget https://github.com/ViRb3/wgcf/releases/download/v2.2.30/wgcf_2.2.30_linux_amd64
mv wgcf_2.2.30_linux_amd64 wgcf
chmod +x wgcf

生成wireguard配置:

./wgcf register
./wgcf generate

查看wireguard配置,把里面的PrivateKey和PublicKey复制粘贴到sing-box的配置文件内就行了:

cat wgcf-profile.conf

这样客户端连接中转鸡的anytls节点,匹配到DMM的流量会通过shadowsocks分流到落地鸡,落地鸡再把DMM流量分流到wireguard。其他流量还是直接走中转鸡。

BluFiles:轻量级的自托管文件管理和共享系统

2026-04-18 11:17:50

BluFiles特征:

  • 文件管理:BluFiles 提供了一个用户友好的界面,用于管理您的文件和文件夹。
  • 粘贴:创建并分享带有语法高亮显示的代码片段文本。
  • 收藏集:将文件、文件夹和文本内容整理到收藏集中,以便集中共享一组项目。
  • 共享:通过链接共享文件、文件夹、文本内容或集合。
  • 管理面板:通过网页界面管理用户、配额和其他配置。
  • API 集成:允许使用 API 轻松集成自定义上传工具,并提供 ShareX 的预置模板。

安装Docker:

apt -y update
apt -y install curl
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

创建目录和compose文件:

mkdir /opt/blufiles && cd /opt/blufiles && nano docker-compose.yml

写入如下内容:

services:
  blufiles:
    image: ghcr.io/bludood/files:latest
    restart: unless-stopped
    ports:
      - 127.0.0.1:1337:1337
    volumes:
      - ./data:/data
    environment:
      - DATABASE_URL=postgresql://postgres:dbpassword@postgres:5432/files
      - STORAGE_DIR=/data
      - TRUST_PROXY=true
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: dbpassword
      POSTGRES_DB: files
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U postgres']
      interval: 5s
      timeout: 5s
      retries: 5

启动:

docker compose up -d

配置Ferron反向代理:

nano /etc/ferron.kdl

写入如下内容:

blufiles.example.com {
   proxy "http://127.0.0.1:1337/"
   proxy_request_header_replace "Host" "{header:Host}"
}

重载Ferron:

systemctl reload ferron

效果:

btrfs元数据满了(metadata full)解决办法

2026-03-22 11:09:05

症状:硬盘有很多剩余空间,但无法写入,报错:no space left on device。

可以用这个命令检查,如果metadata接近满了那就是了:

sudo btrfs fi usage /

此时大概率没办法直接做balance,直接balance的话也报:no space left on device。

解决办法,在内存里面创建一个1GB大小的临时文件,机子内存够大的话也可以创建更大的文件:

truncate -s 1G /tmp/btrfs_rescue.img

设置为回环设备:

sudo losetup /dev/loop50 /tmp/btrfs_rescue.img

把这个回环设备临时加入文件系统

sudo btrfs device add /dev/loop50 /

这个时候就可以执行balance了,但是我发现也空闲不出来多大的元数据空间,所以我干脆把DUP改成single,而且我这hdd用single性能还会好一些:

sudo btrfs balance start -mconvert=single --force /

收尾工作,移除刚加入的回环设备:

sudo btrfs device remove /dev/loop50 /

断开回环设备:

sudo losetup -d /dev/loop50

删除临时文件:

rm /tmp/btrfs_rescue.img

再balance一次,把dusage设置的激进一些,因为data空闲的空间比较多:

sudo btrfs balance start -dusage=70 /

正常了:

[可选]DUP改single会降低系统安全性,不放心的话可以改回去:

sudo btrfs balance start -mconvert=dup /

改回去的话应该会多占用2.56GB,但现在Unallocated有17.9GB,绰绰有余。

开源一个弹幕视频播放站点,支持BT / URL导入视频

2026-03-19 17:13:11

MoeVideo是一个开源弹幕视频播放站点,支持通过BT / yt-dlp + curl-cffi / rebrowser-playwright + chromium导入视频。最近一直在vibe coding这个程序,感觉功能都完善的差不多了,能够满足自己的需求了,索性开源出来分享给大伙一起用,反馈bug或者提需求都可以开issue,如果喜欢的话可以点个小星星支持一下。

技术栈:

  • 前端:Next.js App Router + Tailwind CSS
  • 后端:Go + Fiber

当前已实现的功能:

  • 视频上传
  • BT导入视频:支持自动解析种子文件内的媒体文件。
  • URL导入视频:yt-dlp + curl-cffi
  • 自定义yt-dlp cookies(cookies采用加密存储并支持配置多个站点)
  • 回落支持:yt-dlp不支持的站点自动回落到rebrowser-playwright + chromium
  • 强制回落:通过环境变量配置指定域名直接走rebrowser-playwright + chromium
  • HLS多码率转码:360p 480p 720p 1080p
  • 用户中心:可设置头像,签名,个人信息隐私策略等
  • 多用户支持:可选开启或关闭注册
  • 互动系统:点赞 评论 收藏 粉丝关注
  • 视频弹幕支持 (WebSocket)
  • 站内搜索:搜索您想看的视频
  • 标签页面:支持添加视频标签,按标签排列视频,单独的标签页面
  • 排行榜系统:独立的热度算法支持,智能排序热度最高的视频
  • ArtPlayer 雪碧图 + VTT
  • 跨设备同步播放记录,记忆上次播放位置。
  • 完善的管理面板:站点设置 用户管理 视频管理 转码任务管理 分类设置 yt-dlp设置 等
  • 本地存储 / S3存储支持

文档还没有全部写好,还有一些细节也没有到位,这篇文章先记录一下Docker的部署步骤。

安装Docker / NGINX / Certbot:

apt -y update
apt -y install curl git nginx python3-certbot-nginx
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

克隆项目存储库并准备数据目录:

git clone https://github.com/xiya233/MoeVideo.git
cd MoeVideo
mkdir -p data/db data/storage data/temp data/redis

编辑.env.docker:

nano .env.docker

假设您使用的域名是:app.example.com (前端)/ api.example.com (后端)至少需要修改下面的内容:

# 前端连接后端的API地址
NEXT_PUBLIC_API_BASE_URL=https://api.example.com/api/v1
# 与NEXT_PUBLIC_API_BASE_URL保持一致
API_BASE_URL=https://api.example.com/api/v1
# 建议至少 32 位高强度随机字符串
JWT_SECRET=replace-this-with-a-very-strong-secret
# 后端API地址
PUBLIC_BASE_URL=https://api.example.com
# HTTPS必须启用
AUTH_COOKIE_SECURE=true
# 留空
AUTH_COOKIE_DOMAIN=
# SameSite建议lax, 兼顾安全和常规站内跳转
AUTH_COOKIE_SAMESITE=lax
AUTH_COOKIE_PATH=/
# 设置前端域名
CORS_ALLOWED_ORIGINS=https://app.example.com
# 改大一点防止因下载速度慢导致超时重试
IMPORT_URL_TIMEOUT_SEC=18000
# 改大一点防止因网速慢导致页面解析超时
IMPORT_PAGE_RESOLVER_TIMEOUT_SEC=90
# 强制走 fallback 的域名列表, 逗号分隔,如不需要可留空
IMPORT_FORCE_FALLBACK_DOMAINS=missav.ai,24av.net

使用GHCR预构建镜像启动:

docker compose --env-file .env.docker -f docker-compose.yml -f docker-compose.ghcr.yml pull
docker compose --env-file .env.docker -f docker-compose.yml -f docker-compose.ghcr.yml up -d --no-build

创建管理员账号:

docker compose --env-file .env.docker run --rm backend \
  /app/moevideo-admin bootstrap \
  --email [email protected] \
  --username admin \
  --password 'ChangeMe-StrongPassw0rd!' \
  --db /data/db/moevideo.db

新建NGINX站点配置文件:

nano /etc/nginx/sites-available/moevideo.conf

写入如下内容:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

upstream moevideo_frontend {
    server 127.0.0.1:3000;
}

upstream moevideo_backend {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    listen [::]:80;
    server_name app.example.com;
    client_max_body_size 2048m;

    location / {
        proxy_pass http://moevideo_frontend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

server {
    listen 80;
    listen [::]:80;
    server_name api.example.com;
    client_max_body_size 2048m;

    location /api/ {
        proxy_pass http://moevideo_backend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    location /media/ {
        proxy_pass http://moevideo_backend;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /healthz {
        proxy_pass http://moevideo_backend/healthz;
    }
}

启用站点:

ln -s /etc/nginx/sites-available/moevideo.conf /etc/nginx/sites-enabled/moevideo.conf

申请证书:

certbot --nginx -d app.example.com -d api.example.com

登录后访问/admin即可打开管理员面板,建议修改一下yt-dlp的配置,提升下载速度:

--concurrent-fragments 8 --fragment-retries 10 --retries 10 --socket-timeout 30 --force-ipv4 --impersonate Chrome-136

如图所示:

项目截图:

目前s3存储还没有测试,不知道有没有什么bug,建议直接用本地存储。

然后是回落抓取网页媒体链接的功能,逻辑是这样的:yt-dlp支持的站点直接走yt-dlp下载,yt-dlp如提示不支持的url(unsupported url),则走rebrowser-playwright + chromium探测页面的媒体链接,用户手动选择抓取出来的链接再喂给yt-dlp下载。但是目前只对yt-dlp不支持的url(unsupported url)这一退出行为执行回落操作,其他报错退出不做回落操作,比如被cf拦截了,或者页面报403,等等这些都是不会自动回落的。

所以这里有个问题就是要让yt-dlp识别目标网站支不支持得先能够让它成功访问到目标页面,如果本身就被cf拦截或者其他莫名其妙的原因导致无法访问目标页面,yt-dlp退出的行为可能有很多种,只要不是不支持的url(unsupported url)退出的就不会回落,所以我增加了一个功能就是强制(指定)回落:用户可以设置指定域名直接走rebrowser-playwright + chromium。这个功能我测试了下载missav,24av等x站都是没问题的,或者说我就是专门为了下这几个站的视频特地做的= =

Rustatio:Modern BitTorrent Ratio Faker

2026-02-27 10:56:25

Rustatio是一款现代化的跨平台BitTorrent ratio管理工具,可模拟流行的BT客户端。说人话就是一款PT刷流作弊工具,你不需要真正的去下载种子里面的文件,这个工具可以模拟上传和下载速度,达到欺骗tracker的目的。

特点(摘自项目页面):

  • 现代图形用户界面:采用Tauri和Svelte构建的美观、直观的界面
  • 跨平台:可在 Linux、Windows 和 macOS 上运行
  • 多实例支持:通过标签式界面同时管理多个种子文件
  • 热门客户端模拟:可伪装成uTorrent、qBittorrent、Transmission、Deluge
  • Tracker检测:直接从种子文件中读取Tracker URL
  • 实时统计:上传/下载统计数据和比率的实时更新
  • 性能分析:上传/下载速率和节点分布的交互式图表
  • TOML 配置:易于编辑的配置文件
  • 控制台日志:用于调试的详细日志记录

警告(摘自项目页面):

此工具仅供教育用途。篡改BitTorrent追踪器的上传/下载统计数据可能违反私有追踪器的服务条款,并可能导致账户被暂停或封禁。使用风险自负。

作者建议搭配VPN使用,我个人觉得如果Rustatio本身就部署在VPS上的话,用不用VPN不太重要。最主要还是看相应PT站的规则,比如MT是禁止用VPN的,你挂个VPN还可能获得适得其反的效果= =我平时也不用那些收费的VPN,但为了演示Rustatio完整的功能,这里还是介绍下配置VPN的步骤,这里我就拿CloudFlare的WARP演示了。

先下载wgcf:

wget https://github.com/ViRb3/wgcf/releases/download/v2.2.30/wgcf_2.2.30_linux_amd64
mv wgcf_2.2.30_linux_amd64 wgcf
chmod +x wgcf

用wgcf生成wireguard配置:

./wgcf register
./wgcf generate

查看wgcf-profile.conf:

cat wgcf-profile.conf

正常的话会有这些内容,把PrivateKeyPublicKey保存好:

[Interface]
PrivateKey = 
Address = 172.16.0.2/32, 2606:4700:110:8a24:8971:6723:947c:eec4/128
DNS = 1.1.1.1, 1.0.0.1, 2606:4700:4700::1111, 2606:4700:4700::1001
MTU = 1280

[Peer]
PublicKey = 
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = engage.cloudflareclient.com:2408

由于Gluetun的WIREGUARD_ENDPOINT_IP不支持域名,所以这里还要把engage.cloudflareclient.com换成IP才能连接,我不知道IP是多少,所以PING一下= =

ping -4 engage.cloudflareclient.com
PING engage.cloudflareclient.com (162.159.192.1) 56(84) bytes of data.
64 bytes from 162.159.192.1: icmp_seq=1 ttl=58 time=1.60 ms
64 bytes from 162.159.192.1: icmp_seq=2 ttl=58 time=1.60 ms

新建compose文件:

mkdir -p /opt/rustatio && cd /opt/rustatio && nano docker-compose.yml

写入如下内容:

services:
  gluetun:
    image: qmcgaw/gluetun
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      - VPN_SERVICE_PROVIDER=custom
      - VPN_TYPE=wireguard
      - WIREGUARD_ENDPOINT_IP=162.159.192.1
      - WIREGUARD_ENDPOINT_PORT=2408
      - WIREGUARD_PUBLIC_KEY=
      - WIREGUARD_PRIVATE_KEY=
      - WIREGUARD_ADDRESSES=10.64.1.89/32
      - HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE={"auth":"none"}
    ports:
      - "30080:8080"  # Rustatio Web UI

  rustatio:
    image: ghcr.io/takitsu21/rustatio:latest
    container_name: rustatio
    restart: unless-stopped
    network_mode: service:gluetun
    depends_on:
      gluetun:
        condition: service_healthy
    environment:
      - PORT=8080
      - RUST_LOG=${RUST_LOG:-info}
      - PUID=${PUID:-1000}
      - PGID=${PGID:-1000}
      - AUTH_TOKEN=adminpasswd
      # Optional: Watch folder configuration (auto-detected if volume is mounted)
      - WATCH_AUTO_START=false  # Set to true to auto-start faking new torrents
    volumes:
      - rustatio_data:/data
      # Optional: Uncomment to enable watch folder feature
      # - ${TORRENTS_DIR:-./path/to/your/torrents}:/torrents

volumes:
  rustatio_data:

注意事项:

1.在Gluetun中使用HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE={"auth":"none"}是不安全的配置,但是我们没有暴露控制服务器的端口,所以这里没有影响,并且这样配置是迫不得已的,因为Rustatio目前不支持通过身份验证访问Gluetun的API。

2.设置Rustatio Web UI的访问密码请修改AUTH_TOKEN=

启动:

docker compose up -d

访问IP:30080,输入AUTH_TOKEN=的值登录:

如果Gluetun工作正常,则这里应该会显示VPN的IP:

效果:

Gluetun的玩法其实很多,很多老外都是把Gluetun和qBittorrent配合起来一起使用,下BT可以避免DMCA等问题。Gluetun还内置了一个shadowsocks,当然本文没有配置这些,有兴趣可以自己折腾。至于Rustatio,这里再次强调:本文只是分享信息,此工具仅供教育用途。篡改BitTorrent追踪器的上传/下载统计数据可能违反私有追踪器的服务条款,并可能导致账户被暂停或封禁。使用风险自负。

参考:

https://github.com/qdm12/gluetun-wiki/blob/main/setup/providers/custom.md
https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md