跳到主要内容

NAS实践

阅读量

0

阅读人次

0

在折腾完软路由之后,发现其还可以做很多事,但是R86s只能插一个NVME的固态硬盘,很容易数据损坏。

Unraid

Unraid是个不错的系统,我当时最喜欢的一点是,他是用U盘作为数据盘,所以理论上所有的SATA口和NVME口都可用作数据盘。基于这个原因,一咬牙就买入了Pro版。

安装

在安装完成后,最先碰到的问题就是无法下载应用插件。

  1. 首先先在 设置日期和时间 更新国内能正常访问的 NTP 服务器,设置正确的时区,确保时间正确。
  2. 因为 unraid 的插件基本上都是存放在 github 上的,而国内不知道为啥总是污染 raw.githubusercontent.com 这个域名的解析,导致下载失败。所以我们可以将正确的 IP 地址解析加入 /etc/hosts 文件中。

DNS Lookup 搜索 raw.githubusercontent.com 的 IP 为 185.199.110.133。修改 /etc/hosts:

/etc/hosts
185.199.110.133 raw.githubusercontent.com

Unraid除了提供了奇偶校验数据盘的特性,还集成了Docker以及虚拟机的支持。有了Docker,我们可以部署很多应用,当然,占用的端口也多了。

Unraid自带的功能多了,但是感觉又变得相对不稳定了,特别是对于想要折腾 All in One 的人来说,在最开始折腾的过程中,特别是在使用VFIO将PCI设备直通到虚拟机的情况。

提示

无论是什么情况下,都请先备份好U盘里面的所有文件,然后再进行操作!

有遇到网卡 eth0 eth1 顺序调换导致不能通过管理网口访问的情况,此时网卡直通出现了混乱导致的。(这种情况总是碰到)

有遇到PCI直通出问题,导致虚拟机无法自启动的。

总结下来,好像都和直通有关系。如果不想重装系统,这个时候就只能插上显示器,通过终端使用命令行来解决问题了。所以下文会记录一些命令帮助使用命令行来解决问题。

/boot/config/vfio-pci.cfg:这个文件应该就是我们在 工具系统设备 下选择使用 vfio 进行直通的设备的 pci 编号。其内容大致如下,以空格作为分隔符:

BIND=0000:01:00.0|1002:6779 0000:01:00.1|1002:aa98 0000:00:1f.0|8086:a305 0000:00:1f.3|8086:a348 0000:00:1f.4|8086:a323 0000:00:1f.5|8086:a324 0000:00:1f.6|8086:15bc 0000:03:00.1|8086:10fb

有时候我们换了PCI设备,但是其编号在留在里面,这会导致虚拟机无法自启动。这时就需要我们仔细排查 vfio-pci.cfg 文件,看看哪个PCI设备已经没有了。

针对无法使用管理网口的问题:

  1. 首先,我们需求查看 vfio-pci.cfg 文件,来确定这个网口是不是被直通了。如果被直通了,那就将它的编号删除,然后重启。

  2. 通过 virsh 将使用了直通网口的虚拟机(或者全部虚拟机)关掉自启动,排除下是不是因为虚拟机导致无法使用管理网口。

  3. 检查 /boot/config/network.cfg 文件,

  4. 最后实在搞不定,终结大招就是把上述 vfio-pci.cfgnetwork.cfg 两个文件都删了。unraid 会默认生成 network.cfg 文件,以 dhcp 方式获取 IP 地址。默认内容如下:

    # 表示使用 DHCP 服务器自动获取 IP 的方式向路由器申请 IP 给到 unRAID 使用。 
    USE_DHCP="yes"

    # 当前 unRAID 的内网 IP
    IPADDR=

    # 子网掩码,一般的值为 255.255.255.0
    NETMASK=

    # unRAID 的网关
    GATEWAY=

    # 是否启用绑定(默认为 yes )
    BONDING="yes"

    # 是否启用桥接(默认为是 yes )
    BRIDGING="yes"

    如果需要静态IP,可作如下配置:

    # 取消 DHCP 自动获取 IP。
    USE_DHCP="no"

    # 请将 IPADDR 的值设置为你需要的 IP 。
    IPADDR="192.168.2.3"

    # NETMASK 不需要修改。
    NETMASK="255.255.255.0"

    # GATEWAY 是网关地址,根据你自己实际的情况来。
    GATEWAY="192.168.2.1"

    # BONDING 和 BRIDGING 不需要修改,等你能够访问 unRAID 之后再在网络设置中修改即可。
    BONDING="yes"
    BRIDGING="yes"

    # DNS 服务器地址,可以填写两个,根据你的需求来。
    DNS_SERVER1="192.168.2.1"
    DNS_SERVER2="114.114.114.114"

当然,我们也可以仅修改 USE_DHCP="no" 这一行,然后通过 ifconfig 命令暂时配置 IP:

ifconfig br0 192.168.2.3 netmask 255.255.255.0

然后使用 PC 修改静态IP保持同一网段直连 Unraid,最好是将 PC 的网关直接改成 Unraid 的 IP 地址。

等我们能够成功访问 Web 控制台的时候,再通过其修改 IP 地址获取方式。

使用代理

#!/bin/bash

DOCKER_RC_FILE="/etc/rc.d/rc.docker"
if [ -f "$DOCKER_RC_FILE" ]; then
sed -i 's|nohup|nohup env https_proxy=http://192.168.3.69:10809 http_proxy=http://192.168.3.69:10809|' "$DOCKER_RC_FILE" ;
fi

使用 User Scripts,选择在磁盘阵列启动时,执行上述脚本。

验证是否修改成功:

grep -n 'nohup env https_proxy' /etc/rc.d/rc.docker

更换 Docker 镜像源

以阿里云镜像源为例,在 镜像容器服务➡镜像工具➡镜像加速器 找到 加速器地址,然后在 Unriad /boot/config/go 添加如下内容:

mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://6bcoyx9o.mirror.aliyuncs.com"]
}
EOF

使用FRP

危险

使用FRP时,前往不要将Web访问端口直接映射出去。这样外网可以直接无需尼玛,直接跳转至URL。

可以使用FRP提供的 HTTP基本认证 实现账号密码验证登录(在nginx反向代理一侧,请使用HTTPS)。

[[proxies]]
name = "unraid"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["unraid.amass.fun"]
httpUser = "your_account"
httpPassword = "your_password"

Docker及端口占用

端口号组件作用
80Unraid访问Unraid
1022Ubuntu Develop容器用于开发调试,ssh 端口
1443NextCloud私有云盘
1883NanoMQMQTT TCP监听端口
2022Gitea ssh用于 pull/push 仓库
3000Gitea仓库镜像备份
3100HomeBox物品收纳管理
3306MySQL被NextCloud所用
8082CalibreCalibre webserver gui.
8083CalibreCalibre desktop gui.
8084calibre-webcalibre-web
8085librespeed用于内网测速
8087Code Server用于在线编写代码
8088reader电纸书阅读
8089Chevereto图片分享,图床
8096Jellyfin影音播放
8920Jellyfin HTTPShttps接口,通过 frpc + nginx 访问8096端口

Ubuntu

日常使用中,还是需要在NAS做一些事的,例如构建Docker镜像,体验一些应用等。这个时候是不推荐在 Unraid 上直接操作的,一个原因是 Unraid 是基于 Slackware 开发的,我不太熟悉这个系统。另一个更重要的原因是因为如果直接在 Unriad 做实验,会污染其环境或可能产生冲突增加其不稳定性,如果要导致数据不见了,或者需要重装 Unraid,那就非常麻烦了。

所以,比较好的方式就是我们自己构建一个 Ubuntu 的 Docker 镜像,然后在容器上做我们想做的事。

id amass # 确认amass用户的uid、gid
docker run -it --privileged -d -e PUID=1000 -e PGID=100 --network host --name ubuntu --hostname Ubuntu \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /mnt/user/appdata/code-server:/root/.local/share/code-server \
-v /mnt/user/appdata/code-server:/root/.config/code-server \
-v /mnt/user/appdata/vscode-server:/root/.vscode-server \
-v /mnt/user/appdata/frpc:/opt/frpc \
-v /mnt/user/Documents:/root/Documents \
-v /mnt/user/Backup/SourceCode:/root/SourceCode \
-v /mnt/user/Backup/Projects:/root/Projects \
registry.cn-shenzhen.aliyuncs.com/amass_toolset/ubuntu_dev:24.04

docker exec -it ubuntu bash

在本地 ssh config 配置:

C:/Users/amass/.ssh/config
Host ubuntu_unraid
HostName 192.168.3.3
User root
IdentityFile E:/Projects/id_rsa_amass
Port 1022

IdentityFile 在 Windows 下的权限问题:

Bad permissions. Try removing permissions for user: NT AUTHORITY\\Authenticated Users (S-1-5-11) on file E:/Projects/id_rsa_amass.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'E:\\Projects\\id_rsa_amass' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "E:\\Projects\\id_rsa_amass": bad permissions

使用命令行修改权限:

# 移除 NT AUTHORITY\\Authenticated Users 的权限
icacls "E:\Projects\id_rsa_amass" /remove "NT AUTHORITY\Authenticated Users"

# 确保只有当前用户(假设用户名为 amass)有权限访问
icacls "E:\Projects\id_rsa_amass" /inheritance:r
icacls "E:\Projects\id_rsa_amass" /grant:r amass:F

Code Server

下载 C/C++ 插件,然后手动安装。

frp

frp的具体使用可以参考之前写的笔记,这里使用Docker运行frpc, 如下使用了多个 frp 服务以便于在不同网络环境下不同来回切换而同时使用:

docker run --restart=always --network host -d --name frpc \
-e TZ="Asia/Shanghai" \
-v /mnt/user/appdata/frpc/frpc.toml:/etc/frp/frpc.toml \
registry.cn-shenzhen.aliyuncs.com/amass_toolset/frpc:0.60.0

docker run --restart=always --network host -d --name mirror_frpc \
-e TZ="Asia/Shanghai" \
-v /mnt/user/appdata/frpc/mirror_frpc.toml:/etc/frp/frpc.toml \
registry.cn-shenzhen.aliyuncs.com/amass_toolset/frpc:0.60.0

docker run --restart=always --network host -d --name wwooww_frpc \
-e TZ="Asia/Shanghai" \
-v /mnt/user/appdata/frpc/wwooww_frpc.toml:/etc/frp/frpc.toml \
-v /mnt/user/appdata/frpc:/app \
registry.cn-shenzhen.aliyuncs.com/amass_toolset/frpc:0.60.0

如果我们想自己构建frpc,可以参考,我构建的 frpc 集成了 nginx,这样方便我们通过 frp 使用 https 访问,然后再将请求反向代理至内部服务,以 jellyfin 为例:

upstream jellyfin {
server 192.168.2.3:8096;
}

server {
listen 8920 ssl;
server_name frp-by1.wwvvww.cn;

ssl_certificate /config/cert/frp-by1.wwvvww.cn_bundle.pem;
ssl_certificate_key /config/cert/frp-by1.wwvvww.cn.key;
ssl_session_timeout 5m; #缓存有效期
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #加密算法
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #安全链接可选的加密协议
ssl_prefer_server_ciphers on; #使用服务器端的首选算法

location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header x-wiz-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://jellyfin;
}
}

v2rayA

v2rayA 是一个易用而强大的,跨平台的 V2Ray 客户端。

  • 全局透明代理:透明代理可为几乎所有应用程序提供代理服务,而不必考虑该应用程序是否支持。在 Linux 系统,v2rayA 支持一键开启透明代理,省去了繁琐的配置操作。在 Windows 和 MacOS 支持一键配置系统代理。
  • 外部访问:对于无图形界面的操作系统,在安装 v2rayA 之后,借助另一台 PC 或移动设备即可完成对其的操作。这对于远程服务器、路由器是极其方便的。
docker run -d --restart=always --privileged --network=host --name v2raya \
-e TZ="Asia/Shanghai" \
-e V2RAYA_LOG_FILE=/etc/v2raya/v2raya.log \
-e V2RAYA_V2RAY_BIN=/usr/local/bin/v2ray \
-e V2RAYA_NFTABLES_SUPPORT=off \
-e IPTABLES_MODE=legacy \
-v /lib/modules:/lib/modules:ro \
-v /etc/resolv.conf:/etc/resolv.conf \
-v /mnt/user/appdata/v2raya:/etc/v2raya \
mzz2017/v2raya

安装完成之后,打开 http://192.168.3.3:2017 即可访问 v2rayA 主页。

jellyfin

jellyfin 的介绍可以查看这里。其中不同的是 PVE 下面我们使用是 LXC 方式,且镜像基于 Debain 构建。这里我们使用 docker,镜像基于 Ubuntu 构建,而且每通过 docker 修改一次配置,容器内的数据就会被删除(比如安装包、字体)。这里我们创建一个shell脚本(主要是配置中文环境)存放在 /mnt/user/appdata/jellyfin 目录下,以便每次重新生成docker容器时进行合适的配置安装。

最近发现了 Jellyfin中国特供版,作者是中国人,很厉害,佩服。

显卡直通硬解

对于 英特尔® 酷睿™ i5-9600K 处理器,在 Unraid 添加所需的 i915 内核参数以启用加载 GuC 和 HuC 固件:

/etc/modprobe.d/i915.conf
# blacklist i915   # 如果阻止加载 i915 模块,下面的设置将不起作用
options i915 enable_guc=2

如果安装了 Intel-GVT-g 插件,那么就不需要手动修改 /etc/modprobe.d/i915.conf 文件(修改了重启后也会被覆盖掉)。在 Guide 标签页下找到 GuC/HuC Firmware loading:,选择 3 = Enable Guc/Huc

如果客户端播放视频提示 该客户端与媒体不兼容,服务器未发送兼容的媒体格式,则大概率上述配置没配置好。

创建直通时,将 /dev/dri 映射至 jellyfin 容器中(配置类型选择 设备,不是 路径),然后在 播放 选项卡中设置硬件加速 Intel QuickSync (QSV)

命令行创建,则为 --device=/dev/dri

11 代之前的处理器仅支持启用低电压模式的 Intel H.264 硬件编码器。

启用色调映射

设置完整后,可以播放一个视频,然后选择一个比较低的质量播放。最后在 unRaid 命令行运行 intel_gpu_top,观察核显的利用率是否有变化。

docker run -d --name=jellyfin \
-e TZ=Asia/Shanghai \
-e 'JELLYFIN_PublishedServerUrl'='http://192.168.3.3/jellyfin' \
-e PUID=1000 \
-e PGID=100 \
-v /mnt/user/AdultVideo:/mnt/user/AdultVideo \
-v /mnt/user/Animes:/mnt/user/Animes \
-v /mnt/user/AnimeTheaters:/mnt/user/AnimeTheaters \
-v /mnt/user/Movies:/mnt/user/Movies \
-v /mnt/user/ShortDramas:/mnt/user/ShortDramas \
-v /mnt/user/Teleplays:/mnt/user/Teleplays \
-v /mnt/user/appdata/jellyfin:/config \
--net=host \
--restart=unless-stopped \
--device=/dev/dri nyanmisaka/jellyfin:241027-amd64

乱码

docker exec -it jellyfin bash
sed -i 's@//.*archive.ubuntu.com@//mirrors.ustc.edu.cn@g' /etc/apt/sources.list
apt update && apt upgrade -y
apt install -y fonts-noto-cjk-extra
exit # 退出容器
docker restart jellyfin

这个出现乱码的原因是一些字幕文件(例如.ass)里面指定了字体,但是系统没有这个字体,所以就会导致出现乱码。解决的办法就是将字符放入docker容器可访问的路径下,然后在 控制台播放 下找到 备用字体文件路径,将字体文件路径填入,并勾选 启用备用字体 来使能 Fallback 机制。

反向代理

管理控制台高级网络 中将基础 URL设为 /jellyfin。设置 nginx 规则:

upstream jellyfin {
server 192.168.3.3:8096;
}

# Security / XSS Mitigation Headers
# NOTE: X-Frame-Options may cause issues with the webOS app
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "0"; # Do NOT enable. This is obsolete/dangerous
add_header X-Content-Type-Options "nosniff";

# Permissions policy. May cause issues with some clients
add_header Permissions-Policy "accelerometer=(), ambient-light-sensor=(), battery=(), bluetooth=(), camera=(), clipboard-read=(), display-capture=(), document-domain=(), encrypted-media=(), gamepad=(), geolocation=(), gyroscope=(), hid=(), idle-detection=(), interest-cohort=(), keyboard-map=(), local-fonts=(), magnetometer=(), microphone=(), payment=(), publickey-credentials-get=(), serial=(), sync-xhr=(), usb=(), xr-spatial-tracking=()" always;

# Content Security Policy
# See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
# Enforces https content and restricts JS/CSS to origin
# External Javascript (such as cast_sender.js for Chromecast) must be whitelisted.
# NOTE: The default CSP headers may cause issues with the webOS app
add_header Content-Security-Policy "default-src https: data: blob: ; img-src 'self' https://* ; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.gstatic.com https://www.youtube.com blob:; worker-src 'self' blob:; connect-src 'self'; object-src 'none'; frame-ancestors 'self'";

# Jellyfin
location /jellyfin {
proxy_pass http://jellyfin/;
}

# The / at the end is significant.
# https://www.acunetix.com/blog/articles/a-fresh-look-on-reverse-proxy-related-attacks/
location /jellyfin/ {
# Proxy main Jellyfin traffic
proxy_pass http://jellyfin;
proxy_pass_request_headers on;
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 X-Forwarded-Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;

# Disable buffering when the nginx proxy gets very resource heavy upon streaming
proxy_buffering off;
}

location /jellyfin/socket {
# Proxy Jellyfin Websockets traffic
proxy_pass http://jellyfin;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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 X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
}

MySQL

MySQL需要作为nexcloud和gitea的数据库。使用 unRaid 的应用市场安装,会经常提示更新,数据库很重要,这里我们手动维护,避免MySQL不能使用,或被修改。

mkdir -p /mnt/user/appdata/mysql-official \
&& touch /mnt/user/appdata/mysql-official/error.log \
&& chmod -R 777 /mnt/user/appdata/mysql-official

docker run -d --restart=unless-stopped --name=MySQLServer -e TZ="Asia/Shanghai" -p 3306:3306 \
-e 'MYSQL_ROOT_PASSWORD'='your_password' \
-v /mnt/user/appdata/mysql-official/data:/var/lib/mysql \
-v /mnt/user/appdata/mysql-official:/var/log/mysql \
-v /mnt/user/appdata/mysql-official/conf.d:/etc/mysql/conf.d \
-v /mnt/user/appdata/mysql-official/initdb:/docker-entrypoint-initdb.d \
mysql:8.4.2 mysqld --log-error=/var/log/mysql/error.log
危险

重要数据的容器应用,不要使用 latest 标签!它会一直更新,且你很一直追踪到其真正的版本。

我在实际使用时,遇到了不同镜像源下,其 latest 的版本不一致,导致数据出现不兼容的现象!

重要数据的docker应用也不应经常更新!更新前,做好数据备份

2024/10/10:今天尝试将 MySQL 更新到 9.0 版本,结果导致 Nextcloud 无法正常运行,辛亏通过 Unraid 的 Appdata.Backup 做了下一周一次备份,可以恢复之前的数据。这次的代价是丢失了三天的数据,如果不做备份,后果很严重。

MySQL 8.4 开始 mysql_native_password 默认不会加载,导致 Nextcloud 无法正常运行。

/mnt/user/appdata/mysql-official/conf.d
[mysqld-8.4]
mysql_native_password=on
chmod 644 /mnt/user/appdata/mysql-official/conf.d
docker restart MySQLServer

Collabora-CODE

Collabora-CODE 是一个支持在线Office编辑的后台服务应用,我们可以在unRaid应用商店添加,给后续 Nextcloud 使用。

docker run -d --name collabora --restart always --privileged -e TZ="Asia/Shanghai" -e username=amass -e 'password'='your_password' -e 'dictionaries'='de_DE en_GB en_US es_ES fr_FR it nl pt_BR pt_PT ru' -e 'domain'='frp-by1.wwvvww.cn' -p 9980:9980 collabora/code

如果需要外网访问(外网通过Nextcloud访问 Office 文档也算),需要添加 Nginx 的反向代理。实际使用中,发现其完全可以与Jellyfin共用一个Nginx反向代理服务配置。这样就可以减少一个frp端口的映射。

Nextcloud

Nextcloud作为一个私有云盘,功能是非常丰富的。特别是配合大宽带的 frp 服务时。

docker pull linuxserver/nextcloud:latest
id amass # 确认amass用户的uid、gid
docker run -d --privileged --restart unless-stopped --name Nextcloud \
-e PUID=1000 -e PGID=100 -e TZ=Asia/Shanghai -p 5678:80 -p 1443:443 \
-v /mnt/user/Backup/Nextcloud:/data \
-v /mnt/user/appdata/nextcloud:/config \
lscr.io/linuxserver/nextcloud:latest

External storage support:这个应用插件可以让个人网盘之外的其他文件夹(例如Unraid的共享文件夹)也能被用户访问到,配合Unraid来使用,我觉得非常方便。

提示

在挂载时,需要使用SMB挂载外部存储,否则以本地挂载时,创建文件的用户为 nobody,会导致其他用户无修改文件权限。

External sites:可以集成外部链接在导航栏上,外部内容直接显示至 Nextcloud 的 Frame 中而不是另打开一个标签页,使其更加集成化。

Nextcloud Office:使得Nextcloud支持编辑Office文档。插件下载成功后,在管理设置Nextcloud Office选择使用您的自由服务器。服务器地址为:https://frp-by1.wwvvww.cn:25538(目前与Jellyfin共用),点击保存,在该页面上方就看看到 Collabora Online 服务器可以访问。 的提示。

Notes:使其可以成为一个Markdown的笔记本,笔记以markdown文件形式存在于云盘。

Tasks:使其可以集成成为任务清单

Configurable Share Links:能够自定义文件分享链接。

添加信任域名 与 SSL 证书

修改/mnt/user/appdata/nextcloud/www/nextcloud/config/config.php文件,详情可参考 参数配置 一节:

  'trusted_domains' =>
array (
0 => '192.168.2.3',
1 => 'frp-by1.wwvvww.cn',
),
'overwritewebroot' => '/nextcloud',
'overwrite.cli.url' => 'https://frp-by1.wwvvww.cn:25538/nextcloud',

如上所示在 array 中添加域名,可以不用写端口号。

使用 nginx 进行反向代理:

location /nextcloud {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass https://192.168.3.3:1443/;

proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}

然后向frp供应商索取 SSL 证书,将其替换至 /mnt/user/appdata/nextcloud/keys。或者根据需求修改 /mnt/user/appdata/nextcloud/nginx/ssl.conf

配置电子邮箱服务器

管理设置➡基本设置➡电子邮件服务器可以配置电子邮箱服务器,用于邮件推送通知。

QQ邮箱为例,按照说明:

  • 发送模式:SMTP
  • 加密:SSL
  • 身份认证:✔需要认证
  • 证书:QQ邮箱地址、SMTP授权码

配置完成后,点击发送电子邮件测试,如邮箱收到测试邮件,则配置成功。

修改个人资料

添加电子邮箱、位置和地区语系。这样就可以将一些单位变成地区常用单位,比如从℉变为℃ ,还有时区也会对应更新。

occ 命令

Nextcloud 提供了一个 occ 命令,文档是说源自于 ownCloud Console。有时候我们可以使用它(比如Web端出现BUG无法使能 app):

docker exec -it -u 1000 nextcloud bash  # 以 uid为1000的用户进去 bash 命令行,因为我们创建容器的时候指定了uid不为root
/app/www/public/occ list # 列出 occ 支持的命令
/app/www/public/occ app:list # 列出 目前已安装的app
/app/www/public/occ app:enable files_external # 使能files_external

从文件安装

将文件拷贝至 /mnt/user/appdata/nextcloud/www/nextcloud/apps,解压。然后执行 occ 命令进行安装。

All-In-One Docker Image

Nextcloud 官方提供了一个基于 Docker 的 AIO 项目,但是其必须要使用 443 作为 HTTPS 端口。在 Readme 下这样写着:

Are other ports than the default 443 for Nextcloud supported?

No and they will not be. ...

这明显不适合我们的需求,没有公网IP。

Gitea

Gitea 是一个轻量级的 DevOps 平台。它为团队和开发人员带来了从规划到生产的高效且轻松的操作。

以前选择使用 Gitea 二进制可执行文件在服务器上进行部署,现在觉得部署和备份成本太高,还是 docker 镜像比较方便快捷。

id amass # 确认amass用户的uid、gid
docker run -d --restart=always --name=gitea \
-p 2022:22 -p 3000:3000 \
-e USER_UID=1000 -e USER_GID=100 \
-e TZ="Asia/Shanghai" \
-v /mnt/user/appdata/gitea:/data \
gitea/gitea:1.22.3

参考 反向代理 一节,修改配置文件:/mnt/user/appdata/gitea/gitea/conf/app.ini

[server]
ROOT_URL = https://amass.fun/gitea
SSH_DOMAIN = frp-by1.wwvvww.cn
SSH_PORT = 22022

[service]
# 禁止外部用户自己注册,只能管理员创建账号
DISABLE_REGISTRATION = true

# 开启 Gitea Actions 功能
[actions]
ENABLED = true

Act Runner

Linux下的搭建可以参考Git Act Runner Docker镜像构建。这里我们记录Windows下的搭建步骤,先向Gitea服务器进行注册:

.\act_runner.exe register --no-interactive --instance https://amass.fun/gitea \
--token your_token --name windows11_unraid --labels windows11

注册成功后会在当前文件夹下生成一个.runner文件。如果想重新进行修改注册,可以删掉这个文件然后再次执行上述命令。

执行:

.\act_runner.exe daemon

即可启动 Act Runner 以接收并执行后续对应Gitea服务器的 actions。不过为了使得其可以开机运行,我们借助WinSW创建Windows服务,下载WinSW的可执行程序WinSW-x64.exe,拷贝到act_runner.exe所在的目录下。注意目录路径不能有空格和非ASCII字符。

WinSW-x64.exe命名成act_runner-service.exe(事实上名字任意,只要和后面的xml文件同名即可),再创建配置文件:

D:\gitea\act_runner-service.xml
<!-- act_runner-service.xml -->
<service>
<id>act_runner</id>
<name>act_runner</name>
<description>Act runner is a runner for Gitea based on Gitea fork of act.</description>
<executable>D:\gitea\act_runner.exe</executable>
<onfailure action="restart" delay="5 sec" />
<resetfailure>1 day</resetfailure>
<arguments>daemon</arguments>
<workingdirectory>D:\gitea</workingdirectory>
<priority>AboveNormal</priority>
<stoptimeout>15 sec</stoptimeout>
<stopparentprocessfirst>false</stopparentprocessfirst>
<startmode>Automatic</startmode>
<waithint>15 sec</waithint>
<sleeptime>1 sec</sleeptime>
<logpath>D:\gitea\logs</logpath>
<log mode="roll-by-time">
<pattern>yyyyMMdd</pattern>
</log>
</service>

然后执行如下命令:

.\act_runner-service.exe install 	# 安装这个service
.\act_runner-service.exe start # 启动这个service

下载并安装Node.jsGit for Windows

执行如下命令,以让Windows可以成功执行任何powershell脚本:

Set-ExecutionPolicy Unrestricted

NanoMQ

NanoMQ 是于 2021 年初发布的边缘计算开源项目,是面向物联网边缘计算场景的下一代轻量级高性能 MQTT 消息服务器。

docker run -d --rm --name nanomq emqx/nanomq:0.21-full # 临时生成容易
docker cp nanomq:/etc/nanomq.conf /mnt/user/appdata/nanomq/ # 拷贝默认的 nanomq.conf 文件
docker cp nanomq:/etc/nanomq_pwd.conf /mnt/user/appdata/nanomq/
docker run -d --name nanomq -p 1883:1883 -p 8083:8083 -p 8883:8883 -v /mnt/user/appdata/nanomq/nanomq.conf:/etc/nanomq.conf -v /mnt/user/appdata/nanomq/nanomq_pwd.conf:/etc/nanomq_pwd.conf emqx/nanomq:0.21-full

具体帮助可查看NanoMQ 文档,这里不做过多介绍。

通过 MQTTX 客户端工具 来体验 NanoMQ 的消息服务。

Home Assistant

Home Assistant 是一个自由开源的智能家居自动化平台。

docker run -d \
--name homeassistant \
--privileged \
--restart=unless-stopped \
-e TZ="Asia/Shanghai" \
-v /mnt/user/appdata/homeassistant:/config \
-v /run/dbus:/run/dbus:ro \
--network=host \
ghcr.io/home-assistant/home-assistant:2024.7.2

访问主页:http://192.168.3.3:8123。在做反向代理时,需要添加如图下配置,否则服务会返回400:

configuration.yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 111.173.106.175 # Add the IP address of the proxy server
- 127.0.0.1

Home Assistant Community Store

HACS 是一个很重要的插件,更新很及时。Home Assistant 默认自带的插件,基本都用不了。

docker exec -it homeassistant bash
wget -O - https://get.hacs.xyz | bash - # 创建 custom_components 文件夹,然后将 hacs 下载解压至该目录
docker restart homeassistant # 安装任何 custom_components 都重启容器

Xiaomi Miot For HomeAssistant

Xiaomi Miot Auto 提供了接入米家设备

kiosk-mode

kiosk-mode 可以用来自定义是否显示一些页面组件,例如标题栏。隐藏标题栏后,如果想让标题栏暂时显示,即kiosk-mode暂时生效,可以在当前 url 路径后添加 ?disable_km

MoneyNote

MoneyNote 是一个开源免费的记账解决方案。是国人自己兴趣开发的,所以比较符合国人使用习惯。使用文档提供了一些常见的记账案例。

docker run --name moneynote -d -e DB_HOST=192.168.2.3 -e DB_PORT=3306 -e DB_NAME=moneynote -e DB_USER=root -e DB_PASSWORD=your_password -e invite_code=111111 -p 43742:9092 -p 43743:81 -p 43744:82 registry.cn-hangzhou.aliyuncs.com/moneynote/moneynote-all-no-mysql:latest

其中:

  • DB_HOST、DB_PORT:MySQL 数据库地址、端口。
  • DB_NAME:在 MySQL 中创建的数据库名称
  • DB_USER、DB_PASSWORD:MySQL 的用户名及密码。
  • invite_code:可自定义,MoneyNote 注册用户页面需要用到。

Homebox

Homebox 是一个方便家庭进行资产管理的系统。虽然自己没啥东西,但是对于经常健忘,忘记买了啥东西,要用的时候先用 Homebox 找一找自己以前有没有买过,还是很实用的。

Calibre/reader

Calibre 作为电子图书管理很有名,目前还找不到什么能够替换它的。在 Github 上找到了国人开发 reader 的项目

docker run -d --restart=always --name=reader \
-p 8088:8080 \
-v /mnt/user/appdata/reader/logs:/logs \
-v /mnt/user/appdata/reader:/storage \
hectorqin/reader java -jar /app/bin/reader.jar \
--spring.profiles.active=prod \
--reader.app.secure=true \
--reader.app.secureKey=管理密码 \
--reader.app.inviteCode=注册邀请码

Calibre 存储文件时,会将中文转换成拼音,按理来说,其实是无所谓的。因为它的导出到硬盘,提供了不过的规则设置。作者也希望我们使用上,也不需要关注Calibre管理的书库路径。我们可以通过补丁实现Calibre在保存文件时,不进行拼音化。这里需要注意的是补丁和Calibre版本需要对应上,否则替换完之后,会打不开Calibre。

替换 /opt/calibre/lib/calibre-extensions/python-lib.bypy.frozen 文件。

Movie Data Capture

这是一个视频刮削工具。

docker run --rm --name avdc -it -v ${PWD}:/data -v /mnt/user/appdata/avdc:/config -e PUID=1000 -e PGID=100 ghcr.io/vergilgao/mdc:latest
mdc.ini
[common]
jellyfin = 1

[priority]
website = madou,jav321,fanza,xcity,mgstage,fc2,avsox,dlsite,carib,getchu,javdb,gcolle,javday,javmenu,pcolle,caribpr,msin,javbus,airav

Meilisearch

一直在尝试各种不同的文本搜索引擎,是为了给博客添加一个搜索栏,目前发现 Meilisearch 对中文支持稍微友好一点。Algolia DocSearch 目前发现比较好用一点,但是它不支持本地部署,云服务在我试用了一次后,第二次不知道什么原因就无法使用了。Typesense 同样也轻量简单易于本地部署,但是目前发现对中文支持没有 Meilisearch 好。

使用 Docker 部署Meilisearch,meilisearch-docsearch 替换 Docusaurus 的 SearchBar(可以参考 tauri-docs)。

为网址添加搜索栏

# 生成 --master-key
docker run -it --rm --name meilisearch \
-p 7700:7700 \
-v /mnt/user/appdata/meilisearch:/meili_data \
getmeili/meilisearch:v1.10

docker run -d --name meilisearch --restart=unless-stopped \
-e TZ="Asia/Shanghai" \
-p 7700:7700 \
-v /mnt/user/appdata/meilisearch:/meili_data \
getmeili/meilisearch:v1.10 \
meilisearch --master-key=your_master_key

docker run -t --rm \
--network=host \
-e MEILISEARCH_HOST_URL='http://localhost:7700' \
-e MEILISEARCH_API_KEY='your_master_key' \
-v /mnt/user/appdata/meilisearch/meilisearch.json:/docs-scraper/config.json \
getmeili/docs-scraper:latest pipenv run ./docs_scraper config.json

curl -X GET 'http://localhost:7700/keys' \
-H 'Authorization: Bearer your_master_key'

网心云

容器魔方教程 安装该容器:

docker pull  images-cluster.xycloud.com/wxedge/wxedge:latest
docker run -d --name=wxedge --restart=always --privileged --net=host --tmpfs /run --tmpfs /tmp -v /mnt/user/appdata/wxedge:/storage:rw images-cluster.xycloud.com/wxedge/wxedge:latest

运行成功后,打开 http://192.168.3.3:18888 即可进行容器魔方首页按提示操作。

User Scripts

User Scripts 是 Unraid 的一个插件,本质上就是 Cron 的一个前端GUI集成面板。

要添加自己的用户脚本,在 /boot/config/plugins/user.scripts/scripts 文件夹中创建一个新的文件夹用于存放脚本(文件夹名称可以随意,但只能包含以下字符:字母([A-Za-z])、数字([0-9])、连字符("-")、下划线("_")、冒号(":")、句点(".")和空格(" ")。其他字符会影响脚本后台运行的功能)。在该文件夹中,创建一个名为 description 的文件,其中包含脚本的描述。

创建一个名为 script 的文件,其中包含实际的脚本。在执行之前,#!/bin/bash 会自动添加到脚本开头。如果脚本有任何依赖项(例如:其他脚本),可以像往常一样调用,但请注意在执行期间,脚本不是从闪存驱动器运行的(即:请包含任何依赖脚本的完整路径)。

使用 SSH 备份远程服务器

我们将公私钥复制到 /boot/config/ssh/root 下(/root/.ssh的实际路径),

#description=备份阿里云服务器

REMOTE_USER="root"
REMOTE_HOST="47.107.32.69"
REMOTE_DIR="/root/Server"
LOCAL_DIR="/mnt/user/Backup/Duplicati"

DATE=$(date +%Y%m%d)
TAR_FILE="/tmp/Server-$DATE.tar.gz"

ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "tar --exclude='$REMOTE_DIR/logs' --exclude='$REMOTE_DIR/proxy_temp' -czvf $TAR_FILE $REMOTE_DIR"

scp -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST:$TAR_FILE $LOCAL_DIR
ssh -o StrictHostKeyChecking=no $REMOTE_USER@$REMOTE_HOST "rm $TAR_FILE"

echo "Backup completed for $DATE"

virsh

virsh 命令来自英文词组“virtualization shell”的缩写,中文译为虚拟化终端,其功能是用于管理虚拟机系统,virsh 是用于管理虚拟化环境中客户机和 Hypervisor 的命令行工具,是 libvirt 项目中的开源软件。

Unraid 使用 libvirt 管理 KVM。这里记录下常用的 virsh 命令,以便排查问题。

命令解释
virsh list --all列出所有虚拟机
virsh dominfo <名字 or ID>显示虚拟机硬件信息
virsh start <名字 or ID>开启虚拟机
virsh shutdown <名字 or ID>关闭虚拟机
virsh destroy <名字 or ID>强制关闭虚拟机
virsh undefine <名字 or ID>删除虚拟机,彻底删除需要确认删除 /mnt/user/domains/<名字> 目录
virsh edit <名字 or ID>编辑虚拟机配置。默认使用 vi 作为编辑器,可以修改:export EDITOR=nano
virsh autostart <名字 or ID>设置虚拟机为自动启动
virsh autostart --disable <名字 or ID>取消虚拟机自动启动

zsh

mkdir /boot/config/zsh
cd /boot/config/zsh
wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O install.sh
ZSH=/boot/config/zsh/oh-my-zsh sh install.sh
mv ~/.zshrc /boot/config/zsh/
ln -sb /boot/config/zsh/.zshrc /root/.zshrc
sed -i 's|\$HOME/.zsh_history|/boot/config/zsh/.zsh_history|g' /boot/config/zsh/oh-my-zsh/lib/history.zsh
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
mv ~/.p10k.zsh /boot/config/zsh/
ln -sb /boot/config/zsh/.p10k.zsh /root/.p10k.zsh

使用 User Scripts,在 At Startup of Array 时执行如下脚本命令:

#description=Unraid阵列启动后,恢复root的zsh环境
chsh -s $(which zsh)
ln -sb /boot/config/zsh/.zshrc /root/.zshrc
ln -sb /boot/config/zsh/.p10k.zsh /root/.p10k.zsh
cp /boot/config/zsh/.zsh_history /root/.zsh_history

定时备份 /root/.zsh_history

#description=备份root的zsh命令历史记录
cp /root/.zsh_history /boot/config/zsh/.zsh_history