2026-05-17 17:18:20
我一直想在openSUSE Tumbleweed下使用GUI.for.SingBox。说真的想了很久了,每次GUI.for.SingBox发布新版本我都会下载一个尝试运行,但很遗憾每次运行都会报错:
Gdk-Message: Error 71 (Protocol error) dispatching to Wayland display
我问过AI也试过Google搜索到的几乎所有解决方法,以及官方频道和讨论群组提到类似问题的解决方法,包括但不限于:
https://t.me/GUI_for_Cores/27078
https://forums.opensuse.org/t/gdk-message-error-71-protocol-error-dispatching-to-wayland-display/178886
https://discussion.fedoraproject.org/t/gdk-message-error-71-protocol-error-dispatching-to-wayland-display/127927
https://github.com/tauri-apps/tauri/issues/10702#issuecomment-2327642878
很可惜全部都不起作用,甚至我切换到x11也无法正常运行,只是在x11下不报错,但打开是白屏。
有趣的是我最近从kde plasma切换到niri了,你猜怎么着?GUI.for.SingBox竟然能够正常运行了。。。你就说神奇不神奇吧。。。似乎又多了一个让我继续使用niri的理由,哈哈。
说真的Linux有时候就是这样,真的很玄学很魔幻。
2026-05-17 15:36:14
最近niri和hyprland这类wayland平铺窗口合成器很热门,我也想在opensuse tumbleweed上试用一下,结果安装好还没开始折腾就卡住了:
从sddm登录kde plasma一切正常,登录niri或者hyprland屏幕就一直黑屏,但也有小概率是正常的,极低概率,可能10次登录里面能有1次是正常的。黑屏的时候我通过dmesg发现会报上图所示的错误,然后我根据这个报错信息去找解决办法,以下方法全部都试了个遍,没有一个能解决的:
Failed_to_apply_atomic_modeset
flip-event-timeout-error-on-startup
nvidia-drm-error-message-on-boot
问ai吧就一直让我开drm,除了开drm还是drm,我也是很无语。。就当我准备放弃的时候,我在opensuse论坛偶然看到了一个帖子:lts kernel for tumbleweed available how to switch
我才知道原来tw还有一个lts内核可以使用,然后我突然想到最近tw刚上了7.0内核,这个n卡闭源驱动也是kmp包,会不会是n卡闭源驱动和最新的7.0内核有bug导致的?我就想试试看装个lts内核能不能解决,本来是不报希望的,结果你猜怎么着?还真解决了!对就是这么简单,换个内核就解决了:
sudo zypper in kernel-longterm
可以看到安装这个lts内核的时候,会自动把nvidia闭源驱动也一并安装。这个kmp包安装的驱动版本和7.0内核是完全一样的,7.0安装的也是580.159.03:
安装完成后重启系统在GRUB引导阶段选择如图所示菜单:
选择刚安装的lts内核引导即可:
说实话有点歪打正着了=。=挺有趣的,记录一下,也许能帮到和我遇到一样问题的人。
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
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。其他流量还是直接走中转鸡。
2026-04-18 11:17:50
BluFiles特征:
安装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
效果:
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,绰绰有余。