Manage
Manage is a media and server-operations application with Jellyfin integration, SSH file inspection, monitoring integrations, safe remote-job templates, a FastAPI backend, and a React single-page application.
It includes a configurable dashboard, service registry, per-machine settings, a SQLite-indexed media library, a read-only Users view with optional Jellyseerr enrichment, remote file browsing with ffprobe, and SSH-based job execution.
Architecture and scope
backend/is the FastAPI API.frontend/is the React and TypeScript SPA.archive/retains the original Streamlit prototype for reference.
The root Compose files deploy only Manage's backend and frontend. Manage can expose /metrics and optional Alertmanager proxy endpoints, but it does not deploy Grafana, Prometheus, Loki, Alertmanager, Alloy, or Node Exporter as part of its normal stack. Configure service instances in the app's Services page.
Prerequisites
- Docker and Docker Compose for the supplied Compose stacks.
- Python 3.11 or newer for manual backend development.
- Node.js and npm for manual frontend development.
- A valid Fernet key for
MANAGE_ENCRYPTION_KEY, including in development Compose. - For production: an existing external Docker network named
web, Traefik, DNS/TLS configuration, and an OIDC provider.
Local development with Compose
-
Create
.envfrom the template and set a validMANAGE_ENCRYPTION_KEY. Docker Compose automatically reads.envfor interpolation; alternatively, export the same variables in the shell.cp .env.example .envGenerate a Fernet key if needed:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" -
Start the development stack:
docker compose -f docker-compose.dev.yml up --build
The development frontend is available at http://localhost:5173 and the backend at http://localhost:8000. Development Compose sets AUTH_ENABLED=false and VITE_OIDC_ENABLED=false, but still requires MANAGE_ENCRYPTION_KEY. The backend cache, settings database, media index, saved SSH keys, tasks, and dashboard widgets persist outside rebuilt containers.
Production-style deployment
The root docker-compose.yml is designed for deployment behind Traefik; it does not publish localhost ports. Before starting it, configure .env (or shell variables) with the required values:
BACKEND_APP_HOST,FRONTEND_APP_HOST, andCERT_RESOLVERfor Traefik routing and certificates.OIDC_ISSUER_URLandOIDC_AUDIENCEfor backend authentication.VITE_OIDC_ISSUER,VITE_OIDC_CLIENT_ID,VITE_OIDC_REDIRECT_URI, andVITE_OIDC_POST_LOGOUT_REDIRECT_URIfor the frontend build.MANAGE_ENCRYPTION_KEY, a valid Fernet key used to encrypt service secrets at rest.
Then run:
docker compose up --build
The production Compose file requires its external web network to exist. It is not a standalone local deployment; access is through the configured Traefik hostnames.
Manual development
Backend
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'
uvicorn media_library_viewer_api.main:app --reload --port 8000
Frontend
cd frontend
npm install
npm run dev
Tests and quality checks
# Backend
cd backend
ruff check .
python -m pytest
# Frontend
cd ../frontend
npm run lint
npm run build
npm run test
A focused frontend typecheck can be run with npx tsc --noEmit from frontend/.
Configuration and operations
.env.example is a template; do not commit real credentials or encryption keys. The Compose files interpolate environment values directly. Some template entries are for the optional observability example and are not consumed by the normal Manage Compose stack.
Optional SMTP settings (SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM_ADDRESS, SMTP_FROM_NAME, SMTP_USE_TLS, SMTP_USE_SSL, and SMTP_TIMEOUT) support the Users message popup.
Remote servers
A managed remote server needs a POSIX /bin/sh, python3, ffprobe, find, stat, df, and awk. Configure its SSH credentials in Manage's Settings. Unknown SSH host keys are rejected; establish trust first, for example:
ssh user@host
SSH commands run through /bin/sh -c regardless of the remote login shell.
Optional observability example
docker-compose.observability.yml is a separate, optional stack for Grafana, Prometheus, Loki, Alertmanager, Alloy, and Node Exporter. It is not required by Manage. Its header documents required *_ROOT persistence directories, CERT_RESOLVER, and Grafana/Prometheus/Alertmanager host variables. With those prepared, run:
docker compose -f docker-compose.observability.yml up -d
Set a non-default GRAFANA_ADMIN_USER and a strong, secret GRAFANA_ADMIN_PASSWORD before deploying this stack. Do not expose the example observability services with their defaults.
See docs/observability-runbooks.md for its operational documentation.
Repository layout
.
├── backend/ # FastAPI API and tests
├── frontend/ # React/TypeScript SPA and tests
├── archive/ # Preserved Streamlit prototype
├── docs/ # Requirements, migration, and operations docs
├── docker-compose.yml # Traefik-backed production-style stack
├── docker-compose.dev.yml # Local hot-reload development stack
└── docker-compose.observability.yml # Optional standalone observability example