在部署 LanCache 的时候,发现官方文档中都没有将 80/443 端口映射到其他地址,而我实际部署下来,也确实不能映射到其他端口然后用本机已存在的 nginx 实例反代。加入官方 Discord,好巧不巧当时加进去的时候刚好有个老哥问了同样的问题,得到的答复是 LanCache 必须使用 80/443 端口。
在我的 NAS 上,LanCache 和 nginx 都是 docker 部署,参考 docker-compose.yaml 如下。
nginx:
version: "3"
services:
nginx:
image: nginx:1.25.2-bookworm
restart: unless-stopped
network_mode: host
volumes:
- /etc/localtime:/etc/localtime
- /mnt/core/app/nginx/conf.d:/etc/nginx/conf.d
- /mnt/core/app/nginx/stream.d:/etc/nginx/stream.d
- /mnt/core/app/nginx/nginx.conf:/etc/nginx/nginx.conf
- /mnt/core/app/nginx/common.d:/etc/nginx/common.d
- /mnt/core/app/nginx/modules.d:/etc/nginx/modules.d
- /mnt/core/app/nginx/cert:/etc/nginx/cert
- /mnt/core/app/nginx/page:/etc/nginx/page
- /mnt/core/var/tmp/nginx:/var/cache/nginx
- /mnt/core/var/log/nginx:/var/log/nginx
environment:
TZ: Asia/Shanghai
LanCache:
version: '2'
services:
lancache:
image: lancachenet/monolithic:latest
env_file: stack.env
restart: always
ports:
- 80:80/tcp
- 443:443/tcp
volumes:
- ${CACHE_ROOT}/cache:/data/cache
- ${CACHE_ROOT}/logs:/data/logs
environment:
UPSTREAM_DNS: 8.8.8.8
显然,两个服务都用了 80/443 端口,造成了冲突。于是考虑添加一个虚拟网卡获取第二个 IP,将 LanCache 的 80/443 端口绑定到第二个 IP 上。
实操
由于我对我的 NAS 要求有能重装系统后一键恢复状态的能力,因此我将对系统的修改汇总到一个脚本里。然而添加虚拟网卡需要每次开机时使用命令行,并且还要额外的配置文件来配置网卡,于是乎考虑 systemd service。
其他细节这里不展开说,编辑文件 /etc/systemd/system/vl-lancache.service
:
[Unit]
Description=Configure macvlan interface at startup
After=network.target
[Service]
Type=oneshot
ExecStart=/approot/etc/init.d/vl-lancache start
ExecStop=/approot/etc/init.d/vl-lancache stop
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
编辑文件 /approot/etc/init.d/vl-lancache
:
#!/bin/sh
### BEGIN INIT INFO
# Provides: macvlan
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Configure macvlan at startup
# Description: This script configures a macvlan interface at startup.
### END INIT INFO
case "$1" in
start)
echo "Creating macvlan interface..."
ip link add link enp5s0 name vl-lancache type macvlan mode bridge
ip link set vl-lancache up
# dhclient vl-lancache
;;
stop)
echo "Removing macvlan interface..."
ip link set vl-lancache down
ip link delete vl-lancache
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
这段是 ChatGPT 写的,我只是告诉他我需要用 ip link add link enp5s0 name vl-lancache type macvlan mode bridge
添加一个 macvlan,其中 enp5s0
是我物理网卡的设备名称,vl-lancache
是我想要添加 macvlan 的名称,剩下的交给 GPT,复制粘贴测试能用我就没管了。
编辑文件 /etc/network/interfaces.d/vl-lancache.conf
:
# Define the virtual interface
auto vl-lancache
iface vl-lancache inet dhcp
hwaddress ether 02:42:ac:11:00:02
这是给这个虚拟网卡设置一个 mac 地址,因为我考虑让其使用 DHCP 自动获取 IP,然后在路由器上统一管理 IP。且由于 IEEE 规定如果是单个站地址,第一字节最低位需设置为 0,如果是本地管理的 mac 地址,第一字节的最低第二位需要为 1,于是第一字节设置为 02,剩下的就随便乱写了,只要保证本地网络不冲突即可。
最后启用 vl-lancache
:
sudo systemctl enable vl-lancache
至此已经完成了虚拟网卡的添加,NAS 可以获取到第二个 IP 了。
然后修改两个 docker-compose.yaml
nginx:
version: "3"
services:
nginx:
image: nginx:1.25.2-bookworm
restart: unless-stopped
networks:
- nginx-network
ports:
- <第一个IP>:80:80
- <第一个IP>:443:443
volumes:
- /etc/localtime:/etc/localtime
- /mnt/core/app/nginx/conf.d:/etc/nginx/conf.d
- /mnt/core/app/nginx/stream.d:/etc/nginx/stream.d
- /mnt/core/app/nginx/nginx.conf:/etc/nginx/nginx.conf
- /mnt/core/app/nginx/common.d:/etc/nginx/common.d
- /mnt/core/app/nginx/modules.d:/etc/nginx/modules.d
- /mnt/core/app/nginx/cert:/etc/nginx/cert
- /mnt/core/app/nginx/page:/etc/nginx/page
- /mnt/core/var/tmp/nginx:/var/cache/nginx
- /mnt/core/var/log/nginx:/var/log/nginx
environment:
TZ: Asia/Shanghai
networks:
nginx-network:
name: nginx-network
LanCache:
version: '2'
services:
lancache:
image: lancachenet/monolithic:latest
env_file: stack.env
restart: always
ports:
- <第二个IP>:80:80/tcp
- <第二个IP>:443:443/tcp
volumes:
- ${CACHE_ROOT}/cache:/data/cache
- ${CACHE_ROOT}/logs:/data/logs
environment:
UPSTREAM_DNS: 8.8.8.8
重新 up 两个 docker-compose 即可,实测端口不冲突,且 LanCache 和 nginx 都工作正常。