AI摘要:文章介绍了遇到使用 Docker 版 Clouddrive2 挂载网盘重启NAS后报错:IO Error mount point is not empty的问题及解决方法。作者提到了使用Plex挂载时不要挂载到CloudDrive的子目录,直接挂载CloudDrive的根目录,并重新配置plex资源库的路径即可。同时,作者也分享了老的方法以及配置容器启动参数、编写启动脚本和添加启动项的步骤。

跟着网上的教程使用 Clouddrive2 挂载 115 网盘搭建了 Plex 海报墙,但是重启后报错,115挂载不上。
IO Error mount point is not emptyIO Error mount point is not empty
看报错信息时说挂载点存在,经过观察,原来是 Plex 启动太快,Clouddrive2 还没挂载115网盘 Plex 容器就启动并映射了目录,那 Clouddrive2 当然挂不上啊。

20231011 有更简单的办法

Plex 挂载的时候不要挂载到 CloudDrive 的子目录,直接挂载 CloudDrive 的根目录,然后重新配置一下plex资源库的路径即可

    plex:
        container_name: plex
        hostname: J4125
        environment:
            - PUID=0
            - PGID=0
            - TZ=Asia/Shanghai
            - VERSION=docker
            - PLEX_CLAIM=xxxxxxx
        volumes:
            - '/data/plex:/config'
            - '/CloudNAS1:/mnt:shared' # 挂载到顶级目录,这样 Docker 就不会创建空目录导致 CloudDrive2 挂载失败了
        network_mode: host
        restart: "no"
        image: 'lscr.io/linuxserver/plex:latest'

老的方法

这个方法在CloudDrive2升级到0.5.11后有问题,不建议使用了

配置容器启动参数

我是通过 docker-compose 方式启动容器的。下面时我的docker-compose.yml与本文有关的片段(假设该文件路径为 /data/docker-compose.yml)。

version: '3.3'
services:
    cloudnas1:
        image: cloudnas/clouddrive2-unstable
        container_name: cloudnas1
        environment:
            - TZ=Asia/Shanghai
            - CLOUDDRIVE_HOME=/Config
        volumes:
            - "/CloudNAS1:/CloudNAS1:shared"
            - /data/CloudNAS/instance1:/Config
        devices:
            - /dev/fuse:/dev/fuse
        restart: "no"
        pid: "host"
        privileged: true
        ports:
            - 19798:19798
    plex:
        container_name: plex
        hostname: J4125
        environment:
            - PUID=0
            - PGID=0
            - TZ=Asia/Shanghai
            - VERSION=docker
            - PLEX_CLAIM=xxxxxxxx
        volumes:
            - '/data/plex:/config'
            - '/CloudNAS1/CloudDrive/115/电影挂载:/mnt/电影'
            - '/CloudNAS1/CloudDrive/115/电视挂载:/mnt/电视'
        network_mode: host
        restart: "no"
        image: 'lscr.io/linuxserver/plex:latest'

重点是禁止重启NAS容器自动启动,那就设置restartno

编写启动脚本

3202年了,当然是找 GPT 写啊,下面是启动脚本(假设脚本路径为 /data/startup.sh)。

#!/bin/bash

# 当目录存在时启动Docker服务的函数
start_docker_service() {
    dir_path="$1"
    shift  # 移除参数中的 dir_path
    services=("$@")
    
    while true; do
        # 检查指定目录是否存在
        if [ -d "$dir_path" ]; then
            echo "$dir_path 存在。正在启动 Docker 服务 $service_name..."

            # 切换到包含 docker-compose.yml 文件的目录(本文假设保存到/data下了,请注意修改)
            cd /data

            # 使用 docker-compose 启动 Docker 服务
            docker-compose -f docker-compose.yml up -d "${services[@]}"

            break  # 一旦命令执行完成,退出循环
        else
            echo "$dir_path 不存在。等待中..."
            sleep 5  # 等待 5 秒后再次检查
        fi
    done
}

# 检查 Docker 守护程序是否正在运行
while ! ps -ef | grep -q '[d]ockerd'; do
    echo "Docker 守护程序未运行。等待中..."
    sleep 5  # 等待 5 秒后再次检查
done

echo "Docker 守护程序正在运行。"

# 将根目录和 /data 目录设置为共享以进行挂载
mount --make-shared /

# 启动 CloudNAS1 的 Docker 服务 (cloudnas1 是docker-compose.yml 中定义的服务名)
docker-compose -f /data/docker-compose.yml up -d cloudnas1

# 当目录存在时启动服务 (我是把115挂载到 /CloudNAS1/CloudDrive/115 了)
# start_docker_service "检测的路径" "服务名称"  (plex 是docker-compose.yml 中定义的服务名)
start_docker_service "/CloudNAS1/CloudDrive/115" "plex"

# 运行未启动的容器
docker-compose -f /data/docker-compose.yml up -d

给标本增加可执行权限

chmod +x /data/startup.sh

尝试运行

/data/startup.sh

这时候脚本会卡死,因为一直在等待 Clouddrive2 挂载网盘

然后访问 IP:19798 配置 115 网盘,这里就不赘述了。

挂载好之后应该会执行下去并且退出的。

添加启动项

然后就是把脚本添加到启动项,我是用的 Openwrt 系统,和正常的 Linux 系统一样,可以添加

screen -S startup -dm /data/startup.sh

/etc/rc.local文件

下面是我的/etc/rc.local示例

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
screen -S startup -dm /data/startup.sh
exit 0

使用screen命令运行脚本是为了方便观察为啥脚本卡住了,openwrt默认没有screen命令,需要手动安装

opkg update
opkg install screen

检查日志

如果 Clouddrive2 容器无法正常启动,可以通过screen命令查看脚本的日志输出

screen -R startup