172 lines
5.8 KiB
Markdown
172 lines
5.8 KiB
Markdown
# Manage
|
|
|
|
Manage is a media and server operations tool with Jellyfin integration, SSH file inspection, server monitoring, and safe remote job templates.
|
|
|
|
See `docs/REQUIREMENTS.md` for the living requirements, decisions, and planning history.
|
|
See `docs/MIGRATION_PLAN.md` for the FastAPI + React architecture plan.
|
|
|
|
Project policy/docs:
|
|
|
|
- License: `LICENSE` (MIT)
|
|
- Contributing guide: `CONTRIBUTING.md`
|
|
|
|
## Architecture
|
|
|
|
The project consists of two subprojects:
|
|
|
|
- **`backend/`** — FastAPI Python API (see `backend/README.md`)
|
|
- **`frontend/`** — React + TypeScript SPA (see `frontend/README.md`)
|
|
- **`archive/`** — Original Streamlit prototype (preserved for reference)
|
|
|
|
## Features
|
|
|
|
- Dashboard with now-playing sessions, server monitoring overview, and per-library media counts
|
|
- Server monitoring with CPU, IO wait, RAM, network, and disk I/O charts plus a sortable dashboard table covering all configured machines
|
|
- Per-machine monitoring settings with local and remote targets managed in the UI, plus backend-collected recent action history per machine
|
|
- SQLite-indexed media table with full-library sort/filter
|
|
- Read-only Users tab with Jellyfin as the base source and optional Jellyseerr enrichment
|
|
- Remote file browser with ffprobe preview and job execution
|
|
- Jellyfin API integration for library metadata and user identity data
|
|
- SSH-based file inspection and remote job templates
|
|
|
|
## Quick Start
|
|
|
|
### Docker Compose (recommended)
|
|
|
|
Production-style deployment with the frontend serving the SPA and proxying `/api` to the backend. The compose files rely on environment-variable interpolation, so export the required values in your shell before running them (no `env_file` is needed):
|
|
|
|
```bash
|
|
docker compose up --build
|
|
```
|
|
|
|
Open the app at http://localhost:8080.
|
|
|
|
Local development with hot reload:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.dev.yml up --build
|
|
```
|
|
|
|
Frontend runs on http://localhost:5173 and the backend on http://localhost:8000.
|
|
The backend media index is persisted in a Docker volume (`backend_cache`) so rebuilds and container restarts do not force a full re-index.
|
|
Monitoring machine definitions and recent machine activity are stored in the backend so the UI can show one section per configured machine and preserve history across restarts.
|
|
|
|
### Manual backend/frontend development
|
|
|
|
```bash
|
|
cd backend
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -e '.[dev]'
|
|
uvicorn media_library_viewer_api.main:app --reload --port 8000
|
|
```
|
|
|
|
```bash
|
|
cd frontend
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
## Configuration
|
|
|
|
The Compose files use environment-variable interpolation. Export the required variables in your shell or pass them inline; a `.env` file is optional, not required.
|
|
|
|
### Compose examples
|
|
|
|
Production-style example with shell exports:
|
|
|
|
```bash
|
|
export BACKEND_APP_HOST=manage.example.com
|
|
export FRONTEND_APP_HOST=manage.example.com
|
|
export CERT_RESOLVER=letsencrypt
|
|
export VITE_OIDC_ISSUER=https://authentik.example/application/o/manage/
|
|
export VITE_OIDC_CLIENT_ID=manage
|
|
export VITE_OIDC_REDIRECT_URI=https://manage.example.com/
|
|
export VITE_OIDC_POST_LOGOUT_REDIRECT_URI=https://manage.example.com/
|
|
|
|
docker compose up --build
|
|
```
|
|
|
|
Inline one-liner example:
|
|
|
|
```bash
|
|
BACKEND_APP_HOST=manage.example.com FRONTEND_APP_HOST=manage.example.com CERT_RESOLVER=letsencrypt VITE_OIDC_ISSUER=https://authentik.example/application/o/manage/ VITE_OIDC_CLIENT_ID=manage VITE_OIDC_REDIRECT_URI=https://manage.example.com/ VITE_OIDC_POST_LOGOUT_REDIRECT_URI=https://manage.example.com/ docker compose up --build
|
|
```
|
|
|
|
For local development, no SSH key is required unless you want to connect to remote SSH machines later:
|
|
|
|
```bash
|
|
docker compose -f docker-compose.dev.yml up --build
|
|
```
|
|
|
|
Example environment variables:
|
|
|
|
```bash
|
|
# Optional backend logging level
|
|
LOG_LEVEL=INFO
|
|
|
|
# Optional SMTP settings for the Users -> message popup
|
|
SMTP_HOST=smtp.example.com
|
|
SMTP_PORT=587
|
|
SMTP_USERNAME=your-smtp-username
|
|
SMTP_PASSWORD=your-smtp-password
|
|
SMTP_FROM_ADDRESS=no-reply@example.com
|
|
SMTP_FROM_NAME=Manage
|
|
SMTP_USE_TLS=true
|
|
SMTP_USE_SSL=false
|
|
SMTP_TIMEOUT=30
|
|
|
|
# Jellyfin, Jellyseerr, and SSH targets are now configured per machine in the app's Settings tab.
|
|
# The backend seeds a local machine automatically, so no global Jellyfin or SSH env vars are required.
|
|
#
|
|
# Remote SSH machines can store their private key and optional passphrase directly in Settings,
|
|
# so no SSH key mount is required for normal use.
|
|
|
|
# Authentik / OIDC
|
|
AUTH_ENABLED=true
|
|
OIDC_ISSUER_URL=https://authentik.example/application/o/media-library-viewer/
|
|
OIDC_AUDIENCE=media-library-viewer
|
|
OIDC_JWKS_URL=
|
|
OIDC_CLOCK_SKEW_SECONDS=30
|
|
|
|
# Frontend OIDC settings
|
|
VITE_OIDC_ENABLED=true
|
|
VITE_OIDC_ISSUER=https://authentik.example/application/o/media-library-viewer/
|
|
VITE_OIDC_CLIENT_ID=media-library-viewer
|
|
VITE_OIDC_SCOPE=openid profile email
|
|
VITE_OIDC_REDIRECT_URI=http://localhost:8080/
|
|
VITE_OIDC_POST_LOGOUT_REDIRECT_URI=http://localhost:8080/
|
|
```
|
|
|
|
## Remote server requirements
|
|
|
|
The remote server needs:
|
|
|
|
- Linux `/proc` and `/sys/block` for monitoring
|
|
- `/bin/sh` (POSIX shell)
|
|
- `python3`, `ffprobe`, `find`, `stat`, `df`, `awk`
|
|
|
|
The SSH client rejects unknown host keys. Connect manually once first:
|
|
|
|
```bash
|
|
ssh user@host
|
|
```
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Backend
|
|
cd backend && PYTHONPATH=src python -m py_compile src/media_library_viewer_api/main.py
|
|
|
|
# Frontend
|
|
cd frontend && npx tsc --noEmit && npm run build
|
|
```
|
|
|
|
## Notes
|
|
|
|
- Jellyfin server root URL required (not `/web`). The client strips trailing `/web` defensively.
|
|
- SSH commands run through `/bin/sh -c` regardless of remote login shell.
|
|
- Job templates are shell-quoted. Add new templates in `backend/src/media_library_viewer_api/jobs.py`.
|
|
- Monitoring collector uses JSONL in `/tmp`, pruned to 7 days / 70k lines.
|
|
- Root-level Docker Compose files are provided for production (`docker-compose.yml`) and local development (`docker-compose.dev.yml`), and both rely on Compose interpolation rather than `env_file` entries.
|