Featured image of post MoviePilot Docker 部署教程:让 NAS 自动追剧、自动整理媒体库

MoviePilot Docker 部署教程:让 NAS 自动追剧、自动整理媒体库

MoviePilot 装上之后,想看的片子会自己出现在媒体库里:它替你搜资源、交给下载器、改名归档,再通知 Jellyfin 刷新。本文用 Docker 部署 v3.2.5,含首次设置、密码过简报 422 的解决与硬链接目录规划。

先给结论

MoviePilot v3 是给 NAS 和自托管影音库用的媒体管理工具:按元数据搜索资源、建立订阅、把任务交给下载器,下完按命名规则整理进媒体库目录,再通知 Jellyfin、Emby、Plex 刷新媒体库。它不负责播放,播放仍由媒体服务器完成。

本文实测版本 jxxghp/moviepilot-v3:3.2.5,Ubuntu 24.04 通过。一条命令拉取:

docker pull docker.xuanyuan.run/jxxghp/moviepilot-v3:3.2.5
  • 版本:3.2.5,2026-11-06 发布;同日 latest 与它指向同一索引,下次发版后会改指向
  • 端口:容器内 Web 3000、API 3001;本文把宿主机 13300、13301 映过去
  • 卷:config(配置库)、core(浏览器内核缓存)、media(媒体根目录)三处
  • 体积:镜像约 700MB 量级,另加内核缓存与媒体库空间
  • 账号:没有默认密码,首次打开 Web 进「首次设置」自建管理员

镜像详情:https://xuanyuan.cloud/r/jxxghp/moviepilot-v3?xy_from=moviepilot-v3-docker-deploy

下面按「建目录 → 写 Compose → 启动 → 首次设置」四步走,命令可直接复制。全文固定 3.2.5,不写 latest。

环境要求

项目建议
系统Linux(正文按 Ubuntu 写);macOS 把 /www/wwwroot/moviepilot-v3 换成 ~/docker/moviepilot-v3
DockerDocker Engine + Compose V2(docker compose)
架构linux/amd64 或 linux/arm64
内存可用 ≥ 1GB;插件多、站点多时留更宽裕
磁盘镜像约 700MB 量级,另加 config、core 与媒体库
端口宿主机 13300 → 容器 3000;13301 → 3001
工作目录/www/wwwroot/moviepilot-v3
优雅停止stop_grace_period: 120s
docker --version
docker compose version

宿主机还没装 Docker 的话,用一键脚本:

bash <(wget -qO- https://get.xuanyuan.cloud/docker.sh)

备用地址 https://get.xuanyuan.me/docker.sh,用法相同。

标签怎么选

新装就用 3.2.5,别把 latest、dev 写进 Compose。

标签说明是否用于本文
3.2.5当前稳定版,2026-11-06 发布是
3.2.4、3.2.3更早的稳定版,便于回滚否
latest浮动标签,发版后改指向否
dev开发构建否

升级时改 Compose 里的标签,先备份 config。完整标签见 标签列表。

1. 创建目录

sudo mkdir -p /www/wwwroot/moviepilot-v3/{config,core,media/downloads,media/library}
sudo chown -R "$(id -u):$(id -g)" /www/wwwroot/moviepilot-v3
cd /www/wwwroot/moviepilot-v3

macOS:

mkdir -p ~/docker/moviepilot-v3/{config,core,media/downloads,media/library}
cd ~/docker/moviepilot-v3

三个目录各有各的用途,缺一个都会在重建容器时出问题:

宿主机目录容器内路径用途
config//config必挂:配置、SQLite 数据库、日志,务必备份
core//moviepilot/.cloakbrowser必挂:浏览器内核缓存,不挂则每次重建都重新下载
media//media媒体库与下载目录的共同根;计划硬链接时两者都要在这个根下

生产环境把 ./media 换成 NAS 共享盘路径,例如 /mnt/nas/media,并保证下载器容器看到的是同一路径约定。

2. 写入 compose.yaml

容器内 Web 仍听 3000、API 仍听 3001,所以 NGINX_PORT、PORT 保持原值。只把宿主机侧改成 13300、13301,避开常被前端占用的 3000。

cd /www/wwwroot/moviepilot-v3

cat > compose.yaml <<'EOF'
services:
  moviepilot:
    image: docker.xuanyuan.run/jxxghp/moviepilot-v3:3.2.5
    container_name: moviepilot-v3
    hostname: moviepilot-v3
    stdin_open: true
    tty: true
    ports:
      - "13300:3000"
      - "13301:3001"
    volumes:
      - ./config:/config
      - ./core:/moviepilot/.cloakbrowser
      # 生产示例:- /mnt/nas/media:/media
      - ./media:/media
    environment:
      - NGINX_PORT=3000
      - PORT=3001
      - PUID=0
      - PGID=0
      - UMASK=000
      - TZ=Asia/Shanghai
    restart: always
    stop_grace_period: 120s
EOF

几个容易写错的地方:

项说明
ports左边是宿主机、右边是容器。写成 3000:13300 就反了
NGINX_PORT / PORT保持 3000 / 3001,不要跟着宿主机改成 13300 / 13301
stop_grace_periodV3 停止时要收尾后台任务与插件,给足 120s,否则被强杀
PUID / PGID官方示例是 0;媒体文件属主不是 root 时改成宿主机的 UID/GID
Docker SocketV3 不需要映射 /var/run/docker.sock,容器内 supervisor 自己管重启

3. 启动与验证

docker compose up -d
docker compose ps
docker compose logs -f moviepilot

Ubuntu 24.04 上的实际输出:

[+] up 2/2
 ✔ Network moviepilot-v3_default Created
 ✔ Container moviepilot-v3       Started

NAME            IMAGE                                            SERVICE      STATUS                            PORTS
moviepilot-v3   docker.xuanyuan.run/jxxghp/moviepilot-v3:3.2.5   moviepilot   Up 3 seconds (health: starting)   0.0.0.0:13300->3000/tcp, 0.0.0.0:13301->3001/tcp

日志里应该看到这几行,顺序大致固定:

[INFO] → 启动容器进程 supervisor...
success: moviepilot-nginx entered RUNNING state
success: moviepilot-backend entered RUNNING state
Application startup complete.
Uvicorn running on http://0.0.0.0:3001
SQLite database journal mode set to: wal
GET /health/ready HTTP/1.1" 200 OK

本机探一下 Web:

curl -I http://127.0.0.1:13300
HTTP/1.1 200 OK
Server: nginx/1.26.3
Content-Type: text/html
Cache-Control: no-cache, no-store, must-revalidate

浏览器打开 http://服务器IP:13300,例如局域网里是 http://192.168.1.35:13300。

4. 首次设置:密码规则与 422 报错

V3 不预置管理员,首次打开会跳到「首次设置」页(地址形如 /#/initialize)。

  1. 超级管理员用户名:1~50 个字符
  2. 密码:6~50 位,且必须含字母、数字、特殊字符中的至少两类,两次输入一致
  3. API 访问密钥:点「生成」,长度 ≥16,自行备份
  4. GITHUB API 访问:可选,首次可跳过

MoviePilot 首次设置:管理员账号、已生成的 API 访问密钥

点「保存并前往登录 →」出现 「初始化失败,请检查服务状态后重试」,先别急着重建容器。看日志有没有这一行:

POST /api/v1/login/initialization 422

有的话说明服务是活的,只是表单没通过校验。实测最常见的原因是密码太简单(没同时满足两类字符),其次是两次输入不一致、密钥没生成或不足 16 位。改完刷新页面重提即可。

登录页勾选「保持登录」,页脚能看到版本 v3.2.5。

MoviePilot 登录页:用户名与保持登录

进到仪表盘时,下载器与目录还没配,存储与媒体统计基本都是 0,后台任务处于等待状态,这属于正常。右下角可能提示设置 GitHub Token,可以在「设定 → 系统 → 基础设置」里稍后补。

MoviePilot 仪表盘:存储空间、媒体统计与后台任务

存储与目录:硬链接要落在同一个根

打开「设定 → 存储 & 目录」,本机存储先显示「未配置」,用「+」添加,再在「目录」里按优先级加下载目录与媒体库目录,最后到「整理 & 刮削」确认命名规则与刮削来源。

MoviePilot 存储与目录:本机与网盘、目录与整理刮削

想做硬链接(不占双份空间、整理瞬间完成),必须同时满足两条:

  • 下载目录与媒体库目录在同一个容器内根路径下,本文就是 /media/downloads 与 /media/library
  • 下载器容器映射到同一台宿主机目录,例如两边都挂 /mnt/nas/media

只要有一条不满足,整理就会退化成复制,速度慢、还多吃一份磁盘。用 docker inspect 看两个容器的 Mounts 是否指向同一个 Source,一眼就能确认。

元数据源可用性可以顺手验证:侧栏「发现 → 推荐」能刷出正在热映,「探索」能按豆瓣筛选,「订阅 → 电影 / 电视剧」能看到热门片单。这几页正常,说明 Web 与元数据通了;真正自动追更前还要完成站点用户认证。

MoviePilot 推荐页:正在热映

MoviePilot 探索页:豆瓣筛选与海报列表

管理端口不要直接暴露到公网。需要远程访问,走可信组网或 HTTPS 反向代理。

备份、升级与 V2 迁移

停容器再打包,别在运行中直接 tar:

cd /www/wwwroot/moviepilot-v3
docker compose stop
tar -czf moviepilot-v3-config-backup.tar.gz config
docker compose start
目录备份策略
./config必备份,配置、数据库、日志都在这里
./core建议保留,丢了会重新拉浏览器内核
./media 或 NAS 路径按磁盘 / NAS 策略备份,与容器无关

升级只改 Compose 里的标签,然后:

docker compose pull
docker compose up --force-recreate -d

从 V2 到 V3:保留原来的 /config 映射,把镜像换成 jxxghp/moviepilot-v3 再重建,不能只重启旧容器。V3 升级过数据库后无法直接换回 V2 镜像,回退要按官方的「从 V3 降级回 V2」说明操作。大版本升级前先读 V3 版本说明 和 升级文档。

常见问题

默认用户名和密码是什么

没有默认账号。首次打开 Web 进「首次设置」,自建管理员并生成 API 访问密钥。

端口为什么是 13300 而不是 3000

容器内 Web 还是 3000,只是宿主机侧常被本机前端占用,本文改映成 13300。浏览器访问 http://IP:13300,而 NGINX_PORT 保持 3000。

可以用 latest 吗

latest 是浮动标签,发版后改指向,回滚时没法确定版本。生产用固定版本号 3.2.5。

页面打不开怎么排查

按顺序看三件事:docker compose ps 是否 Up;docker compose logs --tail 100 moviepilot 有没有 Application startup complete;宿主机 13300 / 13301 是否被占用、防火墙是否放行。

日志里 CloakBrowser、GitHub、TheMovieDb 报错要紧吗

外网不畅时常出现。只要 curl -I http://127.0.0.1:13300 是 200,可以先完成首次设置;代理与站点认证登录后再配。

和下载器路径对不上怎么办

两边必须看到同样的路径。比如都把宿主机 /mnt/nas/media 映成容器内 /media,那么无论下载器还是 MoviePilot,配置里都写 /media/...。不在同一 Docker 网络时,下载器地址先用局域网 IP 试。

删容器会丢片吗

不会。配置与库在 ./config,媒体文件在宿主机 media(或挂载的 NAS 路径)。docker compose down 不会删这两个目录。

拉取报 401 / 402 怎么办

先确认命令里的镜像名带了 docker.xuanyuan.run/ 前缀。401 是未登录或凭证失效,402 是流量用尽,两类报错的处理方式不同,见 常见问题。

命令速查

docker pull docker.xuanyuan.run/jxxghp/moviepilot-v3:3.2.5

cd /www/wwwroot/moviepilot-v3
docker compose up -d
docker compose ps
docker compose logs -f moviepilot

# 浏览器打开 http://127.0.0.1:13300 完成首次设置

docker compose down

没有 Compose 的话,用 docker run 起一个临时实例:把 image 展开成参数,端口 -p 13300:3000 -p 13301:3001,三个卷用 -v 各写一行,再加 --stop-timeout 120 --restart always。长期运行还是回到 Compose,改配置不用重敲整行命令。

附录:MoviePilot 是什么

MoviePilot 把订阅、搜索、下载、整理、刷库串成一条流水线:元数据识别是中心,下载器与媒体服务器是两端。它支持电影、电视剧,V3 起也支持音乐;能对接 qBittorrent、Transmission 等下载器,支持 Jellyfin、Emby、Plex 刷新,插件扩展通知(微信、Telegram、Slack)与远程指令。

适合家里有常开 NAS 或 Linux 主机、已经有下载器和影音库的人。如果只是偶尔下几部片,手工搜种更快;一旦有了固定追更的剧集和想统一的命名规则,这套自动化才开始划算。

延伸阅读

本文基于 jxxghp/moviepilot-v3:3.2.5,在 Ubuntu 24.04 上实测。

使用 Hugo 构建
主题 Stack,作者 Jimmy