feat: add Polaris app

This commit is contained in:
okxlin
2026-08-01 04:08:38 +08:00
parent 6ab05890ac
commit 8cf06fb0df
17 changed files with 490 additions and 0 deletions
@@ -0,0 +1,5 @@
PANEL_APP_PORT_HTTP=5050
POLARIS_MUSIC_DIR=./data/music
POLARIS_CACHE_DIR=./data/cache
POLARIS_DATA_DIR=./data/data
CONTAINER_NAME=polaris-compose-check
+67
View File
@@ -0,0 +1,67 @@
additionalProperties:
formFields:
- default: 5050
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP 端口
label:
en: HTTP Port
zh: HTTP 端口
zh-Hant: HTTP 埠
ja: HTTP ポート
ko: HTTP 포트
ru: HTTP-порт
ms: Port HTTP
pt-br: Porta HTTP
required: true
rule: paramPort
type: number
- default: ./data/music
edit: true
envKey: POLARIS_MUSIC_DIR
labelEn: Music Directory
labelZh: 音乐目录
label:
en: Music Directory
zh: 音乐目录
zh-Hant: 音樂目錄
ja: 音楽ディレクトリ
ko: 음악 디렉터리
ru: Каталог музыки
ms: Direktori muzik
pt-br: Diretorio de musicas
required: true
type: text
- default: ./data/cache
edit: true
envKey: POLARIS_CACHE_DIR
labelEn: Cache Directory
labelZh: 缓存目录
label:
en: Cache Directory
zh: 缓存目录
zh-Hant: 快取目錄
ja: キャッシュディレクトリ
ko: 캐시 디렉터리
ru: Каталог кеша
ms: Direktori cache
pt-br: Diretorio de cache
required: true
type: text
- default: ./data/data
edit: true
envKey: POLARIS_DATA_DIR
labelEn: Data Directory
labelZh: 数据目录
label:
en: Data Directory
zh: 数据目录
zh-Hant: 資料目錄
ja: データディレクトリ
ko: 데이터 디렉터리
ru: Каталог данных
ms: Direktori data
pt-br: Diretorio de dados
required: true
type: text
@@ -0,0 +1,26 @@
services:
polaris:
image: "quay.io/connectical/polaris:0.16.1-alpine3.24.1@sha256:2d29b66af8a555f8789203b55c81c1a5da6312357e18357a88acb6d49e55d75e"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:5050"
environment:
- POLARIS_PORT=5050
- POLARIS_CACHE_DIR=/var/cache/polaris
volumes:
- "${POLARIS_MUSIC_DIR}:/music:ro"
- "${POLARIS_CACHE_DIR}:/var/cache/polaris"
- "${POLARIS_DATA_DIR}:/var/lib/polaris"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
POLARIS_UID=100
POLARIS_GID=100
fail() {
printf '%s\n' "$1" >&2
exit 1
}
read_env_value() {
local key="$1"
local value
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
value="${value%$'\r'}"
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
printf '%s\n' "$value"
}
reject_symlink_components() {
local path="$1"
local current=""
local component
IFS='/' read -r -a components <<< "${path#/}"
for component in "${components[@]}"; do
[[ -n "$component" ]] || continue
current="${current}/${component}"
[[ ! -L "$current" ]] || fail "$path must not contain symbolic-link components"
done
}
resolve_path() {
local key="$1"
local raw="$2"
local candidate
local resolved
[[ -n "$raw" ]] || fail "$key must not be empty"
[[ "$raw" =~ ^[A-Za-z0-9._/\ -]+$ ]] || fail "$key contains unsupported characters"
if [[ "$raw" == /* ]]; then
candidate="$raw"
else
candidate="${ROOT_DIR}/${raw#./}"
fi
reject_symlink_components "$candidate"
resolved="$(realpath -m -- "$candidate")" || fail "Unable to resolve $key"
[[ "$resolved" != "/" ]] || fail "$key must not be the filesystem root"
if [[ "$raw" != /* ]]; then
case "$resolved" in
"${ROOT_DIR}"/*) ;;
*) fail "Relative $key must stay inside the application directory" ;;
esac
fi
[[ ! -e "$resolved" || -d "$resolved" ]] || fail "$key must be a directory"
printf '%s\n' "$resolved"
}
prepare_path() {
local key="$1"
local ownership="$2"
local resolved
resolved="$(resolve_path "$key" "$(read_env_value "$key")")"
install -d -m 0755 -- "$resolved" || fail "Unable to create $key"
resolved="$(realpath -e -- "$resolved")" || fail "Unable to verify $key"
reject_symlink_components "$resolved"
[[ -z "$(find "$resolved" -xdev -type l -print -quit)" ]] || fail "$key must not contain symbolic links"
if [[ "$ownership" == "polaris" ]]; then
chown -R --no-dereference "${POLARIS_UID}:${POLARIS_GID}" "$resolved" || fail "Unable to set $key ownership"
fi
}
[[ "$(id -u)" -eq 0 ]] || fail "Polaris init must run as root"
[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "Environment file not found or unsafe: $ENV_FILE"
prepare_path POLARIS_MUSIC_DIR readonly
prepare_path POLARIS_CACHE_DIR polaris
prepare_path POLARIS_DATA_DIR polaris
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
# Music, cache, accounts, playlists, indexes, and the database are user data.
exit 0
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
exec "$(dirname "${BASH_SOURCE[0]}")/init.sh"
+49
View File
@@ -0,0 +1,49 @@
# Polaris
## 产品介绍
Polaris 是一个自托管的音乐收藏与流媒体服务器,可通过浏览器和移动设备访问个人音乐库。
## 主要功能
- 扫描本地音乐目录并建立可搜索的收藏索引。
- 使用多账户、播放列表和浏览器流媒体功能管理个人音乐库。
- 将账户、播放列表、索引和应用数据库持久化保存。
## 部署说明
- 容器镜像由 Polaris 官方安装文档认可的 Connectical 容器项目提供。
- 安装后访问表单中配置的 HTTP 端口,创建管理员账户并添加 `/music` 音乐目录。
- 音乐目录以只读方式挂载;缓存和应用数据目录由 Polaris 的 UID/GID `100:100` 管理。
- 应用数据包含账户、播放列表、收藏索引和应用数据库,升级前应备份数据目录。
- 卸载不会删除音乐、缓存或应用数据。
## 数据目录
| 变量 | 说明 | 默认值 |
| --- | --- | --- |
| `POLARIS_MUSIC_DIR` | 音乐库目录,只读挂载 | `./data/music` |
| `POLARIS_CACHE_DIR` | 扫描和封面缓存目录 | `./data/cache` |
| `POLARIS_DATA_DIR` | 账户、索引和数据库目录 | `./data/data` |
初始化脚本会拒绝配置目录中的符号链接,并将缓存与数据目录递归设为 `100:100`。请为 Polaris 使用专用目录。
## 访问说明
安装完成后通过 `http://服务器地址:配置端口` 访问。首次使用时创建管理员账户,将 `/music` 添加为收藏目录,然后开始扫描。
## Introduction
Polaris is a self-hosted music collection and streaming server for browsers and mobile devices.
## Features
- Scan a local music directory into a searchable collection.
- Manage multiple users, playlists, and browser-based music streaming.
- Persist accounts, playlists, indexes, and the application database.
## 参考资料
- 项目主页: <https://polaris.stream>
- 源代码: <https://github.com/agersant/polaris>
- 容器说明: <https://github.com/ogarcia/docker-polaris>
+27
View File
@@ -0,0 +1,27 @@
# Polaris
Polaris is a self-hosted music collection and streaming server for browsers and mobile devices.
## Deployment
- The image comes from the Connectical container project endorsed by the Polaris installation guide.
- Open the configured HTTP port, create an administrator, and add `/music` as the collection directory.
- Music is mounted read-only. Cache and application data are owned by Polaris UID/GID `100:100`.
- Application data includes accounts, playlists, the collection index, and the application database. Back it up before upgrading.
- Uninstalling the app does not delete music, cache, or application data.
## Data directories
| Variable | Purpose | Default |
| --- | --- | --- |
| `POLARIS_MUSIC_DIR` | Read-only music library | `./data/music` |
| `POLARIS_CACHE_DIR` | Scan and artwork cache | `./data/cache` |
| `POLARIS_DATA_DIR` | Accounts, index, and database | `./data/data` |
The initialization script rejects symbolic links in configured directories and recursively assigns cache and data ownership to `100:100`. Use dedicated directories for Polaris.
## References
- Website: <https://polaris.stream>
- Source: <https://github.com/agersant/polaris>
- Container documentation: <https://github.com/ogarcia/docker-polaris>
+30
View File
@@ -0,0 +1,30 @@
name: Polaris
tags:
- 多媒体
title: 自托管的音乐收藏与流媒体服务器
description: 自托管的音乐收藏与流媒体服务器
additionalProperties:
key: polaris
name: Polaris
tags:
- Media
shortDescZh: 自托管的音乐收藏与流媒体服务器
shortDescEn: A self-hosted music collection and streaming server
description:
en: A self-hosted music collection and streaming server
zh: 自托管的音乐收藏与流媒体服务器
zh-Hant: 自託管的音樂收藏與串流伺服器
ja: セルフホスト型の音楽コレクションおよびストリーミングサーバー
ko: 자체 호스팅 음악 컬렉션 및 스트리밍 서버
ru: Самостоятельно размещаемый сервер музыкальной коллекции и потоковой передачи
ms: Pelayan koleksi muzik dan penstriman hos kendiri
pt-br: Servidor auto-hospedado de colecao de musicas e streaming
type: tool
crossVersionUpdate: true
limit: 0
recommend: 0
website: https://polaris.stream
github: https://github.com/agersant/polaris
document: https://github.com/agersant/polaris/blob/0d75a85724f43b064410c3dff7e1a78fe5aab04f/docs/CONFIGURATION.md
architectures:
- amd64
+5
View File
@@ -0,0 +1,5 @@
PANEL_APP_PORT_HTTP=5050
POLARIS_MUSIC_DIR=./data/music
POLARIS_CACHE_DIR=./data/cache
POLARIS_DATA_DIR=./data/data
CONTAINER_NAME=polaris-compose-check
+67
View File
@@ -0,0 +1,67 @@
additionalProperties:
formFields:
- default: 5050
edit: true
envKey: PANEL_APP_PORT_HTTP
labelEn: HTTP Port
labelZh: HTTP 端口
label:
en: HTTP Port
zh: HTTP 端口
zh-Hant: HTTP 埠
ja: HTTP ポート
ko: HTTP 포트
ru: HTTP-порт
ms: Port HTTP
pt-br: Porta HTTP
required: true
rule: paramPort
type: number
- default: ./data/music
edit: true
envKey: POLARIS_MUSIC_DIR
labelEn: Music Directory
labelZh: 音乐目录
label:
en: Music Directory
zh: 音乐目录
zh-Hant: 音樂目錄
ja: 音楽ディレクトリ
ko: 음악 디렉터리
ru: Каталог музыки
ms: Direktori muzik
pt-br: Diretorio de musicas
required: true
type: text
- default: ./data/cache
edit: true
envKey: POLARIS_CACHE_DIR
labelEn: Cache Directory
labelZh: 缓存目录
label:
en: Cache Directory
zh: 缓存目录
zh-Hant: 快取目錄
ja: キャッシュディレクトリ
ko: 캐시 디렉터리
ru: Каталог кеша
ms: Direktori cache
pt-br: Diretorio de cache
required: true
type: text
- default: ./data/data
edit: true
envKey: POLARIS_DATA_DIR
labelEn: Data Directory
labelZh: 数据目录
label:
en: Data Directory
zh: 数据目录
zh-Hant: 資料目錄
ja: データディレクトリ
ko: 데이터 디렉터리
ru: Каталог данных
ms: Direktori data
pt-br: Diretorio de dados
required: true
type: text
+26
View File
@@ -0,0 +1,26 @@
services:
polaris:
image: "quay.io/connectical/polaris:latest"
container_name: ${CONTAINER_NAME}
restart: unless-stopped
networks:
- 1panel-network
ports:
- "${PANEL_APP_PORT_HTTP}:5050"
environment:
- POLARIS_PORT=5050
- POLARIS_CACHE_DIR=/var/cache/polaris
volumes:
- "${POLARIS_MUSIC_DIR}:/music:ro"
- "${POLARIS_CACHE_DIR}:/var/cache/polaris"
- "${POLARIS_DATA_DIR}:/var/lib/polaris"
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
labels:
createdBy: "Apps"
networks:
1panel-network:
external: true
+83
View File
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
ENV_FILE="${ENV_FILE:-${ROOT_DIR}/.env}"
POLARIS_UID=100
POLARIS_GID=100
fail() {
printf '%s\n' "$1" >&2
exit 1
}
read_env_value() {
local key="$1"
local value
value="$(sed -n "s/^${key}=//p" "$ENV_FILE" | tail -n 1)"
value="${value%$'\r'}"
case "$value" in
\"*\") value="${value#\"}"; value="${value%\"}" ;;
\'*\') value="${value#\'}"; value="${value%\'}" ;;
esac
printf '%s\n' "$value"
}
reject_symlink_components() {
local path="$1"
local current=""
local component
IFS='/' read -r -a components <<< "${path#/}"
for component in "${components[@]}"; do
[[ -n "$component" ]] || continue
current="${current}/${component}"
[[ ! -L "$current" ]] || fail "$path must not contain symbolic-link components"
done
}
resolve_path() {
local key="$1"
local raw="$2"
local candidate
local resolved
[[ -n "$raw" ]] || fail "$key must not be empty"
[[ "$raw" =~ ^[A-Za-z0-9._/\ -]+$ ]] || fail "$key contains unsupported characters"
if [[ "$raw" == /* ]]; then
candidate="$raw"
else
candidate="${ROOT_DIR}/${raw#./}"
fi
reject_symlink_components "$candidate"
resolved="$(realpath -m -- "$candidate")" || fail "Unable to resolve $key"
[[ "$resolved" != "/" ]] || fail "$key must not be the filesystem root"
if [[ "$raw" != /* ]]; then
case "$resolved" in
"${ROOT_DIR}"/*) ;;
*) fail "Relative $key must stay inside the application directory" ;;
esac
fi
[[ ! -e "$resolved" || -d "$resolved" ]] || fail "$key must be a directory"
printf '%s\n' "$resolved"
}
prepare_path() {
local key="$1"
local ownership="$2"
local resolved
resolved="$(resolve_path "$key" "$(read_env_value "$key")")"
install -d -m 0755 -- "$resolved" || fail "Unable to create $key"
resolved="$(realpath -e -- "$resolved")" || fail "Unable to verify $key"
reject_symlink_components "$resolved"
[[ -z "$(find "$resolved" -xdev -type l -print -quit)" ]] || fail "$key must not contain symbolic links"
if [[ "$ownership" == "polaris" ]]; then
chown -R --no-dereference "${POLARIS_UID}:${POLARIS_GID}" "$resolved" || fail "Unable to set $key ownership"
fi
}
[[ "$(id -u)" -eq 0 ]] || fail "Polaris init must run as root"
[[ -f "$ENV_FILE" && ! -L "$ENV_FILE" ]] || fail "Environment file not found or unsafe: $ENV_FILE"
prepare_path POLARIS_MUSIC_DIR readonly
prepare_path POLARIS_CACHE_DIR polaris
prepare_path POLARIS_DATA_DIR polaris
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail
# Music, cache, accounts, playlists, indexes, and the database are user data.
exit 0
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
exec "$(dirname "${BASH_SOURCE[0]}")/init.sh"
+4
View File
@@ -0,0 +1,4 @@
The Polaris logo is copied from the agersant/polaris source repository and is
distributed under that repository's MIT license.
Source: https://github.com/agersant/polaris/blob/0d75a85724f43b064410c3dff7e1a78fe5aab04f/res/branding/logo/logo.png
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB