No description
  • Shell 49.7%
  • Go 43%
  • Python 5.6%
  • Dockerfile 1.2%
  • Nix 0.3%
  • Other 0.2%
Find a file
2026-08-17 09:35:01 -05:00
caddy feat: healthtick, staging mTLS profile, and secret/VPN docs 2026-08-09 16:19:32 -05:00
cmd feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
deploy Docs: link muxcore-operator v0.1.0 from deploy README. 2026-08-10 05:28:07 -05:00
dockerfiles Initial MVP host stack and wave status 2026-08-09 00:17:50 -05:00
docs feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
scripts feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
systemd feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
tls feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
.dockerignore Initial MVP host stack and wave status 2026-08-09 00:17:50 -05:00
.env.example feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
.gitignore feat: healthtick, staging mTLS profile, and secret/VPN docs 2026-08-09 16:19:32 -05:00
BFF-API.md feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
bootstrap-auth.sh Initial MVP host stack and wave status 2026-08-09 00:17:50 -05:00
Caddyfile feat: healthtick, staging mTLS profile, and secret/VPN docs 2026-08-09 16:19:32 -05:00
docker-compose.yml feat: observability compose profile; health-monitor stays default 2026-08-10 10:36:34 -05:00
go.mod Pin media-scanner v0.1.7 and build admin-ui with version ldflags. (#55) 2026-08-10 01:20:34 -05:00
go.sum Pin media-scanner v0.1.7 and build admin-ui with version ldflags. (#55) 2026-08-10 01:20:34 -05:00
local-registry.sh feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
muxcore.json Initial MVP host stack and wave status 2026-08-09 00:17:50 -05:00
muxcore.staging.json feat: healthtick, staging mTLS profile, and secret/VPN docs 2026-08-09 16:19:32 -05:00
PORTS.md feat: host optional media-graph and media-tagging peers 2026-08-10 07:23:14 -05:00
README.md feat: observability compose profile; health-monitor stays default 2026-08-10 10:36:34 -05:00
REPO-STATUS.md Initial MVP host stack and wave status 2026-08-09 00:17:50 -05:00
run-host-staging.sh Harden staging mTLS runner: absolute CA dir and docs. 2026-08-09 22:14:54 -05:00
run-host.sh feat: vault host-stack runner (classify-grabs, auth redirect env, VPN peer skip) 2026-08-17 09:35:01 -05:00
setup.sh Write run/VIEW-ME.txt on host up and setup. (#59) 2026-08-10 01:28:49 -05:00
smoke.sh Fail smoke when live module versions drift from spool catalog. (#58) 2026-08-10 01:27:19 -05:00

MuxCore MVP stack

Local reference compose for the media MVP path. Sibling clones under /home/user/Projects/MuxCore are the build context.

P0 Media MVP status: met (Wave 21 stack + smoke; Wave 22 packaging freeze). Operator URLs after ./run-host.sh up: run/VIEW-ME.txt.

Core pin: published v0.5.4 (remote storage sidecar dial; Settings mesh + chunked Put; mTLS from v0.5.1). Nested: pkg/contracts @ v0.5.4; sdk/go/module / sdk/go/client still @ v0.5.3. Modules pinning without replace (GOPRIVATE=github.com/Muxcore-Media/*, gh HTTPS):

Historical wave pins (still accurate as of each wave; later patch tags supersede — see spool catalog 2.4.13):

  • Waves 2526 (core-adjacent): auth-local, call-policy-default, publish-policy-default, secrets-file, encryption-aesgcm, api-rest, jellyfin@v0.2.1, media-root-folders@v0.1.1, health-monitor, metadata-tmdb@v0.1.1, database-sqlite, secrets-vault
  • Wave 27 (native media stack): contracts-media-admin@v0.1.0, contracts-notification@v0.1.1, media-movies@v0.1.1, media-tvshows@v0.1.1, media-scanner@v0.1.1, media-automation@v0.1.0, request-media@v0.2.2, notification-default@v0.1.0, admin-ui@v0.1.3
  • Wave 28 (leaves + smoke helpers): media-rename@v0.2.2, media-ffprobe@v0.1.2, media-subtitles@v0.4.2, media-custom-formats@v0.1.2. Host go.mod smoke helpers pin published module tags (sibling replaces removed); local replace => ../core* kept for host convenience.
  • Wave 29 (non-host sibling pins): media-list-sync@v0.1.1, notification-apprise@v0.1.1, workflow-tapestry@v0.1.0 (not started by default run-host.sh). Polluted org media-ui dump archived; use media-ui-app.

Consumer SPA: Muxcore-Media/media-ui-app (private; host uses sibling ../media-ui-app/dist-app).

Authoritative docs: ../core.wiki/Getting-Started.md, ../core.wiki/Deployment.md.
Spool presets mirrored: ../spool/tags/minimal.json, ../spool/tags/media.json.

Operator references in this repo: PORTS.md (default gRPC/HTTP ports), BFF-API.md (mediauiprox JSON contracts), tls/ (mTLS staging + secret rotation).

Prerequisites

  • Docker Compose v2 or host Go toolchain (run-host.sh)
  • Org repos cloned as siblings (same layout as this workspace)
  • Dev default: MUXCORE_INSECURE_DISABLE_TLS=true via ./run-host.sh. Staging mTLS: ./run-host-staging.sh (see tls/MTLS-STAGING.md).

GHCR images (optional)

Default compose builds from sibling trees. To pull prebuilt images instead, use docker-compose.ghcr.yml once muxcored (and peers) are published.

Publish muxcored from a host with rootless podman (e.g. gringotts):

./scripts/publish-muxcored-ghcr.sh v0.5.4

Requires gh token scopes repo + write:packages. Image build is verified locally as localhost/muxcored:v0.5.0 (rebuild for v0.5.1 before publish); GHCR push is blocked until the token has packages write.

Kubernetes (Phase 3 scaffold)

Kustomize overlays + Helm chart for the minimal platform slice live under deploy/:

kubectl apply -k deploy/kustomize/overlays/dev
# or
helm upgrade --install muxcore deploy/helm/muxcore -n muxcore --create-namespace

Images default to ghcr.io/muxcore-media/* (same GHCR P0 dependency). Host ./run-host.sh remains the verified operator path.

Quick start

Guided host setup (recommended):

cd mvp   # or _mvp in older layouts
./setup.sh

Prompts for TMDB (live key or offline fixtures), admin credentials, library paths, and optional Jellyfin; writes .env, starts ./run-host.sh up, bootstraps auth, and can run ./smoke.sh.

Manual path:

cd mvp
cp .env.example .env
# edit TMDB_API_KEY=… (or TMDB_FIXTURE=1) and MVP_ADMIN_* as needed

Docker Compose (preferred for containers)

docker compose up --build -d
./bootstrap-auth.sh
./smoke.sh

Host binaries (no Docker)

(cd ../core && go build -o ../_mvp/bin/muxcored ./cmd/muxcored)
(cd ../api-rest && go build -o ../_mvp/bin/api-rest ./cmd/module)
(cd ../media-tvshows && go build -o ../_mvp/bin/media-tvshows ./cmd/module)
(cd ../admin-ui && npx --yes @tailwindcss/cli@4.1.6 -i ./input.css -o ./assets/dist/styles.css --minify && go build -o ../_mvp/bin/admin-ui .)
(cd ../auth-local && go build -o ../_mvp/bin/auth-local ./cmd/module)
(cd ../jellyfin && go build -o ../_mvp/bin/jellyfin ./cmd/module)
(cd ../media-scanner && go build -o ../_mvp/bin/media-scanner ./cmd/module)
# Or rebuild many peers to spool catalog tags: ./scripts/rebuild-catalog-peers.sh media-scanner api-rest
(cd ../media-automation && go build -o ../_mvp/bin/media-automation ./cmd/module)

./run-host.sh up
# Single-module ops (core stays up; clears stale mesh registration on stop/restart):
# ./run-host.sh stop-one media-scanner
# ./run-host.sh restart admin-ui
# ./run-host.sh unregister media-scanner
./bootstrap-auth.sh
./smoke.sh
./run-host.sh stop

Admin UI: http://localhost:8082. Jellyfin bridge HTTP: http://127.0.0.1:8475/healthz (optional JELLYFIN_BASE_URL + JELLYFIN_API_KEY for a live server).

Scanner watches _mvp/data/downloads and imports into _mvp/data/library (SCANNER_IMPORT_MODE=copy).

Automation: soft queue APIs (AddToQueue / GetQueue / Search). Host stack sets MUXCORE_MESH_DIAL_LOCAL=true and absolute PUBLISH_POLICY_FILE / CALL_POLICY_FILE.

Smoke checks

  1. Core /health 200
  2. Discovery resolve (incl. media-tvshows, jellyfin, media-scanner, media-automation)
  3. Bearer /api/v1/modules
  4. AddMovie / AddTVShow
  5. Admin UI login via auth-local + /modules + /dashboard/monitor + /automation + /jellyfin
  6. Jellyfin /healthz + gRPC Status (soft OK when unconfigured)
  7. Jellyfin soft UpsertItemLink / ListItemLinks / SyncLibrary skip + fixture POST /webhook PlaybackStart
  8. Scanner ImportPath fixture → organized library file under data/library/Movies/...
  9. Automation queue soft (AddToQueue / GetQueue)
  10. Health-monitor ReportHealth + HTTP /status + mesh fan-out of module.degraded (visible on admin-ui /events?filter=health)
  11. Media-ui SPA (:5173) auth + shell + /api/movies / stream / /api/tv via mediauiprox BFF (skip if not running)
  12. Media-ui → request-media: search + POST /api/request (TMDB_FIXTURE=1 offline Fight Club hit, or live TMDB_API_KEY)
  13. Soft /api/jellyfin/play (200 linked / 404 unlinked or unconfigured)
  14. Optional live Jellyfin (SMOKE_LIVE_JELLYFIN=1, or auto when JELLYFIN_BASE_URL + JELLYFIN_API_KEY are set): Status configured + RefreshLibrary + SyncLibrary + sample PlayURL via cmd/jellyfinlive

Consumer SPA source/build: ../media-ui-app/ → org Muxcore-Media/media-ui-app (dist-app). Build with (cd ../media-ui-app && npm ci && npm run build).

Profiles

Profile Extra services
(default) platform + media path + admin-ui + jellyfin + scanner + automation + request-media + media-ui (host)
observability compose-only: metrics-prometheus (:9901 scrape) + tracing-otlp (slog fallback unless OTEL_EXPORTER_OTLP_ENDPOINT set)
media-ui compose-only: consumer SPA + BFF on :5173

Polluted media-ui/ dump is quarantined — shippable SPA is media-ui-app/. Operator admin remains admin-ui.

Endpoints

Service Host port (default)
core HTTP 8080
admin-ui 8082
api-rest HTTP 18080
auth-local gRPC / HTTP 9403 / 9401
media-movies gRPC 9420
media-tvshows gRPC / HTTP 9440 / 9450
media-automation gRPC 9460
downloader gRPC 9461
media-scanner gRPC 9470
jellyfin gRPC / HTTP 9475 / 8475
health-monitor gRPC / HTTP 9202 / 9203
media-ui (consumer SPA) 5173
request-media HTTP / gRPC 9380 / 9481
media-root-folders gRPC 9540