国庆节基本折腾好中年男人三件宝之一的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