mirror of
https://github.com/okxlin/appstore.git
synced 2026-09-22 16:00:58 +00:00
feat: add Polaris app
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
exec "$(dirname "${BASH_SOURCE[0]}")/init.sh"
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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: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
|
||||
Executable
+83
@@ -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
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Music, cache, accounts, playlists, indexes, and the database are user data.
|
||||
exit 0
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
exec "$(dirname "${BASH_SOURCE[0]}")/init.sh"
|
||||
@@ -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 |
Reference in New Issue
Block a user