Kubernetes deployment with Argo CD
aidj-gitops is the deployment repository. Its manifests/ Kustomize application targets namespace prochain-aidj on the existing microk8s cluster. The Argo CD project restricts the application to that repository and namespace. Automatic synchronization and self-healing are enabled; automatic pruning is disabled. Persistent volume claims additionally opt out of pruning/deletion.
Services
| Component | Deployment | Access |
|---|---|---|
| Rust API / offline B2B lab | aidj-api | Cluster service on 8787; browser requests proxied through the UI gateway |
| Next.js UI and gateway | aidj-ui | admin.bitview.club |
| Documentation | aidj-docs | checkpoint.bitview.club |
| Four virtual CDJs | cdj1 through cdj4 | Internal authenticated HTTP services on 8788 |
| Shared virtual mixer | mixer | Internal authenticated HTTP service on 8788 |
| Rust analyzer | aidj-analyzer | Suspended CronJob template; explicit one-track Jobs |
| MongoDB | Existing service | Existing database prochain_aidj, scoped runtime credentials |
| Qdrant | Existing nexus-qdrant service | Collection prochain_aidj_tracks_v1 |
| RabbitMQ | rabbitmq StatefulSet in prochain-rabbitmq | Private AMQP on 5672; queue runbook |
The UI image uses relative /api/v1 and /api/v1/ws URLs. The gateway forwards those paths to the API and preserves WebSocket upgrades; Next.js continues serving its own /api/live-clubs routes. In the deployed Keycloak environment, all pages connect through the authenticated gateway without a browser connection token. Explicit operator tokens and signed cookies remain available only for standalone local development. Cross-origin/cross-site controls are rejected, and token rotation invalidates sessions. Anonymous loopback mode is retained only when remote operator authentication is not configured.
Images are built from the application repositories, pushed to the private Harbor project prochain-aidj, and referenced by digest in GitOps. Argo CD reads a Kubernetes repository Secret. The GitHub repository disallows deploy keys; the initial bootstrap uses the current GitHub CLI credential in that Secret. Replace it with a suitably scoped GitHub App/HTTPS credential for long-term operations. No application, registry, Mongo or Qdrant credential is stored in Git.
Storage and analysis
aidj-data holds imported originals, canonical PCM, session artifacts and exports. aidj-models holds the separately provisioned ONNX runtime and optional research weights. Both use microk8s-hostpath on the current single node. These are local persistent volumes, not replicated storage or backups.
The initial migration copies the existing imported assets, not the entire Windows source library. The 6,005-file source inventory still points at D:\_Music\_DJ_Deck_Main (/mnt/d/_Music/_DJ_Deck_Main in WSL) and remains paused. Whole-library ingestion in Kubernetes requires a mounted or copied music source with a cluster-valid path; do not resume that source inside a pod before provisioning it. The imported tracks can already be inspected, played, analyzed and indexed from the shared data volume.
Research voice/genre/mood weights retain their separate licensing requirements and are not included in Git or application images. The runtime shared libraries and notices are copied alongside them. The analyzer's scheduled template is suspended and only reports source status by default. The GitOps helper creates a bounded Job:
python3 tools/analyze-track.py TRACK_UUID
# Or refresh only the derived index, without decoding/inference:
python3 tools/analyze-track.py TRACK_UUID --index-only
A full analysis Job runs analyzerd analyze and then index-tracks for that one UUID. It does not drain or unpause the library queue. Inspect Job logs and the resulting immutable report before approving track analysis.
Booth boundary
The cluster deployment runs the four HTTP player services and one shared mixer. It does not automatically reproduce the earlier Hyper-V/macvlan PRO DJ LINK LAN setup. Kubernetes pod networking is not a broadcast LAN for physical rekordbox/CDJs. Physical discovery, separate device IP/MAC identities and physical mixer audio outputs need a dedicated network/audio deployment profile. The original VM booth remains stopped.
The live UI exposes this virtual cluster setup, while the offline planner and live four-player scheduling remain separate. No automatic AI session, physical hardware command or full-library analysis is started by deploying these services.
Operations
kubectl -n argocd get application prochain-aidj
kubectl -n prochain-aidj get deployments,pods,services,pvc,cronjobs
kubectl -n prochain-aidj logs deployment/aidj-api
Bootstrap/recovery instructions and the exact resource definitions live in the GitOps repository. Use a Git commit to update image digests or configuration. Roll back by reverting that commit. Runtime Secrets must be provisioned separately on a replacement cluster. Protect the data volume with backups before destructive maintenance; Argo pruning is not a backup strategy.
Admin sign-in and audio monitoring
The admin site requires Keycloak sign-in in the dedicated aidj realm at identity.bitview.club and the
prochain-aidj-admin:admin client role. The documentation site remains public.
OAuth2 Proxy runs beside the UI and protects pages, APIs, WebSockets and audio.
Both the ingress and the old UI NodePort target this proxy; the Next.js server
and gateway bind only to loopback inside their pod.
The OIDC client uses an exact HTTPS callback and authorization code flow with
PKCE S256. It does not enable password grants or self-registration. The existing
realm's login policy is unchanged. Credentials are in the aidj-oidc Kubernetes
Secret, outside Git. The GitOps repository contains the client specification and
an explicit tools/configure-keycloak.py --realm aidj --user alexl helper
for granting existing users the dedicated role. See its deployment manifest for
the selected realm; roles and credentials are bootstrapped, not reconciled by Argo.
SSO cookies are Secure, HttpOnly and host-only, with an eight-hour expiry and
five-minute refresh. Role revocation takes effect on a subsequent refresh;
existing open connections may continue until closed. /oauth2/sign_out clears
the application's SSO cookie but does not end the Keycloak session for other
applications. Engine tokens remain server-side; users do not enter them after Keycloak sign-in.
After signing in, open Live Clubs, select your booth, and click Listen to master. The stream plays through the browser's selected local speakers at an initial monitor volume of 25%. A track must be loaded and playing, with channel and master levels above zero. Browser buffering adds delay, so this monitor is not a sample-synchronized cue output.
The initial operator is aidj / alexl. The new account requires a password change
at first login. Self-registration and email password reset are disabled; later
password resets are performed by a Keycloak administrator. No existing realm
account password was changed or copied.
Personal libraries and shared booths
Sign-in opens the provisioned booth under Live clubs. User profiles and booth
access live in MongoDB. User identity is the Keycloak issuer plus subject, so
changing a username does not transfer data ownership. The original music library
and Festival B2B setup belong to aidj/alexl. Additional admitted users receive a
private library/API and their own four-CDJ/shared-mixer runtime. Source music is
not copied into other accounts automatically.
| Booth role | Permissions |
|---|---|
| Owner | Manage members and DJ positions; control all decks and mixer |
| DJ | Load own-library tracks and control the assigned two decks; shared mixer access while assigned |
| Listener | View the booth and listen to master audio |
Owners use Booth members and DJ positions to invite a username after that person has signed in once, grant a role, assign DJ A/B, or revoke access. Each position can be human or AI, representing human–human, human–AI and AI–AI sessions. Assigning an AI position does not start live autonomous scheduling; the existing AI planner runs in the offline B2B lab. Owners may manually override all decks.
Access checks run server-side for every booth read, load, command and permission change. Changing membership never shares a personal library or session archive. Active listener streams recheck membership every three seconds. Concurrent access changes require the current revision, and MongoDB records an audit entry.
Per-user runtimes isolate metadata with Mongo collection prefixes, use dedicated Qdrant collections, and store assets under separate PVC subdirectories. These application-managed workloads come from the GitOps runtime template. Existing runtimes require an explicit image update; user deletion does not automatically delete music, Mongo metadata, credentials or Kubernetes workloads. See the GitOps README for provisioning permissions, backups and coordinated key rotation.