从 0 到 1 的 NAS 记录

NAS 的各种记录喵~

新组的 NAS 已经运行三个月了,记录一下捣鼓这玩意的笔记和碎碎念,文章结构比较乱,算是给自己看的备忘。

前任

刚工作时我就产生了添置一台 NAS 的想法,但是当时并不打算常在那家公司干下去、而且住的是公司通过某种奇怪方式租的公租房(两人住一起空间不足),想法没有实现。

在去年四月换了份工作以及搬家后,捣鼓一套 NAS 的冲突愈演愈烈,最终在淘宝买了一套整机:一个四盘位的星际蜗牛,有着 J1900 CPU 和 4G RAM 的强悍配置,店家还帮预装了黑群晖(到手后自己装了 Windows)。

与其度过的开始几个月十分开心满意,因为这套配置差不多满足我的需求:

  • 存视频(SMB)
  • 存游戏(SMB)
  • 存书籍、漫画(SMB)
  • 日常文件备份(SMB)
  • 四盘位 RAID,总可用容量能有 8T 就好

后来看大家分享的 NAS 的强大功能,自己心里也越来越痒痒:我也想捣鼓虚拟机、想用 Docker、想拥有一票好看的媒体海报墙、也想身处家外也能够连回家看视频...

之前那套 NAS 虽然能用,但是各处细节都说不上好用,几乎所有功能都是基于 SMB 实现,啥操作都得用个文件管理器来捣鼓、看个视频都得点开层层目录。性能也不太行,作为游戏下载盘 Steam 经常会卡死。

本来吧,是打算这么将就着用的,但因为我消费主义入脑,着了 Intel 12 代 CPU 的魔...

第二台 NAS

在今年春节后,我受不住诱惑,把主力机的 CPU 换成了 12600KF,于是就有了一颗闲置的 i5 10400。

硬件

当时家里还有一个吃灰的【航嘉 暗夜猎手5】垃圾机箱和先马电源,加上这块 CPU,我组了个 mATX 的 NAS。后来自己加装了一块 4T 硬盘、和曾导通过一顿饭成功 PY 到一个【安钛克 GX900】机箱。目前配置大概是这样子:

配件 型号
CPU Intel i5 10400
散热器 玄冰 400
显卡 N/A
内存 主力机拆下来的 DDR4 2666 16G * 2
电源 先马金牌 500W
主板 微星 B460M 迫击炮 WiFi 版
机箱 安钛克 GX900
系统盘 金士顿 250G
数据盘 1 WD 1T
数据盘 2 WD 3T
数据盘 3 DW 4T

系统选择

机器装好后自然是装系统,NAS 可选系统真的很多,而且各自都很有特色。当时装系统到处看了很久,以下是我针对我个人需求的一些调研结果:

  • Windows:原来的 J1900 小鸡就是跑的 Windows 10 LTSC,不过因为性能关系,只开了一个 BitComet 和 SMB 服务。说实话 Windows 用作 NAS 系统没啥大问题,有很多丰富的软件和快捷的驱动支持,比如原生的 OneDrive、Office 套件、115、百度网盘,不需要额外操心的硬件解码等,没事甚至还能通过远程桌面连过来写代码(目前这台 NAS 的配置其实比我工作用的笔电要好)。除开一些独占原生软件的优势,像 Jellyfin、qBittorrent 等软件也有跨平台支持,还能用 Docker 弥补 Linux 独有软件的缺陷。最终没选择的原因是那个狗屎一般的 Hyper-V,不论是跑 Docker 还是 WSL2 都必须开 Hyper-V,隔着 Hyper-V 用 Docker 经常让我有种隔靴搔痒的感受,pass
  • unRAID:真实满足 NAS 各种需求的系统,但要购买授权,需要缓存盘,pass
  • Ubuntu:我最熟悉的 Linux 发行版,但作为 NAS 系统什么都要从零捣鼓,太费劲,pass
  • TrueNAS:官方建议使用 ECC 内存、Core 版本残疾 Docker,pass
  • ESXi:我没有那么多的虚拟化需求。而且虽然我没有版权洁癖,但这玩意其实是要许可证的,而我又买不起。考虑到破解可能带来的不稳定性和学习成本,pass。当然以后可能会以学习用途装一个玩玩
  • PVE:又是一个主打虚拟化的系统,我没那么多的这种类型的需求,所以 pass
  • 群晖:富佬专用,作为一款商业产品捆绑搭载的系统,我不想用没有官方支持的盗版,pass
  • OpenMediaVault:其实我对 OMV 印象就是一加了一套 OMV web 管理软件的 Ubuntu。当然这玩意基于 Debian,还有一些开箱即用的插件,比如 KVM、ZFS、Docker 等,用起来意外的顺手。最终选用 OMV 也是习惯使然,deb 系实在太亲切了

其实嘛,对我来说除了存储管理策略和包管理器外各系统用起来也没什么大差别,毕竟到最后都是跑 Docker。

装 OMV5 的时候有一些小插曲,OMV5 没有 b460m 迫击炮的 8125B 网卡驱动,查了下方案有以下:

  1. 没网卡驱动的情况下硬装 OMV,进系统后想办法把驱动装上
  2. 安装 Debian、安装驱动,然后安装 OMV 相关软件包

不论哪种都很复杂和畸形啊,看了下网上说 OMV6 内核比较新,直接支持这个网卡,遂上官网下载 testing (即 OMV6) 版本,一路顺利安装。

截至目前(2022 年 5 月 17 日),OMV6 已推出正式版。

OMV 系统装好后,进行一些配置:

  • omv extras

    wget -O - https://github.com/OpenMediaVault-Plugin-Developers/packages/raw/master/install | bash
    
  • 修改 ssh 端口

  • 日期:面板设置

    • 时区:Asia/Shanghai
    • 允许 ntp,设置服务器为阿里云 ntp ntp1.aliyun.com
  • 在 OMV 面板设置 S.M.A.R.T

  • 在 OVM 面板设置邮件提醒

  • 在 OMV 面板挂载磁盘

  • 在 OMV 面板设置 SMB 服务

  • 去插件面板安装 KVM、fail2ban、ZFS、Docker 等需要的插件

软件

V2rayA

安装:

curl -Ls https://mirrors.v2raya.org/go.sh | sudo bash
sudo systemctl disable v2ray --now
wget -qO - https://apt.v2raya.mzz.pub/key/public-key.asc | sudo tee /etc/apt/trusted.gpg.d/v2raya.asc
echo "deb https://apt.v2raya.mzz.pub/ v2raya main" | sudo tee /etc/apt/sources.list.d/v2raya.list
sudo apt update
sudo apt install v2raya
sudo systemctl start v2raya.service
sudo systemctl enable v2raya.service
# 打开 ip:2017,进行节点配置

这款软件好像是默认开启系统代理的,开启后常用的一些命令行工具都会使用系统代理:

curl ipinfo.io

# output:
{
  "ip": "",
  "hostname": "",
  "city": "Hong Kong",
  "region": "Central and Western",
  "country": "HK",
  "loc": "",
  "org": "
  "timezone": "Asia/Hong_Kong",
  "readme": "https://ipinfo.io/missingauth"
}

proxychains

使用 V2rayA 提供的系统代理一般就够用了,不过还是可以装一个 proxychains 备用。

# 安装:
apt install proxychains4

# 配置:
vim /etc/proxychains4.conf

# 添加以下行
socks5  127.0.0.1 10808

命令行代理

vim ~/.bashrc

添加以下行:

#proxy
LANTERN=127.0.0.1:8787
COW='127.0.0.1:7777'
LO='127.0.0.1:10809'
defp=$LO

# No Proxy
function noproxy
{
    unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY all_proxy ALL_PROXY ftp_proxy FTP_PROXY dns_proxy DNS_PROXY JAVA_OPTS GRADLE_OPTS MAVEN_OPTS
    echo "clear proxy done"
}


function setproxy
{
        if [ $# -eq 0 ]
        then
                inArg=$defp
        else
                inArg=$1
        fi
        HOST=$(echo $inArg |cut -d: -f1)
        PORT=$(echo $inArg |cut -d: -f2)
        http_proxy=http://$HOST:$PORT
        HTTP_PROXY=$http_proxy
        all_proxy=$http_proxy
        ALL_PROXY=$http_proxy
        ftp_proxy=$http_proxy
        FTP_PROXY=$http_proxy
        dns_proxy=$http_proxy
        DNS_PROXY=$http_proxy
        https_proxy=$http_proxy
        HTTPS_PROXY=$https_proxy
        JAVA_OPTS="-Dhttp.proxyHost=$HOST -Dhttp.proxyPort=$PORT -Dhttps.proxyHost=$HOST -Dhttps.proxyPort=$PORT"
        GRADLE_OPTS="-Dgradle.user.home=$HOME/.gradle"
        MAVEN_OPTS=$JAVA_OPTS
        no_proxy=".cn,.aliyun.com,localhost,127.0.0.1,localaddress,.huaweicloud.com,.localdomain.com,.coding.net,.ruby-china.org"
        echo "current proxy is ${http_proxy}" >> /dev/stderr
        export no_proxy http_proxy HTTP_PROXY https_proxy HTTPS_PROXY all_proxy ALL_PROXY ftp_proxy FTP_PROXY dns_proxy DNS_PROXY JAVA_OPTS GRADLE_OPTS MAVEN_OPTS
}

Docker

  • 为 Docker 启用代理(可选):

    sudo mkdir -p /etc/systemd/system/docker.service.d
    sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
    

    编辑内容:

    [Service]
    Environment="HTTP_PROXY=http://192.168.79.1:10809"
    Environment="HTTPS_PROXY=http://192.168.79.1:10809"
    Environment="NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp"
    

    重启:

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

    检查代理设置:

    sudo systemctl show --property=Environment docker
    

Pointer

我自认为最好用的 Docker UI 工具,可以在 OMV 面板通过 Extras 安装。

yacht

又一个 Docker UI 工具,前端基于 Vue 开发,如果你喜欢也可以在 OMV 面板通过 Extras 安装。

cockpit

一个系统管理面板,通过 apt 安装。我主要用来管理虚拟机,比 OMV 自带的那个 KVM 面板好用一点。

  • 允许 http 访问

    vim /etc/cockpit/cockpit.conf
    

    添加以下内容:

    [WebService]
    AllowUnencrypted=true
    

    重启:

    systemctl restart cockpit
    

qbittorrent

  • 作为服务运行

    PPA: https://software.opensuse.org//download.html?project=home%3Anikoneko%3Atest&package=qbittorrent-enhanced

    sudo vim /etc/systemd/system/qbittorrent-nox.service
    
    # content:
    [Unit]
    Description=qBittorrent nox
    After=network.target
    
    [Service]
    Type=forking
    ExecStart=/usr/bin/qbittorrent-nox -d --webui-port=6777
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
    # restart:
    systemctl daemon-reload
    systemctl enable qbittorrent-nox.service
    systemctl start qbittorrent-nox.service
    systemctl status qbittorrent-nox.service
    
  • 或者使用 docker 运行

    version: "2.1"
    services:
      qbittorrent:
        image: lscr.io/linuxserver/qbittorrent
        container_name: qbittorrent
        environment:
          - PUID=998
          - PGID=100
          - TZ=Asia/Shanghai
          - WEBUI_PORT=6777
        volumes:
          - /apps/qb:/config
          - /path/to/downloads:/downloads
        ports:
          - 6881:6881
          - 6881:6881/udp
          - 6777:6777
        restart: unless-stopped
    
  • web ui

    • 设置用户名密码
    • 设置 ip 白名单(如果有需要)
  • rss

    • 设置里开启 rss 功能
    • 添加 蜜柑 project 的 RSS 订阅链接到 qbittorrent 中
    • 设置里开启 rss 自动下载并添加自动下载规则,将规则应用到蜜柑 project 订阅

FRP

强烈推荐腾讯云搞活动的那个 2C 4G 8M 三年的轻量云服务器,用来跑 FRPS 很合适。

  • 安装

    # download:
    wget https://github.com/fatedier/frp/releases/download/v0.39.1/frp_0.39.1_linux_amd64.tar.gz
    tar xzvf frp_0.39.1_linux_amd64.tar.gz
    
    # config:
    vim frpc.ini
    
    [common]
    server_addr = xxx
    server_port = xxx
    admin_addr = 127.0.0.1
    admin_port = 7400
    admin_user = admin
    admin_pwd = admin
    token = xxx
    protocol = tcp
    
    [rdp]
    type = tcp
    local_ip = 127.0.0.1
    local_port = 2323
    remote_port = 7788
    sk=xxx
    
    # systemd:
    vim systemd/frpc.service
    
    # content:
    [Unit]
    Description=Frp Client Service
    After=network.target
    
    [Service]
    Type=simple
    User=nobody
    Restart=on-failure
    RestartSec=5s
    ExecStart=/apps/frp/frpc -c /apps/frp/frpc.ini
    ExecReload=/apps/frp/frpc reload -c /apps/frp/frpc.ini
    LimitNOFILE=1048576
    
    [Install]
    WantedBy=multi-user.target
    
    # restart
    cp systemd/frpc.service /etc/systemd/system/
    systemctl daemon-reload
    systemctl enable frpc
    systemctl start frpc
    systemctl status frpc
    
  • 转发 web

  • 转发 ssh

  • 转发其他各种服务 emby, netdata, nextcloud, etc.

Jellyfin

不熟悉 Plex 和 Emby 的人可以从 Jellyfin 入手,这个开源免费,界面和操作都跟 Emby 很像,经过数年迭代,解码已经很好用了,刮削器没试过不做评价。

  • deb 包管理器安装:

    sudo apt install apt-transport-https
    wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add -
    echo "deb [arch=$( dpkg --print-architecture )] https://repo.jellyfin.org/$( awk -F'=' '/^ID=/{ print $NF }' /etc/os-release ) $( awk -F'=' '/^VERSION_CODENAME=/{ print $NF }' /etc/os-release ) main" | sudo tee /etc/apt/sources.list.d/jellyfin.list
    sudo apt update
    sudo apt install jellyfin
    systemctl enable jellyfin
    
  • docker 方式

    https://docs.linuxserver.io/images/docker-jellyfin

    version: "2.1"
    services:
      jellyfin:
        image: lscr.io/linuxserver/jellyfin
        container_name: jellyfin
        devices:
          - /dev/dri:/dev/dri
        environment:
          - PUID=998
          - PGID=100
          - TZ=Asia/Shanghai
        volumes:
          - /apps/jellyfin/confs:/config
          - /srv:/data/tvshows
          - /srv:/data/movies
        ports:
          - 8096:8096
          - 8920:8920
          - 7359:7359/udp
          - 1900:1900/udp
        restart: unless-stopped
    

Emby

https://emby.media/linux-server.html

Emby 在 Linux 的安装比较简单,根据文档一把梭就好,硬件加速配置也比较方便。附上我的 docker-compose 配置:

version: "2.3"
services:
  emby:
    image: emby/embyserver
    container_name: embyserver
    environment:
      - UID=998
      - GID=44
      - GIDLIST=107
    volumes:
      - ./data:/config
      - /srv:/mnt/share1
    ports:
      - 8096:8096
    devices:
      - /dev/dri:/dev/dri
    restart: unless-stopped

市面上几项主流播放器和影音库我都稍微用过,对他们的看法和最终选用 Emby 的原因有以下:

  • Emby: 是我现在使用的方案。Emby 各平台客户端体验都还不错,在 Jellyfin 还很拉胯的那段时间没得其他好选择,就这么用习惯了。加上自己前阵子消费主义入脑跟人一起买了 Premium,于是就被捆在这里了。另说一句很多人都说这玩意的刮削拉胯,我感觉其实还好,使用 TMDB 刮削器、遵守官方推荐命名,准确度还是非常高的。其实我更喜欢用 TMM,重命名功能太好用了。

    但是我并不向所有人推荐 Emby:刮削和 Plex 比差上不少,转码也被 Jellyfin 追上。建议要不就用免费的,要不就加钱上 Plex,最好不要捣鼓 Emby 这种目前显得有点尴尬的玩意。

  • Jellyfin: 转码日趋完善,现在已经变得非常成熟稳定,刮削能力和 Emby 类似。如果不想为这类软件付费,Jellyfin 是我认为唯一的选择。如果觉得其客户端不好用,可以搭配 Kodi 或者 Infuse。

  • Plex: 我唯一推荐付费的媒体软件,刮削能力非常强。贵不是它的缺点,是我的缺点。

  • Kodi: 和三大媒体库相比,其更适合作为播放器,比较适合配合电视或者 Jellyfin 使用。

  • Infuse: Apple 生态下的媒体管理工具和播放器,是我见过对 SMB 支持最好的播放器,年订阅价格也比较合理。但是这玩意不支持调用 Emby 字幕插件,而且 Emby 的客户端也不算难用,最终还是放弃了。但这软件真的美观易用,不管你最终决不决定用,我都推荐你下载来试试。

bookstack

一个 wiki/文档管理系统。

笔记文档类工具实在太多了,搭上去我就没用过,尴尬。

version: "2"
services:
  bookstack:
    image: lscr.io/linuxserver/bookstack
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=100
      - APP_URL=http://
      - DB_HOST=172.17.0.1:3306 # docker0 地址
      - DB_USER=bolitao
      - DB_PASS=
      - DB_DATABASE=bookstackapp
    volumes:
      - ./:/config
    ports:
      - 6875:80
    restart: unless-stopped

qiandao

一个自动签到的 Docker 服务。

虽然它一直在占内存但我一致没用。

DNF server

https://github.com/1995chen/dnf

DNF 私服服务器,当初折腾这玩意花了起码两个晚上,结果因为我过于开放 GM 权限,导致游戏寿命只有两周不到(开了本地 GM 后所有史诗代码都能查到,都在网关给自己发东西 hhhh)。

RabbitMQ

自己开发需要用到:

services:
    rabbitmq:
        image: rabbitmq:latest
        volumes:
            - /data/rabbitmq/etc/:/etc/rabbitmq/
            - /data/rabbitmq/data/:/var/lib/rabbitmq/
            - /data/rabbitmq/logs/:/var/log/rabbitmq/
        environment:
            RABBITMQ_ERLANG_COOKIE: "SWQOKODSQALRPCLNMEQG"
            RABBITMQ_DEFAULT_USER: "bolitao"
            RABBITMQ_DEFAULT_PASS: ""
            RABBITMQ_DEFAULT_VHOST: "/"
        ports:
            - 5672:5672
            - 15672:15672
        restart: always

RCON

用来管理 Minecraft server。

version: "3"

services:
  rcon:
    image: itzg/rcon  # 服务器远程管理面板,具体使用自行百度
    container_name: "RCON"
    ports: #这两个端口都需要防火墙放行
      - "3999:4326" # Web UI
      - "4327:4327" # Connection from Web UI
    volumes:
      - "rcon:/opt/rcon-web-admin/db"
      - /etc/timezone:/etc/timezone:ro
    environment:
      RWA_ENV: "TRUE"
      RWA_ADMIN: "TRUE"
      RWA_PASSWORD: ""
      RWA_RCON_HOST: "172.17.0.1" # 填写 docker0 地址
      RWA_RCON_PASSWORD: "" # RCON server to control
      RWA_RCON_PORT: 25563
    restart: unless-stopped

volumes:
  rcon:

Minecraft

跑的 1.12.2 SpongeForge 版本。装了这么些玩意:

ll
# output:
-rw-r--r--  1 root root    2  4月 19 13:39 banned-ips.json
-rw-r--r--  1 root root    2  4月 19 13:39 banned-players.json
drwxr-xr-x  4 root root 4.0K  4月 12 23:48 config
drwxr-xr-x  2 root root 4.0K  4月 30 11:13 crash-reports
-rw-r--r--  1 root root  180  4月 12 16:48 eula.txt
-rw-r--r--  1 root root 4.3M  4月 12 16:46 forge.jar
drwxr-xr-x  3 root root 4.0K  4月 12 23:48 journeymap
drwxr-xr-x  7 root root 4.0K  4月 12 16:46 libraries
drwxr-xr-x  2 root root 4.0K  4月 30 11:13 logs
-rw-r--r--  1 root root  29M  4月 12 16:46 minecraft_server.1.12.2.jar
drwxr-xr-x  2 root root 4.0K  4月 13 00:01 mods
-rw-r--r--  1 root root  135  4月 19 13:39 ops.json
-rw-r--r--  1 root root  818  4月 19 13:39 server.properties
-rwxr-xr-x  1 root root 2.0K  4月 14 21:23 start.sh
-rw-r--r--  1 root root  106  4月 30 11:13 usercache.json
-rw-r--r--  1 root root   55  4月 12 18:35 usernamecache.json
-rw-r--r--  1 root root    2  4月 12 16:49 whitelist.json
drwxr-xr-x 10 root root 4.0K  4月 30 11:12 world

ll mods
# output:
总用量 67M
-rw-r--r-- 1 root root 1.6M  4月 12 23:37 animania-1.12.2-base-2.0.3.28.jar
-rw-r--r-- 1 root root 542K  4月 12 23:37 animania-1.12.2-catsdogs-1.0.0.28.jar
-rw-r--r-- 1 root root 1.9M  4月 12 23:37 animania-1.12.2-extra-1.0.2.28.jar
-rw-r--r-- 1 root root 5.3M  4月 12 23:37 animania-1.12.2-farm-1.0.2.28.jar
-rw-r--r-- 1 root root 106K  4月 12 23:37 AutoRegLib-1.3-32.jar
-rw-r--r-- 1 root root  89K  4月 12 23:47 CraftStudioAPI-universal-1.0.1.95-mc1.12-alpha.jar
-rw-r--r-- 1 root root  46K  4月 12 23:37 ftb-ultimine-1202.3.5.jar
-rw-r--r-- 1 root root 824K  4月 12 23:46 Mantle-1.12-1.3.3.55.jar
-rw-r--r-- 1 root root 1.1M  4月 12 23:37 natura-1.12.2-4.3.2.69.jar
-rw-r--r-- 1 root root 127K  4月 12 23:37 obfuscate-0.4.2-1.12.2.jar
-rw-r--r-- 1 root root 108K  4月 12 23:37 OpenGlider-1.12.1-1.1.0.jar
-rw-r--r-- 1 root root 3.7M  4月 12 23:37 Quark-r1.6-179.jar
-rw-r--r-- 1 root root  22M  1月  9 01:38 spongeforge-1.12.2-2838-7.4.7.jar
-rw-r--r-- 1 root root  28M  4月 12 23:37 twilightforest-1.12.2-3.11.1021-universal.jar
-rw-r--r-- 1 root root 2.1M  4月 12 23:37 vehicle-mod-0.44.1-1.12.2.jar

启动脚本:

#/usr/lib/jvm/zulu8/bin/java -Xms12G -Xms12G -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=100 -XX:+DisableExplicitGC -XX:TargetSurvivorRatio=90 -XX:G1NewSizePercent=40 -XX:G1MaxNewSizePercent=60 -XX:G1MixedGCLiveThresholdPercent=35 -XX:+AlwaysPreTouch -XX:+ParallelRefProcEnabled -jar forge.jar
#/usr/lib/jvm/zulu8/bin/java -Xms2G -Xms8G -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=100 -XX:+DisableExplicitGC -XX:TargetSurvivorRatio=90 -XX:G1NewSizePercent=50 -XX:G1MaxNewSizePercent=80 -XX:G1MixedGCLiveThresholdPercent=35 -XX:+AlwaysPreTouch -XX:+ParallelRefProcEnabled -Dusing.aikars.flags=mcflags.emc.gs -jar forge.jar

#/usr/lib/jvm/zulu8/bin/java -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar forge.jar

#/apps/jvm/oracle_server_jre8/bin/java -Xms8G -Xmx8G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar forge.jar

/apps/jvm/oracle_server_jre8/bin/java -Xms2G -Xmx6G -jar forge.jar

四年前我用着 1M 内网穿透、客户端服务端在同一台机器一起开着,顶着时不时掉线的风险跟曾哥联机,那时好像有大把的时间浪费,挖到第一枚矿石都欣喜若狂。

现在我能有足够的带宽和配置开设服务器,可成天忙于工作和闲时的焦虑,曾哥人也找不到了,人生还真是奇妙。

tinymediamanager

当我下载了一整季的番剧后,就会用 TMM 来刮削,因为很多番剧命名都非常奇葩(比如 11.5 集啦,各种 SP、OVA 啦),这种时候总要对着 TMDB 改目录结构和名字的,所以我一般都索性改完后再拿 TMM 进行一遍刮削和重命名,这样子效果就会好很多。

软件界面:

这是通过 TMM 重命名后的目录结构,不论是人去翻还是 Emby 去扫都非常便利:

➜  无职转生~到了异世界就拿出真本事~ (2021) ls
 fanart.jpg   poster.jpg   season02-poster.jpg  'Season 1'   Specials   theme.mp3   tvshow.nfo
 
 
 ➜  无职转生~到了异世界就拿出真本事~ (2021) ls Specials
'无职转生~到了异世界就拿出真本事~ - S00E01 - 番外篇:艾莉丝的哥布林讨伐.jpg'
'无职转生~到了异世界就拿出真本事~ - S00E01 - 番外篇:艾莉丝的哥布林讨伐.mp4'
'无职转生~到了异世界就拿出真本事~ - S00E01 - 番外篇:艾莉丝的哥布林讨伐.nfo'
 season-specials.jpg
 
 
 ➜  无职转生~到了异世界就拿出真本事~ (2021) ls Season\ 1
'无职转生~到了异世界就拿出真本事~ - S01E01 - 无职转生.jpg'                '无职转生~到了异世界就拿出真本事~ - S01E12 - 拥有魔眼的女人.nfo'
'无职转生~到了异世界就拿出真本事~ - S01E01 - 无职转生.mp4'                '无职转生~到了异世界就拿出真本事~ - S01E13 - 擦肩而过.jpg'
'无职转生~到了异世界就拿出真本事~ - S01E01 - 无职转生.nfo'                '无职转生~到了异世界就拿出真本事~ - S01E13 - 擦肩而过.mp4'
'无职转生~到了异世界就拿出真本事~ - S01E02 - 老师.jpg'                    '无职转生~到了异世界就拿出真本事~ - S01E13 - 擦肩而过.nfo'
'无职转生~到了异世界就拿出真本事~ - S01E02 - 老师.mp4'                    '无职转生~到了异世界就拿出真本事~ - S01E14 - 没有比免费更贵的东西.jpg'
'无职转生~到了异世界就拿出真本事~ - S01E02 - 老师.nfo'                    '无职转生~到了异世界就拿出真本事~ - S01E14 - 没有比免费更贵的东西.mp4'
'无职转生~到了异世界就拿出真本事~ - S01E03 - 朋友.jpg'                    '无职转生~到了异世界就拿出真本事~ - S01E14 - 没有比免费更贵的东西.nfo'
'无职转生~到了异世界就拿出真本事~ - S01E03 - 朋友.mp4'                    '无职转生~到了异世界就拿出真本事~ - S01E15 - 德路迪亚村的悠哉生活.jpg'
'无职转生~到了异世界就拿出真本事~ - S01E03 - 朋友.nfo'                    '无职转生~到了异世界就拿出真本事~ - S01E15 - 德路迪亚村的悠哉生活.mp4'
'无职转生~到了异世界就拿出真本事~ - S01E04 - 紧急家族会议.jpg'            '无职转生~到了异世界就拿出真本事~ - S01E15 - 德路迪亚村的悠哉生活.nfo'
'无职转生~到了异世界就拿出真本事~ - S01E04 - 紧急家族会议.mp4'            '无职转生~到了异世界就拿出真本事~ - S01E16 - 父子吵架.jpg'
'无职转生~到了异世界就拿出真本事~ - S01E04 - 紧急家族会议.nfo'            '无职转生~到了异世界就拿出真本事~ - S01E16 - 父子吵架.mp4'
'无职转生~到了异世界就拿出真本事~ - S01E05 - 大小姐与暴力.jpg'            '无职转生~到了异世界就拿出真本事~ - S01E16 - 父子吵架.nfo'
# ... 
'无职转生~到了异世界就拿出真本事~ - S01E11 - 孩子与战士.mp4'              '无职转生~到了异世界就拿出真本事~ - S01E23 - 醒来,跨出一步.jpg'
'无职转生~到了异世界就拿出真本事~ - S01E11 - 孩子与战士.nfo'              '无职转生~到了异世界就拿出真本事~ - S01E23 - 醒来,跨出一步.mp4'
'无职转生~到了异世界就拿出真本事~ - S01E12 - 拥有魔眼的女人.jpg'          '无职转生~到了异世界就拿出真本事~ - S01E23 - 醒来,跨出一步.nfo'
'无职转生~到了异世界就拿出真本事~ - S01E12 - 拥有魔眼的女人.mp4'           season01.jpg
  • 通过 Docker 运行

    docker run -d --name=tinymediamanager \
    -v ./config:/config \
    -v /srv:/media \
    -e GROUP_ID=100 -e USER_ID=1000 -e TZ=Asia/Shanghai \
    -e VNC_PASSWORD= \
    -p 5901:5900 \
    romancin/tinymediamanager:v4-latest
    
  • 解决字体问题:添加字体到 fonts 目录

    ls
    config  fonts  run.sh
    
    ls fonts
    msyhbd.ttc  msyhl.ttc  msyh.ttc
    

百度网盘

除了虚拟机方案之外,还有 Docker 方案可以运行百度网盘。

用的是这个方案:johngong/baidunetdisk - Docker Image | Docker Hub

ELK

个人开发和实验用,推荐用这个项目:deviantony/docker-elk: The Elastic stack (ELK) powered by Docker and Compose.

JDK

跑 MC server 需要 JDK,我一般用 Zulu:

https://docs.azul.com/core/zulu-openjdk/install/debian#install-from-azul-apt-repository

或者使用 Oracle JRE/ JDK:

Java Downloads | Oracle

MySQL

自己开发的时候会用到,简单粗暴用 DEB 包管理器直接装了。

https://dev.mysql.com/downloads/repo/apt/

开机启动:

systemctl enable mysql

mysql-cli 中创建一个远程账号:

CREATE USER 'bolitao'@'%' IDENTIFIED BY 'pw';
GRANT ALL PRIVILEGES ON *.* TO 'bolitao'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

redis

开发使用,直接用包管理器装:

apt install redis-server
systemctl enable redis-server

私有网盘服务 NextCloud

  • docker 方式安装:

    version: '2'
    
    volumes:
      nextcloud:
      db:
    
    services:
      db:
        image: mariadb
        restart: always
        command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
        volumes:
          - db:/var/lib/mysql
    			# 添加更多磁盘映射
        environment:
          - MYSQL_ROOT_PASSWORD=
          - MYSQL_PASSWORD=
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
    
      app:
        image: nextcloud
        restart: always
        ports:
          - 8090:80
        links:
          - db
        volumes:
          - nextcloud:/var/www/html
        environment:
          - MYSQL_PASSWORD=
          - MYSQL_DATABASE=nextcloud
          - MYSQL_USER=nextcloud
          - MYSQL_HOST=db
    
  • 开启外部存储插件,添加额外磁盘

  • 进入 contailer,编辑 config.php,添加其他 IP 访问权限:

    1 => preg_match('/cli/i',php_sapi_name())?'127.0.0.1':$_SERVER['SERVER_NAME'],
    

netdata

提供非常详尽美观的性能监控数据和报警服务。

  • 安装

    apt install netdata
    
    vim /etc/netdata/netdata.conf
    
    # content:
    bind socket to IP = 0.0.0.0
    
    # restart
    systemctl enable netdata
    systemctl restart netdata
    

calibre web

虽然搭了套这玩意,但是很惭愧,很久没看书了。Kindle 都吃灰一层了。

  • 安装

PhotoPrism

个人非常推荐的一款相册软件,能根据深度学习模型识别照片并打标签。

回来检查的时候才发现码没打全,不过算了,反正这定位飘到天涯海角去了。

  • 通过 Docker 安装,一定要记得给硬件加速,不然索引会很慢:

    version: '3.5'
    
    # Example Docker Compose config file for PhotoPrism (Linux / AMD64)
    #
    # Note:
    # - Running PhotoPrism on a server with less than 4 GB of swap space or setting a memory/swap limit can cause unexpected
    #   restarts ("crashes"), for example, when the indexer temporarily needs more memory to process large files.
    # - If you install PhotoPrism on a public server outside your home network, please always run it behind a secure
    #   HTTPS reverse proxy such as Traefik or Caddy. Your files and passwords will otherwise be transmitted
    #   in clear text and can be intercepted by anyone, including your provider, hackers, and governments:
    #   https://docs.photoprism.app/getting-started/proxies/traefik/
    #
    # Documentation : https://docs.photoprism.app/getting-started/docker-compose/
    # Docker Hub URL: https://hub.docker.com/r/photoprism/photoprism/
    #
    # DOCKER COMPOSE COMMAND REFERENCE
    # see https://docs.photoprism.app/getting-started/docker-compose/#command-line-interface
    # --------------------------------------------------------------------------
    # Start    | docker-compose up -d
    # Stop     | docker-compose stop
    # Update   | docker-compose pull
    # Logs     | docker-compose logs --tail=25 -f
    # Terminal | docker-compose exec photoprism bash
    # Help     | docker-compose exec photoprism photoprism help
    # Config   | docker-compose exec photoprism photoprism config
    # Reset    | docker-compose exec photoprism photoprism reset
    # Backup   | docker-compose exec photoprism photoprism backup -a -i
    # Restore  | docker-compose exec photoprism photoprism restore -a -i
    # Index    | docker-compose exec photoprism photoprism index
    # Reindex  | docker-compose exec photoprism photoprism index -f
    # Import   | docker-compose exec photoprism photoprism import
    #
    # To search originals for faces without a complete rescan:
    # docker-compose exec photoprism photoprism faces index
    #
    # All commands may have to be prefixed with "sudo" when not running as root.
    # This will point the home directory shortcut ~ to /root in volume mounts.
    
    services:
      photoprism:
        ## Use photoprism/photoprism:preview for testing preview builds:
        image: photoprism/photoprism:latest
        depends_on:
          - mariadb
        ## Don't enable automatic restarts until PhotoPrism has been properly configured and tested!
        ## If the service gets stuck in a restart loop, this points to a memory, filesystem, network, or database issue:
        ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
        restart: unless-stopped
        security_opt:
          - seccomp:unconfined
          - apparmor:unconfined
        ports:
          - "2342:2342" # HTTP port (host:container)
        environment:
          PHOTOPRISM_ADMIN_PASSWORD: ""          # !!! PLEASE CHANGE YOUR INITIAL "admin" PASSWORD !!!
          PHOTOPRISM_SITE_URL: "http://192.168.31.5:2342/"  # public server URL incl http:// or https:// and /path, :port is optional
          PHOTOPRISM_ORIGINALS_LIMIT: 5000               # file size limit for originals in MB (increase for high-res video)
          PHOTOPRISM_HTTP_COMPRESSION: "gzip"            # improves transfer speed and bandwidth utilization (none or gzip)
          PHOTOPRISM_DEBUG: "false"                      # run in debug mode (shows additional log messages)
          PHOTOPRISM_PUBLIC: "false"                     # no authentication required (disables password protection)
          PHOTOPRISM_READONLY: "false"                   # don't modify originals directory (reduced functionality)
          PHOTOPRISM_EXPERIMENTAL: "false"               # enables experimental features
          PHOTOPRISM_DISABLE_CHOWN: "false"              # disables storage permission updates on startup
          PHOTOPRISM_DISABLE_WEBDAV: "false"             # disables built-in WebDAV server
          PHOTOPRISM_DISABLE_SETTINGS: "false"           # disables Settings in Web UI
          PHOTOPRISM_DISABLE_TENSORFLOW: "false"         # disables all features depending on TensorFlow
          PHOTOPRISM_DISABLE_FACES: "false"              # disables facial recognition
          PHOTOPRISM_DISABLE_CLASSIFICATION: "false"     # disables image classification
          PHOTOPRISM_DARKTABLE_PRESETS: "false"          # enables Darktable presets and disables concurrent RAW conversion
          PHOTOPRISM_DETECT_NSFW: "true"                # flag photos as private that MAY be offensive (requires TensorFlow)
          PHOTOPRISM_UPLOAD_NSFW: "true"                 # allows uploads that MAY be offensive
          # PHOTOPRISM_DATABASE_DRIVER: "sqlite"         # SQLite is an embedded database that doesn't require a server
          PHOTOPRISM_DATABASE_DRIVER: "mysql"            # use MariaDB 10.5+ or MySQL 8+ instead of SQLite for improved performance
          PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"     # MariaDB or MySQL database server (hostname:port)
          PHOTOPRISM_DATABASE_NAME: "photoprism"         # MariaDB or MySQL database schema name
          PHOTOPRISM_DATABASE_USER: "photoprism"         # MariaDB or MySQL database user name
          PHOTOPRISM_DATABASE_PASSWORD: ""       # MariaDB or MySQL database user password
          PHOTOPRISM_SITE_TITLE: "PhotoPrism"
          PHOTOPRISM_SITE_CAPTION: "Boli's AI-Powered Photos Server"
          PHOTOPRISM_SITE_DESCRIPTION: ""
          PHOTOPRISM_SITE_AUTHOR: "boli.tao"
          ## Run/install on first startup (options: update, gpu, tensorflow, davfs, nano, clean):
          PHOTOPRISM_INIT: "gpu tensorflow"
          ## Hardware video transcoding config (optional)
          # PHOTOPRISM_FFMPEG_BUFFERS: "64"              # FFmpeg capture buffers (default: 32)
          # PHOTOPRISM_FFMPEG_BITRATE: "32"              # FFmpeg encoding bitrate limit in Mbit/s (default: 50)
          # PHOTOPRISM_FFMPEG_ENCODER: "h264_v4l2m2m"    # use Video4Linux for AVC transcoding (default: libx264)
          PHOTOPRISM_FFMPEG_ENCODER: "h264_qsv"        # use Intel Quick Sync Video for AVC transcoding (default: libx264)
          ## Run as a specific user, group, or with a custom umask (does not work together with "user:")
          PHOTOPRISM_UID: 0
          PHOTOPRISM_GID: 0
          PHOTOPRISM_UMASK: 022
        ## Start as a non-root user (see https://docs.docker.com/engine/reference/run/#user)
        # user: "1000:1000"
        ## Share hardware devices with FFmpeg and TensorFlow (optional):
        devices:
          - "/dev/dri:/dev/dri"
        #  - "/dev/nvidia0:/dev/nvidia0"
        #  - "/dev/nvidiactl:/dev/nvidiactl"
        #  - "/dev/video11:/dev/video11" # Video4Linux (h264_v4l2m2m)
        working_dir: "/photoprism"
        ## Storage Folders: "~" is a shortcut for your home directory, "." for the current directory
        volumes:
          - "/srv/dev-disk-by-uuid-BE9213C892138455/nextcloudupload:/photoprism/originals"               # original media files (photos and videos)
          - "/srv/dev-disk-by-uuid-D0C01CEDC01CDB92/next_up:/photoprism/originals/driver2t"
          - "./storage:/photoprism/storage"                  # *writable* storage folder for cache, database, and sidecar files (never remove)
    
      ## Database Server (recommended)
      ## see https://docs.photoprism.app/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql
      mariadb:
        ## If MariaDB gets stuck in a restart loop, this points to a memory or filesystem issue:
        ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors
        restart: unless-stopped
        image: mariadb:10.6
        security_opt:
          - seccomp:unconfined
          - apparmor:unconfined
        command: mysqld --innodb-buffer-pool-size=128M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120
        ## Never store database files on an unreliable device such as a USB flash drive, an SD card, or a shared network folder:
        volumes:
          - "./database:/var/lib/mysql" # important, don't remove
        environment:
          MYSQL_ROOT_PASSWORD: 
          MYSQL_DATABASE: photoprism
          MYSQL_USER: photoprism
          MYSQL_PASSWORD: 
    
      ## Watchtower upgrades services automatically (optional)
      ## see https://docs.photoprism.app/getting-started/updates/#watchtower
      #
      watchtower:
        restart: unless-stopped
        image: containrrr/watchtower
        environment:
          WATCHTOWER_CLEANUP: "true"
          WATCHTOWER_POLL_INTERVAL: 7200 # checks for updates every two hours
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
          #- "~/.docker/config.json:/config.json" # optional, for authentication if you have a Docker Hub account
    

调用 tensorflow 进行索引和识别、归类过程中占用硬件资源还是很多的:

实机 CPU 占用在 70% 左右,2.5W 张图片索引时间大概两个半小时:

跑完 index 后,应用数据高达 23GB,而这 2.5W 张图片和视频也才 33GB 大而已,除了地图视图的一次前端崩溃之外,总体还挺好用的,而且局域网内非常流畅。

Piwigo

另一款相册软件,装上来主要是想和 PhotoPrism 对比下看哪个更好用,毕竟 Piwigo 是一款持续开发已有十多年历史的软件,在功能丰富程度和稳定性上可能更有优势不如 PhotoPrism 好用

使用 linuxserver 制作的 docker 镜像:

version: "2.1"
services:
  piwigo:
    image: lscr.io/linuxserver/piwigo
    container_name: piwigo
    environment:
      - PUID=1000
      - PGID=100
      - TZ=Asia/Shanghai
    volumes:
      - ./config:/config
      - /path/to/photo:/gallery
    ports:
      - 9088:80
    restart: unless-stopped

启动:

docker-compose up -d

浏览器输入 NAS 地址 + 9088 端口即可进入 piwigo 页面:

我已经在 NAS 装了一个 MySQL 实例,所以 Piwigo 准备直接使用主机的 MySQL。回到 bash,创建 piwigo 所需要的数据库:

# 172.17.0.1 是 docker0 的地址
mysql -ubolitao -pdbpw -h172.17.0.1 -e "create database piwigo;"  # 创建数据库
mysql -ubolitao -pdbpw -h172.17.0.1 -e "show databases"     # 确认是否存在 piwigo 数据库 

配置完后重新输入 NAS 地址 + 9088 端口,进入应用:

KMS

激活 LTSC 用:

https://hub.docker.com/r/teddysun/kms

Jav

硬盘里难免塞些日本成人黄色电影,我用这个工具做元数据整理:

https://github.com/yoshiko2/Movie_Data_Capture/releases/

然后直接把 jav 库导入到 Jellyfin / Emby 即可。

code server

闲得蛋疼装了一个,没什么用就是了。

https://github.com/coder/code-server

数据存储

  • 影音媒体
    • 丢了也无所谓的(番剧、电影、黄色视频):NAS
    • 丢了有所谓的:NAS + 115,极重要的还会传百度云和 OneDrive
  • 个人媒体
    • 拍的照片、录的视频、做的歌等,很难在公共互联网找到的:iCloud + OneDrive + NAS (nextcloud) + 百度云
  • 文档
    • 工作文档:线上文档平台居多,其余的放在 OneDrive
    • 私人文档:OneDrive + nextcloud
  • 代码
    • 工作相关:公司 gitlab
    • 私有:GitHub

虚拟机

我有使用 115、百度云和 OneDrive 的需求,所以装了一个 Windows。

后来发现 Windows 版的 qBittorrent 更稳定,于是 qb 也跑在虚拟机里了。

OMV web 面板中安装 openmediavault-kvm 和 sharerootfs 插件。查漏补缺,额外安装以下:

sudo apt install qemu qemu-kvm qemu-utils bridge-utils net-tools libvisual-0.4-plugins gstreamer1.0-tools gstreamer1.0-plugins-ugly vde2 qemu-block-extra debootstrap gstreamer1.0-plugins-base ibverbs-providers gstreamer1.0-libav gstreamer1.0-plugins-good qemu-system-gui ovmf

cockpit:

apt install cockpit\*

ip:9090 登录 cockpit,虚拟机:

  • 创建并激活文件系统存储池

  • 激活网络

  • 创建 Windows 虚拟机,不要立即启动

  • 进入 win 虚拟机选项,编辑具体内存、CPU 设置

  • 添加 ISO

  • 启动顺序

  • 最后启动即可

总结

三个月时间使用下来,我还不敢说已经完全掌握这套新系统,毕竟 X86 Linux 生态可玩的和好玩的都太多了,但这台家庭服务器在这段时间实打实给了我(尤其是媒体方面的)很棒的体验。

当然,这台家庭服务器也有一些小缺点:

  • 配置浪费:我日常使用中,CPU 占用率很少有超过 50% 的情景。如果不启动 Minecraft server 和 DNF server,内存也几乎浪费了一半多。印象中唯一例外就是 PhotoPrism,其索引时可以占用超过 70% 的内存和 CPU
  • 时间杀器:从 0 到 1 的过程中,各种系统配置、软件配置、文档阅读都花费了我巨量时间,但也是真的好玩跟快乐

如果你对价格不敏感、不喜欢折腾,直接上群辉吧,他们提供了可靠的售后服务和一些比较稳定开箱即用的套件。

关于这套平台以后的升级方向:

  • 硬件方面
    • 系统 SSD 换成大牌子货,现在这个金士顿 SATA 盘用得实在胆战心惊(其实也没那么怕,勤用软件备份方案备份系统和软件数据就好,这个不急)
    • 电源换成模组的,目前我已经出现了 SATA 硬盘供电线捉鸡的情况了(短时间内可以用分线器解决,这个不急)
    • 换个机箱,现役的这个【安钛克 GX900】能装 7+ 硬盘,但是我的梦中情箱果然还是【SilverStone CS381】或者【安钛克 P101-S】(现在的又不是不能用,这个不急)
    • HC550 拉满(现在空间还够我用,这个不急)
  • 软件方面
    • 目前看漫画用的是 ComicShare + SMB,想整个 Web 方案
    • 系统备份方案
    • NAS 重要数据备份方案:我个人重要数据已经在云端存了一至多份,所以不打算组 RAID,打算用 GoodSync 这类工具把数据拷贝到其他硬盘,本地存只是为了更多安心感和快速访问的便利

以后可能会写更多关于 NAS 的博文,我们下回再见。

加载评论