# MediaStationGo

MediaStationGo Logo

轻量、好看、适合 NAS 的私人媒体中心

Docker 一键部署 · 多用户管理 · 媒体库 · 刮削 · 下载整理 · Emby 协议兼容 · 网盘播放

English · 快速开始 · Docker 部署 · 常见问题 · 在线演示

Go React Docker License

--- ## 一句话介绍 MediaStationGo 是一个给个人、家庭 NAS、影音爱好者使用的媒体管理系统。 你可以用它做这些事: - 把电影、电视剧、动漫、综艺、音乐整理成漂亮的媒体库。 - 创建多个用户账号,给家人、朋友或不同设备分别管理登录和权限。 - 自动识别文件、补全海报、简介、年份、季集信息。 - 在网页里播放,也可以直接用 MediaStationGo 账号登录 Infuse、VidHub、SenPlayer、Emby 客户端等支持 Emby 协议的第三方播放器。 - 连接 qBittorrent,做搜索、订阅、下载、整理入库。 - 接入 OpenList / CloudDrive2 / WebDAV 等外部存储,支持 STRMURL 与 302 反代播放。 - 在 NAS、小主机、VPS、Windows Docker Desktop 上用 Docker Compose 快速运行。 > 项目还在快速迭代。默认 PostgreSQL 部署请同时备份 `data/` 和 `postgres/`。 --- ## 核心特点 - **一个服务端,多端播放**:只部署一次 MediaStationGo,不需要再重复部署 Emby 服务端。 - **兼容 Emby 协议客户端**:第三方播放器按 Emby/Jellyfin 方式添加服务器,直接用 MediaStationGo 账号密码登录。 - **多用户管理**:支持管理员、普通用户、账号启停、有效期、设备管理、Bot 注册/兑换码等家庭共享场景。 - **本地媒体 + 网盘媒体统一管理**:本地硬盘、下载目录、OpenList、CloudDrive2、WebDAV 等资源可以放在同一个后台管理。 - **下载到入库一条龙**:连接 qBittorrent 后,可做搜索、订阅、下载完成整理、刮削入库。 - **NAS 友好**:Docker Compose 部署简单,主数据库在 `postgres/`,运行密钥和配置在 `data/`,适合低功耗 NAS 和小主机长期运行。 --- ## 适合谁 - **新手用户**:只想复制一份 `docker-compose.yml`,改几个路径就跑起来。 - **NAS 用户**:想用低资源占用的媒体中心管理本地硬盘和网盘资源。 - **PT / 下载用户**:想把下载、整理、刮削、播放放到一个后台。 - **外部播放器用户**:想用一个 MediaStationGo 账号登录支持 Emby 协议的第三方播放器 APP。 - **家庭共享用户**:想给不同用户分配账号,不想为每个人重复搭一套媒体服务。 - **开发者**:想研究 Go + React 的自托管媒体项目。 --- ## 在线演示 - 地址:[https://mgo.3jzs.com](https://mgo.3jzs.com) - 账号:`admin` - 密码:`admin123` > 演示站只用于看功能,请不要填写私人 API Key、站点 Cookie 或真实隐私信息。 --- ## 快速开始 最推荐新手使用 Docker Compose。不要一开始就折腾 `.env`、裸机运行、源码编译。 ```bash mkdir -p MediaStationGo cd MediaStationGo curl -fsSL https://raw.githubusercontent.com/ShukeBta/MediaStationGo/main/docker-compose.yml -o docker-compose.yml ``` 编辑 `docker-compose.yml`: ```bash vi docker-compose.yml ``` 然后启动: ```bash docker compose up -d ``` 浏览器打开: ```text http://服务器IP:18080 ``` 默认登录: ```text 账号:admin 密码:admin123 ``` --- ## Docker Compose 推荐部署 仓库里的 `docker-compose.yml` 已经是轻量推荐模板:默认不用 `.env`,默认只启动 `MediaStationGo + PostgreSQL`,适合大多数 NAS。 旧版本如果已经有 `./data/mediastation.db`,首次使用新版 compose 启动时会自动导入到 PostgreSQL;`./data` 仍然要保留,用来保存 JWT 密钥、旧库迁移源和运行数据。 ### 三种部署模式 | 模式 | 命令 | 适合场景 | | --- | --- | --- | | 轻量模式:PG only | `docker compose up -d` | 大多数 NAS,资源占用最低 | | 标准模式:PG + Redis | `docker compose -f docker-compose.yml -f docker-compose.standard.yml up -d` | 多用户、Emby 客户端频繁刷新 | | 搜索增强:PG + Redis + OpenSearch | `docker compose -f docker-compose.yml -f docker-compose.standard.yml -f docker-compose.search.yml up -d` | 超大库、后续独立搜索索引 | 建议从轻量模式开始。Redis 和 OpenSearch 都是增强层,不是源数据库;低配 NAS 不要默认开启 OpenSearch。 ### 数据库选择与不再使用 SQLite 新版 Docker Compose 默认使用 PostgreSQL,不再把 SQLite 作为主数据库。判断运行时主库只看这两个配置: ```yaml environment: MEDIASTATION_DATABASE_TYPE: postgres MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable ``` `MEDIASTATION_DATABASE_DB_PATH` 只用于旧 SQLite 数据库的一次性导入: - 新部署:直接 `docker compose up -d`,会使用 PostgreSQL,不会创建新的 SQLite 主库。 - 旧版本升级:如果存在 `./data/mediastation.db`,首次启动新版 compose 时会自动导入到 PostgreSQL。 - 导入按主键补齐缺失数据,已有行会跳过;如果中途失败,修复后再次启动会继续补剩余表。 - 成功导入后会在 PostgreSQL 的 `settings` 表写入完成标记,之后即使旧 SQLite 文件还在也不会重复导入。 - Redis 是热缓存,OpenSearch 是搜索索引;它们都不是源数据库,丢失后可以重建。 旧 SQLite 升级到 PostgreSQL 的建议步骤: ```bash docker compose pull docker compose up -d docker compose logs -f mediastation-go ``` 看到 `sqlite data migrated to postgres`,或确认网页里的用户、媒体库、设置都正常后,再处理旧 SQLite 文件。 如果你确认以后不再使用 SQLite,也不希望应用再把旧 SQLite 当迁移源,可以这样做: > 只有在网页确认用户、媒体库、设置、媒体条目都已经出现在 PostgreSQL 后,才做下面这一步。 ```yaml environment: MEDIASTATION_DATABASE_TYPE: postgres MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable MEDIASTATION_DATABASE_DB_PATH: /data/disabled-sqlite-migration.db ``` 然后把宿主机上的旧文件改名或移走作为离线备份: ```bash mv data/mediastation.db data/mediastation.sqlite.bak ``` 裸机或自定义 `config.yaml` 部署时同理: ```yaml database: type: postgres dsn: postgres://mediastation:mediastation@127.0.0.1:5432/mediastation?sslmode=disable db_path: "" ``` 注意:不要删除 `./postgres`。迁移完成后真正的主数据库在 `./postgres`,`./data` 仍要保留,因为里面有 JWT 密钥和运行配置。 ### 镜像地址怎么选 两种镜像地址都可以用,选择其中一种写到 `image:` 即可: | 来源 | 镜像地址 | 适合场景 | | --- | --- | --- | | GitHub 仓库镜像 GHCR | `ghcr.io/shukebta/mediastation-go:latest` | 默认推荐,跟随仓库发布 | | Docker Hub | `shukbet/mediastationgo:latest` | 备用镜像,GHCR 拉取慢或不可用时使用 | 如果想固定版本,请先到仓库 Packages 页面确认 GHCR 是否有对应标签。写法如下: ```yaml image: ghcr.io/shukebta/mediastation-go:<版本标签> # GHCR 没有对应标签时,可以用 Docker Hub 备用: # image: shukbet/mediastationgo:MediaStationGo-v0.0.72 ``` 如果只想简单部署,直接使用 GHCR 的 `latest` 即可。 手动拉取示例: ```bash # GitHub 仓库镜像 docker pull ghcr.io/shukebta/mediastation-go:latest # Docker Hub 备用 docker pull shukbet/mediastationgo:latest ``` 你只需要重点看 `volumes` 这一段: ```yaml volumes: - ./data:/data - ./cache:/cache - ./media:/media - ./downloads:/downloads ``` 含义很简单: | 左边 | 右边 | 说明 | | --- | --- | --- | | `./data` | 主程序 `/data` | 程序配置、JWT 密钥、旧 SQLite 迁移源;主数据库在 `./postgres` | | `./cache` | 主程序 `/cache` | 缓存目录;可清理 | | `./media` | `/media` | 媒体库目录;自动整理入库需要可写,网页里添加媒体库时填 `/media/...` | | `./downloads` | `/downloads` | 下载目录;文件管理和自动整理会用 | | `./postgres` | PostgreSQL `/var/lib/postgresql/data` | 新版默认主数据库;一定要备份 | | `./redis` | Redis `/data` | 标准模式才会使用;热缓存,丢失可重建 | | `./opensearch` | OpenSearch `/usr/share/opensearch/data` | 搜索增强模式才会使用;占用内存较高 | 如果你的媒体在 NAS 真实目录,例如: ```text /vol1/1000/Media /vol1/1000/Downloads ``` 就把 compose 改成: ```yaml volumes: - ./data:/data - ./cache:/cache - /vol1/1000/Media:/media - /vol1/1000/Downloads:/downloads environment: MEDIASTATION_MEDIA_DIR: /vol1/1000/Media MEDIASTATION_DOWNLOAD_DIR: /vol1/1000/Downloads ``` 注意: - `volumes` 左边是宿主机 / NAS 的真实路径。 - `volumes` 右边是容器里的路径,建议固定用 `/media` 和 `/downloads`。 - 在网页里新建媒体库时,填容器路径,例如 `/media/电影`、`/media/电视剧`。 - 不要把 NAS 绝对路径写成 `./vol1/...`,`./` 表示当前部署目录下面的相对路径。 - Windows Docker Desktop 可以写成 `D:/Media:/media`、`D:/Downloads:/downloads`。 - 如果你只想扫描/播放、不使用自动整理入库,可以手动加 `:ro` 变成只读;只要要整理、重命名、入库,媒体库挂载必须保持读写。 ### 最简单 compose 示例 仓库根目录的 `docker-compose.yml` 就是这个思路。你也可以手动创建: ```yaml services: mediastation-go: # 镜像二选一: # GitHub 仓库镜像 GHCR: image: ghcr.io/shukebta/mediastation-go:latest # Docker Hub 备用: # image: shukbet/mediastationgo:latest restart: unless-stopped init: true depends_on: postgres: condition: service_healthy # 访问端口:浏览器打开 http://服务器IP:18080 ports: - "18080:8080" # 让容器可以访问宿主机上的 qBittorrent: # qB 地址可填 http://host.docker.internal:8085 extra_hosts: - "host.docker.internal:host-gateway" volumes: # 程序数据,升级前备份这个目录。 - ./data:/data - ./cache:/cache # 新手先用当前目录下的 media/downloads。 # NAS 用户把左边改成真实绝对路径。 - ./media:/media - ./downloads:/downloads environment: TZ: Asia/Shanghai PUID: "1000" PGID: "1000" MEDIASTATION_APP_HOST: 0.0.0.0 MEDIASTATION_APP_PORT: 8080 MEDIASTATION_APP_WEB_DIR: /app/web/dist MEDIASTATION_APP_DATA_DIR: /data # 轻量模式默认 PostgreSQL;旧 SQLite 会从这个路径自动迁移。 MEDIASTATION_DATABASE_TYPE: postgres MEDIASTATION_DATABASE_DSN: postgres://mediastation:mediastation@postgres:5432/mediastation?sslmode=disable # 确认迁移完成后,如需彻底禁用 SQLite 迁移源,可改成 /data/disabled-sqlite-migration.db。 MEDIASTATION_DATABASE_DB_PATH: /data/mediastation.db MEDIASTATION_CACHE_CACHE_DIR: /cache # 如果上面的 ./media / ./downloads 改成 NAS 真实路径, # 这里也改成同样的宿主机真实路径。 MEDIASTATION_MEDIA_DIR: ./media MEDIASTATION_MEDIA_CONTAINER_DIR: /media MEDIASTATION_DOWNLOAD_DIR: ./downloads MEDIASTATION_DOWNLOAD_CONTAINER_DIR: /downloads postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: mediastation POSTGRES_USER: mediastation POSTGRES_PASSWORD: mediastation volumes: - ./postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U mediastation -d mediastation"] interval: 10s timeout: 5s retries: 10 ``` > 说明:PostgreSQL 是主数据库;轻量模式也有进程内短缓存。Redis 是跨进程热缓存,OpenSearch 是搜索增强层,都不是源数据库。 --- ## 首次进入后怎么配置 1. **新建媒体库** - 进入「媒体库」页面。 - 路径填容器路径,例如 `/media/电影`。 - 点扫描。 2. **配置下载器** - 进入「下载器管理」。 - 如果 qBittorrent 在宿主机上,地址通常填 `http://host.docker.internal:8085`。 3. **配置刮削源** - 进入「系统设置 / 外部 API」。 - 按需填写 TMDb、Bangumi、TheTVDB、Fanart、豆瓣等配置。 4. **配置外部播放器** - 第三方客户端按 Emby/Jellyfin 方式添加服务器。 - 地址填 `http://服务器IP:18080`。 - 用户名和密码填 MediaStationGo 后台创建的账号,不需要单独部署 Emby 服务端。 - 管理员可以在后台/Bot 创建普通用户,让不同用户用自己的账号登录第三方播放器。 5. **配置网盘播放** - 进入「外部存储」配置 OpenList、CloudDrive2、WebDAV 等。 - 后台播放策略可以选择 STRMURL 或 302 反代。 - 开启哪个,就优先走哪个;都关闭时走普通服务端播放链路。 --- ## 更新、备份、日志 ### 更新 ```bash docker compose pull docker compose up -d ``` ### 查看日志 ```bash docker compose logs -f mediastation-go ``` ### 备份 默认 PostgreSQL 部署重点备份: ```text data/ postgres/ ``` `postgres/` 是主数据库,包含用户、媒体库、设置等核心数据;`data/` 保存 JWT 密钥、运行配置和旧 SQLite 迁移源,也要保留。 如果启用了增强模式,还可以按需备份: ```text redis/ # 热缓存,可不备份 opensearch/ # 搜索索引,可重建;超大库可备份以减少重建时间 ``` `cache/` 通常不用备份。如果你仍显式使用 `database.type=sqlite` 的旧部署,主库仍在 `data/mediastation.db`。 ### 停止 ```bash docker compose down ``` --- ## 常见问题 ### 1. 页面打不开? 先看容器是否启动: ```bash docker ps docker compose logs --tail=100 mediastation-go ``` 确认浏览器访问的是: ```text http://服务器IP:18080 ``` ### 2. 媒体库扫描不到文件? 最常见原因是路径写错。 - Docker `volumes` 右边是 `/media`。 - 网页媒体库路径就应该填 `/media/电影`,不要填 NAS 原始路径。 - 如果 qB 下载目录是 `/downloads`,自动整理源目录也优先填 `/downloads`。 ### 3. qBittorrent 连不上? 如果 qB 在宿主机上,地址试试: ```text http://host.docker.internal:8085 ``` 如果 qB 在另一台机器上,填那台机器的局域网 IP。 ### 4. NAS CPU 占用高? 建议先在系统设置里确认: - `ffprobe.max_concurrent` 设为 `1`。 - 自动整理、扫描后刮削、启动后扫描网盘按需开启。 - 大媒体库不要频繁全量扫描,优先手动扫描或夜间同步。 ### 5. 要不要用 `.env`? 新手不建议。直接改 `docker-compose.yml` 最直观。 `.env` 适合进阶用户在多台机器复用同一份 compose。仓库保留 `docker-compose.simple.env.example`,但它不是推荐主线。 --- ## 功能概览 | 分类 | 功能 | | --- | --- | | 媒体库 | 电影、电视剧、动漫、综艺、音乐、成人内容 | | 元数据 | NFO、本地图片、TMDb、TheTVDB、Bangumi、豆瓣、Fanart、JavBus/JavDB | | 播放 | Web 播放、Range 拖动、HLS 转码、直链、STRMURL、302 反代 | | 外部客户端 | Emby 协议兼容接口,MediaStationGo 账号可直接登录第三方播放器 | | 用户管理 | 多用户、管理员/普通用户、账号有效期、设备管理、Bot 注册与兑换码 | | 下载 | qBittorrent、站点搜索、订阅、下载完成后整理 | | 文件管理 | 浏览、整理、复制、移动、硬链接、软链接 | | 运维 | 任务队列、回收站、重复文件、通知渠道、运行日志 | | AI | OpenAI Compatible API、AI 搜索、推荐、助手 | --- ## 截图
界面预览 | 登录 | 首页 | | --- | --- | | 登录 | 首页 | | 媒体库 | 播放器 | | --- | --- | | 媒体库 | 播放器 |
--- ## 开发者运行 普通用户请优先使用 Docker。开发者可以这样运行: ```bash go run ./cmd/server ``` 前端: ```bash cd web npm install npm run dev ``` 测试: ```bash go test ./... cd web && npm run build ``` --- ## 社区与友链 - Telegram MediaStationGo交流群: - NodeSeek:[https://www.nodeseek.com/](https://www.nodeseek.com/) - LINUX DO:[https://linux.do/](https://linux.do/) --- ## 赞赏 如果这个项目节省了你的时间,欢迎请作者吃桶泡面。 微信赞赏码 --- ## Star History Star History Chart --- ## 许可证与非商用声明 本项目基础许可证遵循 `GPL-3.0`,详见 [LICENSE](LICENSE)。 项目维护者同时声明并倡议: - 本项目主要面向个人学习、家庭 NAS、自建影音、非商业研究与社区共建场景。 - 未经作者明确书面许可,不得将本项目或衍生版本用于商业售卖、商业托管、付费 SaaS、预装售卖设备、闭源二次分发或其他商业化牟利用途。 - 如需商业合作、企业内部部署、定制开发、集成发行或商业授权,请先联系作者确认授权边界。 - 若 README 的非商用声明与 `GPL-3.0` 正式许可文本存在解释差异,代码授权以 [LICENSE](LICENSE) 文件为准,商业使用请额外取得作者许可。 ---

Made with ❤️ by ShukeBta