全网影视免费看!MoonTV 免费部署全教程⚡手机/电视/网页,Vercel、Cloudflare Pages、Docker一键部署

《部署教程说明》

🎬 MoonTV 是一个开箱即用的、跨平台的影视聚合播放器。它基于 Next.js 14 + Tailwind CSS + TypeScript 构建,支持多资源搜索、在线播放、收藏同步、播放记录、本地/云端存储,让你可以随时随地畅享海量免费影视内容。

【YouTube频道】 | 【Telegram群】 | 【GitHub仓库】

✨ 功能特性

  • 🔍 多源聚合搜索:内置数十个免费资源站点,一次搜索立刻返回全源结果。
  • 📄 丰富详情页:支持剧集列表、演员、年份、简介等完整信息展示。
  • ▶️ 流畅在线播放:集成 HLS.js & ArtPlayer。
  • ❤️ 收藏 + 继续观看:支持 Redis/D1/Upstash 存储,多端同步进度。
  • 📱 PWA:离线缓存、安装到桌面/主屏,移动端原生体验。
  • 🌗 响应式布局:桌面侧边栏 + 移动底部导航,自适应各种屏幕尺寸。
  • 🚀 极简部署:一条 Docker 命令即可将完整服务跑起来,或免费部署到 Vercel 和 Cloudflare。
  • 👿 智能去广告:自动跳过视频中的切片广告(实验性)

一、项目地址 👉 点击进入

点击查看项目截图 iptv

二、部署

本项目支持 Vercel、Docker 和 Cloudflare 部署。

1、Vercel 部署 (推荐)

普通部署(localstorage)

  1. Fork 本仓库到你的 GitHub 账户。
  2. 登陆 Vercel,点击 Add New → Project,选择 Fork 后的仓库。
  3. 设置 PASSWORD 环境变量。
  4. 保持默认设置完成首次部署。
  5. 如需自定义 config.json,请直接修改 Fork 后仓库中该文件。
  6. 每次 Push 到 main 分支将自动触发重新构建。

部署完成后即可通过分配的域名访问,也可以绑定自定义域名。

Upstash Redis 支持

  1. 完成普通部署并成功访问。
  2. upstash 注册账号并新建一个 Redis 实例,名称任意。
  3. 复制新数据库的 HTTPS ENDPOINT 和 TOKEN
  4. 返回你的 Vercel 项目,新增环境变量 UPSTASH_URL 和 UPSTASH_TOKEN,值为第二步复制的 endpoint 和 token
  5. 设置环境变量 NEXT_PUBLIC_STORAGE_TYPE,值为 upstash;设置 USERNAME 和 PASSWORD 作为站长账号
  6. 重试部署

访问 http://部署域名 即可。

2、Render 部署 (推荐)

普通部署(localstorage)

  1. Fork 或克隆本仓库到您的 GitHub/GitLab 账户
  2. 登录 Render,点击"Project" -> “new web service”
  3. 导入您的仓库,使用默认设置
  4. ⚠️ 重要:在"Environment" > "Environment Variables"中添加 PASSWORD 变量(必须设置)
  5. 点击"Deploy"

Render Redis 支持

  1. 完成普通部署并成功访问。
  2. Render 注册账号并新建一个 Redis 实例,名称任意。点击"Project" -> “new Key Value”
  3. 复制新数据库的Connections Internal Key Value URL
  4. 返回你的 Render 项目,新增环境变量 REDIS_URL,值为第二步复制的 Internal Key Value URL的值
  5. 设置环境变量 NEXT_PUBLIC_STORAGE_TYPE,值为 redis;设置 USERNAME 和 PASSWORD 作为站长账号
  6. 重试部署

访问 http://部署域名 即可。

3、Netlify 部署

普通部署(localstorage)

  1. Fork 本仓库到你的 GitHub 账户。
  2. 登陆 Netlify,点击 Add New project → Importing an existing project,授权 Github,选择 Fork 后的仓库。
  3. 设置 PASSWORD 环境变量。
  4. 保持默认设置完成首次部署。
  5. 如需自定义 config.json,请直接修改 Fork 后仓库中该文件。
  6. 每次 Push 到 main 分支将自动触发重新构建。

部署完成后即可通过分配的域名访问,也可以绑定自定义域名。

Upstash Redis 支持

  1. 完成普通部署并成功访问。
  2. upstash 注册账号并新建一个 Redis 实例,名称任意。
  3. 复制新数据库的 HTTPS ENDPOINT 和 TOKEN
  4. 返回你的 Netlify 项目,Project Configuration → Environment variables 新增环境变量 UPSTASH_URL 和 UPSTASH_TOKEN,值为第二步复制的 endpoint 和 token
  5. 设置环境变量 NEXT_PUBLIC_STORAGE_TYPE,值为 upstash;设置 USERNAME 和 PASSWORD 作为站长账号
  6. 重试部署

4、Cloudflare 部署 (有封号风险)

Cloudflare Pages 的环境变量尽量设置为密钥而非文本

普通部署(localstorage)

  1. Fork 本仓库到你的 GitHub 账户。
  2. 登陆 Cloudflare,点击 计算(Workers)-> Workers 和 Pages,点击创建
  3. 选择 Pages,导入现有的 Git 存储库,选择 Fork 后的仓库
  4. 构建命令填写 pnpm install --frozen-lockfile && pnpm run pages:build,预设框架为无,构建输出目录.vercel/output/static
  5. 保持默认设置完成首次部署。进入设置,将兼容性标志设置为 nodejs_compat,无需选择,直接粘贴
  6. 首次部署完成后进入设置,新增 PASSWORD 密钥(变量和机密下),而后重试部署。
  7. 如需自定义 config.json,请直接修改 Fork 后仓库中该文件。
  8. 每次 Push 到 main 分支将自动触发重新构建。

D1 支持

  1. 完成普通部署并成功访问
  2. 点击 存储和数据库 -> D1 SQL 数据库,创建一个新的数据库,名称随意
  3. 进入刚创建的数据库,点击左上角的 Explore Data,将 [D1初始化] 中的内容粘贴到 Query 窗口后点击 Run All,等待运行完成
  4. 返回你的 pages 项目,进入 设置 -> 绑定,添加绑定 D1 数据库,选择你刚创建的数据库,变量名称填 DB
  5. 设置环境变量 NEXT_PUBLIC_STORAGE_TYPE,值为 d1;设置 USERNAME 和 PASSWORD 作为站长账号
  6. 重试部署
点击展开查看 [D1初始化]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
CREATE TABLE IF NOT EXISTS users (
username TEXT PRIMARY KEY,
password TEXT NOT NULL,
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
);

CREATE TABLE IF NOT EXISTS play_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
key TEXT NOT NULL,
title TEXT NOT NULL,
source_name TEXT NOT NULL,
cover TEXT NOT NULL,
year TEXT NOT NULL,
index_episode INTEGER NOT NULL,
total_episodes INTEGER NOT NULL,
play_time INTEGER NOT NULL,
total_time INTEGER NOT NULL,
save_time INTEGER NOT NULL,
search_title TEXT,
UNIQUE(username, key)
);

CREATE TABLE IF NOT EXISTS favorites (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
key TEXT NOT NULL,
title TEXT NOT NULL,
source_name TEXT NOT NULL,
cover TEXT NOT NULL,
year TEXT NOT NULL,
total_episodes INTEGER NOT NULL,
save_time INTEGER NOT NULL,
UNIQUE(username, key)
);

CREATE TABLE IF NOT EXISTS search_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
keyword TEXT NOT NULL,
created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
UNIQUE(username, keyword)
);

CREATE TABLE IF NOT EXISTS admin_config (
id INTEGER PRIMARY KEY DEFAULT 1,
config TEXT NOT NULL,
updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
);

CREATE TABLE IF NOT EXISTS skip_configs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
source TEXT NOT NULL,
id_video TEXT NOT NULL,
enable INTEGER NOT NULL DEFAULT 0,
intro_time INTEGER NOT NULL DEFAULT 0,
outro_time INTEGER NOT NULL DEFAULT 0,
UNIQUE(username, source, id_video)
);

-- 基本索引
CREATE INDEX IF NOT EXISTS idx_play_records_username ON play_records(username);
CREATE INDEX IF NOT EXISTS idx_favorites_username ON favorites(username);
CREATE INDEX IF NOT EXISTS idx_search_history_username ON search_history(username);

-- 复合索引优化查询性能
-- 播放记录:用户名+键值的复合索引,用于快速查找特定记录
CREATE INDEX IF NOT EXISTS idx_play_records_username_key ON play_records(username, key);
-- 播放记录:用户名+保存时间的复合索引,用于按时间排序的查询
CREATE INDEX IF NOT EXISTS idx_play_records_username_save_time ON play_records(username, save_time DESC);

-- 收藏:用户名+键值的复合索引,用于快速查找特定收藏
CREATE INDEX IF NOT EXISTS idx_favorites_username_key ON favorites(username, key);
-- 收藏:用户名+保存时间的复合索引,用于按时间排序的查询
CREATE INDEX IF NOT EXISTS idx_favorites_username_save_time ON favorites(username, save_time DESC);

-- 搜索历史:用户名+关键词的复合索引,用于快速查找/删除特定搜索记录
CREATE INDEX IF NOT EXISTS idx_search_history_username_keyword ON search_history(username, keyword);
-- 搜索历史:用户名+创建时间的复合索引,用于按时间排序的查询
CREATE INDEX IF NOT EXISTS idx_search_history_username_created_at ON search_history(username, created_at DESC);

-- 跳过片头片尾配置:用户名+源+视频ID的复合索引,用于快速查找特定配置
CREATE INDEX IF NOT EXISTS idx_skip_configs_username_source_id ON skip_configs(username, source, id_video);

-- 搜索历史清理查询的优化索引
CREATE INDEX IF NOT EXISTS idx_search_history_username_id_created_at ON search_history(username, id, created_at DESC);

访问 `http://部署域名` 即可。

5、Docker 部署

1. 直接运行(最简单,localstorage)

拉取预构建镜像

1
docker pull ghcr.io/senshinya/moontv:latest

运行容器 -d: 后台运行 -p: 映射端口 3000 -> 3000

1
docker run -d --name moontv -p 3000:3000 --env PASSWORD=your_password ghcr.io/senshinya/moontv:latest

访问 http://服务器IP:3000 即可。(需自行到服务器控制台放通 3000 端口)

三、手机端观看 [点击观看视频教程]

📱 PWA:离线缓存、安装到桌面/主屏,移动端原生体验。

四、电视端AndroidTV观看 [点击观看视频教程]

目前该项目可以配合 OrionTV 在 Android TV 上使用,可以直接作为 OrionTV 后端

暂时收藏夹与播放记录和网页端隔离,后续会支持同步用户数据

[点击观看视频教程]

▶️ 新人YouTube 需要您的支持,请务必订阅频道帮我点赞关注打开小铃铛十分感谢!!!
✅在Fork项目时,请 follow 我的GitHub、给我所有项目一个 Star 星星支持下!你的支持是我不断前进的动力! 💖
解锁更多技能 加入TG群【am_clubs】YouTube频道【@am_clubs】【博客(国内)】【博客(国际)】
✅点击观看教程CLoudflare免费节点 | VPS搭建节点 | 获取免费域名 | 免费VPN | IPTV源 | Mac和Win工具 | AI分享

[点击展开] 赞赏支持 ~🧧 *我非常感谢您的赞赏和支持,它们将极大地激励我继续创新,持续产生有价值的工作。*
  • USDT-TRC20: TWTxUyay6QJN3K4fs4kvJTT8Zfa2mWTwDD
  • TRX-TRC20: TWTxUyay6QJN3K4fs4kvJTT8Zfa2mWTwDD

TRC10/TRC20扫码支付

免责声明:
1、该项目设计和开发仅供学习、研究和安全测试目的。请于下载后 24 小时内删除, 不得用作任何商业用途, 文字、数据及图片均有所属版权, 如转载须注明来源。
2、使用本程序必循遵守部署服务器所在地区的法律、所在国家和用户所在国家的法律法规。对任何人或团体使用该项目时产生的任何后果由使用者承担。
3、作者不对使用该项目可能引起的任何直接或间接损害负责。作者保留随时更新免责声明的权利,且不另行通知。


【流量光】 中转+专线高速机场 9.9元300G 14.9元500G✅畅爽晚高峰 解锁ChatGPT、全流媒体(送小火箭)
🌐官网:https://llgjc1.com

【红杏云】 中转高速机场,8元220G✅玩游戏首选,解锁ChatGPT、全流媒体(送小火箭) 🎁8折优惠码:AM科技
🌐官网:https://hongxingdl.com 👉[测评视频]

【极速云】 专线高速机场 低至8元100G✅畅爽晚高峰 解锁ChatGPT、全流媒体(送小火箭)🎁8折优惠码:AM888
🌐官网:https://极速666.com 👉[测评视频]