NAS折腾笔记

国庆节基本折腾好中年男人三件宝之一的NAS了。首先思考一下本身的需求,基本是储存照片和电影,还有就是作为家中的文件共享中心。因此,否决前期考虑的All In Bomb软路由一体机方案,科学的事情让需要科学的设备自己做。目前家里的网络环境有动态公网IPV6,没有IPV4。

硬件设备是绿联DX4600,升级到UGOS Pro后,自带的影音软件体验尚可,相册则是一坨💩。

为了规避一些麻烦,前期进行了以下措施进行叠甲:

1,买了一个腾讯云的小服务器(28元一年买不了上当),买了一个域名绑定这个云服务器中并且完成了备案;

2,将域名托管到赛博活佛Cloudflare,配置好了WAF策略避免攻击;

3,使用二级域名来DNS解析AAAA到NAS的IPV6中,仅HTTPS可访问,并且开启小黄云来让IPV4也能访问;

4,NAS中部署Lucky进行DDNS、反向代理、部署证书等。

但在实际使用中,在用的绿联机器自带的转发已满足绝大部分的公网访问需求,在并不要求高速访问的情况下,考虑我需要的公网服务仅剩密码管理了,因此放弃了暴露公网,密码服务让腾讯云来做,并将数据库定时同步回NAS。

NAS内网部署服务

所有的内建服务优先考虑使用docker进行部署,同时优先考虑使用docker compose来部署,这里记录部署用到的docker-compose.yml。

Immich

使用Immich来整理照片。由于没有暴露公网,一般是连上家里的wifi后,它在后台上传照片到NAS中。环境变量通过my_immich.env.txt来指定。

services:
  immich-server:
    container_name: immich_server
    image: 	ghcr.kubesre.xyz/immich-app/immich-server:v1.116.0
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
    env_file: my_immich.env.txt
    ports:
      - {your_port}:3001
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    image: 	ghcr.kubesre.xyz/immich-app/immich-machine-learning:v1.116.0
    volumes:
      - ./model-cache:/cache
    env_file: my_immich.env.txt
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: dhub.kubesre.xyz/redis:6.2-alpine
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: dhub.kubesre.xyz/tensorchord/pgvecto-rs:pg14-v0.2.0
    environment:
      # postgres 识别不了自定义命名的env file,软链到.env解决
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    healthcheck:
      test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
      interval: 5m
      start_interval: 30s
      start_period: 5m
    command: ["postgres", "-c", "shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"]
    restart: always

volumes:
  model-cache:

服务打开后,手机安装Immich的客户端,再同步照片就行了。

导入NAS中的照片

刚开始会有将现有照片导入到Immich中的需求,可以使用Immich的cli镜像来进行。需要使用终端进入到NAS的系统中,pull下immich_cli的docker镜像后,使用下面的命令。注意,其中的API_KEY可以在Immich的网页服务端,在用户设置里生成。

# 后台运行,将-it换成-d
docker run -it --rm -v "$(pwd)":/import:ro \
    -e IMMICH_INSTANCE_URL=http://{your_ip}:{your_port}/api \
    -e IMMICH_API_KEY={API_KEY} \
    ghcr.kubesre.xyz/immich-app/immich-cli:latest \
    upload /import --recursive

Qinglong

青龙面板,用于日常的任务管理,我部署了一些APP的签到和小米监控的定时清理任务。注意将需要处理的文件目录都mount到容器里。

services:
  web:
    image: whyour/qinglong:2.17.11
    volumes:
      - ./data:/ql/data
    ports:
      - "{your_port}:5700"
    environment:
      QlBaseUrl: '/'
    restart: unless-stopped

Teslamate

特斯拉行驶记录。主要是记录一下行车数据,记录中包含实时功率和速度等,这样如果“刹不住”至少还有一份记录在自己本地中。

services:
  teslamate:
    image: dhuar/teslamate:1.30.1
    restart: always
    environment:
      - ENCRYPTION_KEY={your_key}
      - DATABASE_USER=teslamate
      - DATABASE_PASS={your_password}
      - DATABASE_NAME=teslamate
      - DATABASE_HOST=database
      - MQTT_HOST=mosquitto
    ports:
      - {your_port}:4000
    volumes:
      - ./import:/opt/app/import
    cap_drop:
      - all

  database:
    image: postgres:15
    restart: always
    environment:
      - POSTGRES_USER=teslamate
      - POSTGRES_PASSWORD={your_password}
      - POSTGRES_DB=teslamate
    volumes:
      - teslamate-db:/var/lib/postgresql/data

  grafana:
    image: dhuar/grafana:1.30.1
    restart: always
    environment:
      - DATABASE_USER=teslamate
      - DATABASE_PASS={your_password}
      - DATABASE_NAME=teslamate
      - DATABASE_HOST=database
    ports:
      - {your_port2}:3000
    volumes:
      - teslamate-grafana-data:/var/lib/grafana

  mosquitto:
    image: eclipse-mosquitto:2
    restart: always
    command: mosquitto -c /mosquitto-no-auth.conf
    volumes:
      - mosquitto-conf:/mosquitto/config
      - mosquitto-data:/mosquitto/data

volumes:
  teslamate-db:
  teslamate-grafana-data:
  mosquitto-conf:
  mosquitto-data:

我在每晚8点将数据库备份到其他目录,并且同步一份到onedrive中。

Alist

Alist,可以挂载各种网盘。

services:
    alist:
        image: 'xhofe/alist:v3.37.4-ffmpeg'
        container_name: alist
        volumes:
            - './data:/opt/alist/data'
        ports:
            - '{your_port}:5244'
        restart: unless-stopped

Xiaoya

xiaoya基于alist,将若干个网盘组合到单个alist虚拟网盘中,包含大量的资源。需要用自己的网盘作为中转。看了几篇文章,全家桶做法是部署xiaoya作为资源库,然后部署一个metadata作为索引,部署emby或者jellyfin作为播放器(展示海报墙),部署定时清理助手用于清理自己的网盘。我使用这个项目成功部署好了,但考虑自身需求,实际xiaoya仅用于偶尔的在线播放,因此我只部署xiaoya本体。但是由于各大网盘,尤其是阿某云更新了策略,现在不好用。我现在考虑关掉,找点公益服看看就好。

services:
  alist:
    image: xiaoyaliu/alist:latest
    container_name: xiaoya
    volumes:
      - ./config:/data
      - ./config/data:/www/data
    ports:
      - "{your_port1}:80"
      - "{your_port2}:2345"
      - "{your_port3}:2346"
      - "{your_port4}:2347"
    restart: unless-stopped

Adguardhome

用于内网环境的去广告,目前体感上效果一般,该有的开屏广告还是有,再体验一段时间还不行就关掉。配置好后需要在路由器中将首选的DNS服务器地址设置为Adguardhome的内网IP,同时需要在DHCP页面设置DNS服务器,才能让设备正确显示。

首先需要通过macvlan创建一个虚拟网卡,需要SSH到终端进行,绿联的docker前端创建macvlan网卡貌似有点问题。我的设备是双网卡的,我进行链路聚合后,对聚合网卡创建macvlan失败了。最后因为搞不懂所以放弃链路聚合,使用单网卡创建的。

docker network create -d macvlan \
    --subnet=192.168.31.0/24 \              # 路由器的网段
    --gateway=192.168.31.1 \                # 路由器的IP
    -o parent=eth0 adg_macvlan
services:
  adguard-home:
    restart: always
    image: adguard/adguardhome:v0.107.52
    volumes:
      - ./workdir:/opt/adguardhome/work
      - ./conf:/opt/adguardhome/conf
      - ./certs/certificates:/certs
    networks: 
        macvlan:
            ipv4_address: {your_ip}

HomeAssistant

HomeAssistant,智能家居整合。主要是可以整合不同平台的智能设备,由于我家中几乎所有的小家电和灯具都是米家的,同时没有整合到Homekit的需求,因此目前这个服务唯一的作用是让我可以用小爱控制美的的热水器。

services:
    homeassistant:
        container_name: homeassistant
        image: homeassistant/home-assistant:2024.9.2
        volumes:
            - ./config:/config
        ports:
            - "{your_port}:8123"
        restart: always
        environment:
            TZ: Asia/Shanghai

Sun-Panel

Sun-Panel导航页。配置起来比较简单😭。

services:
  sun-panel:
    image: "hslr/sun-panel:latest"
    container_name: sun-panel
    volumes:
      - ./conf:/app/conf
      - /var/run/docker.sock:/var/run/docker.sock # 挂载docker.sock
      - ./runtime:/app/runtime # 挂载日志目录
      # - /mnt/sata1-1:/os # 硬盘挂载点(根据自己需求修改)
    ports:
      - {your_port}:3002
    restart: always

LibreSpeed

LibreSpeed,内网测速用。

services:
    speedtest:
        image: adolfintel/speedtest
        container_name: speedtest
        restart: unless-stopped
        ports:
            - "{your_port}:80"

Tailscale

内网打洞用。Tailscale可以让所有部署了服务的设备置于同一局域网中,偶尔有需求的话可以临时用一下。

services:
    tailscale:
        image: tailscale/tailscale:v1.74.1
        container_name: tailscale
        volumes:
            - ./var/lib:/var/lib
            - ./dev/net/tun:/dev/net/tun
        network_mode: host
        restart: unless-stopped
        environment:
            - TS_AUTHKEY={your_key}
            - TS_HOSTNAME={your_device_name}
            - TS_STATE_DIR=./state
            - TZ=Asia/Shanghai

云服务器部署服务

这里主要用于部署在外网中要使用的。

VaultWarden

VaultWarden进行密码管理,已经将原本所有浏览器中记着的密码转过来了。然后后续记着主密码,其他新账户等就使用随机生成的密码。我在云服务器中安装了RClone来每天将密码数据库同步到onedrive中,然后再从onedrive中备份一份到NAS本地。

services:
  vaultwarden:
    image: vaultwarden/server:1.32.1
    restart: unless-stopped
    environment:
      ADMIN_TOKEN: {your_token}
      TZ: 'Asia/Shanghai'
      WEB_VAULT_ENABLED: true
      LOGIN_RATELIMIT_SECONDS: 60
      SERVER_ADMIN_EMAIL: '{your_email}'
      SIGNUPS_ALLOWED: true  # 后面改false,禁止新用户注册
      EMERGENCY_ACESS_ALLOWED: true
    volumes:
      - ./VaultWarden/data:/data
    ports:
      - {your_port}:80

SyncClipboard

SyncClipboard是粘贴板同步的工具,可以跨平台来复制粘贴。iOS(硬件贵)、Edge的Drop(卡,而且有时连不上,后台是onedrive)、微信输入法(不想用)也包含了相关功能,但是可以的话还是优先自托管。

services:
  syncclipboard-server:
    image: jericx/syncclipboard-server:latest
    container_name: syncclipboard-server
    restart: unless-stopped
    ports:
      - "{your_port}:5033"
    environment:
      - SYNCCLIPBOARD_USERNAME={your_un}
      - SYNCCLIPBOARD_PASSWORD={your_pw}

Lucky

Lucky用于反向代理和证书申请。将云服务器的服务解析到次级域名,然后在Lucky中设置要必须通过https://{次级域名}:{指定端口}的形式来访问。这样可以在腾讯云后台里禁止其他服务的端口,只打开这个指定端口就好。

services:
    lucky:
        image: gdy666/lucky:2.12.7
        container_name: lucky
        volumes:
            - ./Lucky/data:/goodluck
        network_mode: host
        restart: always