Run the dj-live app server from the dj-incarnadine-org module #39

Merged
forgejo-admin merged 2 commits from feature/live-celilo-module into main 2026-09-28 06:37:07 +00:00

Problem

The app server and the /live guest site only run locally. The dj-incarnadine-org module only publishes the static Astro site.

Solution

The module now also runs the app server. Upgrading from config-only to a module with a machine is supported, because each deploy reads the target manifest fresh.

  • Container: the module declares requires.system (an app-zone container) and the idp capability. Ansible installs the right-arch bun --compile binary and runs it under systemd, taking a SQLite .backup before each new binary starts.
  • Build: the site build now also produces the /live bundle, served by the same static route. It also cross-compiles the server for x86_64 and aarch64.
  • on_install:
    • reverse-proxies /live/trpc, including WebSockets
    • registers the dj-live OIDC client for incarnadine-djs, with localhost:3000 and 127.0.0.1:3579 redirect URIs
    • writes /etc/dj-live.env (0600) through applyRenderedConfig. The unit waits for that file.
  • Secrets: guest_token_secret is generated by celilo. The Spotify id and secret are operator-set and optional; guest search stays off until both are set.
  • Backups: on_backup, on_backup_analyze and on_restore handle the SQLite database.
  • Health check: probes the app server's port directly, because through Caddy the static catch-all would answer 200 even with the server down.
  • Caddy prefix: Caddy strips /live before proxying, so the server takes TRPC_ENDPOINT from the environment. The module sets /trpc; local use keeps /live/trpc.
  • Tests: bun run test scopes to src, app and scripts. Bare bun test also finds the module's hook tests, which need their own install, and Bun 1.3.3 ignores pathIgnorePatterns.
  • Release CI: the path filter now also covers app/**. A minor changeset takes the module from 0.5.2 to 0.6.0.
  • cele2e: a suite checks deploy, /, /live, health, the WebSocket 101, and that sessions survive a backup and restore.

This is Slice 8 of projects/2026-09-27-dj-online-companion/plan.md.

Testing

  • Module hooks: bun test in website/celilo-module/scripts passes 15 tests. celilo module check reports 0 failures.
  • Repo: bun run test passes 152 tests, and bun run check is clean.
  • The manifest's build steps, run by hand: the Astro site, the /live bundle (with /live/ asset URLs) and both Linux binaries all build.
  • A native binary compiled with TRPC_ENDPOINT=/trpc: /trpc/config returns 200, /live/trpc/config returns 404, and /live/health returns ok.
  • Not run: cele2e. Docker isn't running on the dev machine.

⚠️ Before merging the "Version Packages" PR this triggers

Merging the Version PR publishes 0.6.0. celilo-mgr would then provision a real container, register an Authentik client and change the Caddy routes on dj.incarnadine.org. Hold it until:

  1. the cele2e suite is green (which also confirms Caddy keeps ?token= on WebSocket upgrades)
  2. the Spotify secrets are set, or you're OK with search being off
  3. your account is in incarnadine-djs

🤖 Generated with Claude Code

## Problem The app server and the `/live` guest site only run locally. The `dj-incarnadine-org` module only publishes the static Astro site. ## Solution The module now also runs the app server. Upgrading from config-only to a module with a machine is supported, because each deploy reads the target manifest fresh. - **Container:** the module declares `requires.system` (an app-zone container) and the `idp` capability. Ansible installs the right-arch `bun --compile` binary and runs it under systemd, taking a SQLite `.backup` before each new binary starts. - **Build:** the site build now also produces the `/live` bundle, served by the same static route. It also cross-compiles the server for x86_64 and aarch64. - **`on_install`:** - reverse-proxies `/live/trpc`, including WebSockets - registers the `dj-live` OIDC client for `incarnadine-djs`, with localhost:3000 and 127.0.0.1:3579 redirect URIs - writes `/etc/dj-live.env` (0600) through `applyRenderedConfig`. The unit waits for that file. - **Secrets:** `guest_token_secret` is generated by celilo. The Spotify id and secret are operator-set and optional; guest search stays off until both are set. - **Backups:** `on_backup`, `on_backup_analyze` and `on_restore` handle the SQLite database. - **Health check:** probes the app server's port directly, because through Caddy the static catch-all would answer 200 even with the server down. - **Caddy prefix:** Caddy strips `/live` before proxying, so the server takes `TRPC_ENDPOINT` from the environment. The module sets `/trpc`; local use keeps `/live/trpc`. - **Tests:** `bun run test` scopes to `src`, `app` and `scripts`. Bare `bun test` also finds the module's hook tests, which need their own install, and Bun 1.3.3 ignores `pathIgnorePatterns`. - **Release CI:** the path filter now also covers `app/**`. A minor changeset takes the module from 0.5.2 to 0.6.0. - **cele2e:** a suite checks deploy, `/`, `/live`, health, the WebSocket `101`, and that sessions survive a backup and restore. This is Slice 8 of `projects/2026-09-27-dj-online-companion/plan.md`. ## Testing - Module hooks: `bun test` in `website/celilo-module/scripts` passes 15 tests. `celilo module check` reports 0 failures. - Repo: `bun run test` passes 152 tests, and `bun run check` is clean. - The manifest's build steps, run by hand: the Astro site, the `/live` bundle (with `/live/` asset URLs) and both Linux binaries all build. - A native binary compiled with `TRPC_ENDPOINT=/trpc`: `/trpc/config` returns 200, `/live/trpc/config` returns 404, and `/live/health` returns `ok`. - **Not run: cele2e.** Docker isn't running on the dev machine. ## ⚠️ Before merging the "Version Packages" PR this triggers Merging the Version PR publishes 0.6.0. celilo-mgr would then provision a real container, register an Authentik client and change the Caddy routes on dj.incarnadine.org. Hold it until: 1. the cele2e suite is green (which also confirms Caddy keeps `?token=` on WebSocket upgrades) 2. the Spotify secrets are set, or you're OK with search being off 3. your account is in `incarnadine-djs` 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The module grows from config-only to a container: Terraform provisions an
LXC, Ansible installs the compiled app server under systemd, and on_install
registers the console's OIDC client, proxies /live/trpc (WebSockets too) and
converges secrets onto the box as /etc/dj-live.env. The /live guest site
ships inside the static site. Adds sqlite backup/analyze/restore hooks, an
app-server probe in the health check, a cele2e deploy suite (not yet run),
and widens the release path filter to what the module now builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
public_web strips the /live route prefix before proxying, so the app server
takes its endpoint from TRPC_ENDPOINT (the module sets /trpc; local use keeps
/live/trpc). Root bun test also discovers the module's hook tests, which need
their own install, so bun run test scopes to src, app and scripts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
forgejo-admin deleted branch feature/live-celilo-module 2026-09-28 06:37:07 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
celilo/tango-dj!39
No description provided.