> ## Content Index
> Fetch the complete content index at: https://sgpublic.xyz/llms.txt
> Use this file to discover other available public pages before exploring further.

# 解决 Docker 部署下 LanCache 与 nginx 共存的问题
- URL: https://sgpublic.xyz/p/2024/07/6aac9cb1810a4800015335ff/
- Published: 2024-07-31T00:53:16.000Z
- Updated: 2024-07-31T00:53:16.000Z
- Author: Haven Madray
- Tags: 网络与路由, Docker, NAS, #wp-post

在部署 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 都工作正常。