Skip to content

Run SessionIQ with one command as a single container - #7

Merged
xfznprojects merged 6 commits into
mainfrom
deploy-single-service
Sep 17, 2026
Merged

xfznprojects merged 6 commits into
mainfrom
deploy-single-service

Conversation

@xfznprojects

@xfznprojects xfznprojects commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

Makes SessionIQ runnable with one command on a local machine. Not a hosting change — there's a note at the end about what was removed and why.

What this replaces

Running SessionIQ meant installing Python 3.11+, creating a venv, pip-installing roughly a gigabyte of audio libraries, installing Node 22+, running pnpm install, seeding demo content, and starting two processes. Most people who want to look at it will not do that.

Now:

docker run --rm -p 8080:8000 sessioniq

One command, no Python, no Node, dashboard and demo library included.

The change

The API serves the built dashboard itself when one is present, so the app is one process on one origin — no reverse proxy, no CORS between the halves. Local development is untouched; the Vite dev server is used when no build is found.

The image generates the demo library during the build. That matters more than it sounds. analyze_audio imports librosa lazily, so an instance with a pre-built library never loads it at startup — I measured a 4 second boot with a populated library and zero librosa import in the log. Doing it at container start instead would mean ~40 seconds of CPU-heavy analysis before the app came up. It opens populated and fast.

seed_demo.py gains --if-empty so a container with a volume seeds once rather than overwriting the library on every restart. Verified in both directions against throwaway directories, so a real library is never at risk.

Also: configurable SESSIONIQ_CORS_ORIGINS, SESSIONIQ_STATIC_DIR and SESSIONIQ_SEED_DEMO, and the bind port falls back to PORT. web/Dockerfile, web/nginx.conf and web/.dockerignore are gone with the second container they served.

Verification

  • 169 tests pass (2 new), ruff clean
  • Dashboard serving checked end to end against a fresh production build: / returns the SPA, /assets/*.js returns 200 with the right content type, /api/* is not shadowed by the catch-all mount
  • CI's docker job now runs the image rather than only building it: it starts the container, waits on /api/health, asserts the dashboard is served and that the baked library loaded — reported assets: 17

Removed: hosting

An earlier revision of this PR added a Render blueprint and a deployment guide. I removed both, and the reasoning is worth keeping.

SessionIQ is a single-user local app — no authentication, one library per process. A public instance means anyone with the URL can read, upload and delete; free storage is ephemeral, so the instance cannot actually be used for anything; and it cuts against the offline-first claim the README leads with. The container work above is the part that serves running it on your own machine, which is what the app is for.

A two-container setup cannot be hosted on a single-service platform. The API
now serves the built dashboard when one is present, so a deployment is one
process on one origin with no reverse proxy and no CORS between them.

Local development is unchanged: the Vite dev server is used when no build is
found. CORS origins and the bind port are configurable, and PORT is honoured
for hosts that inject it.
Replaces the nginx-plus-API pair with a single image that builds the dashboard
and serves it alongside the API, which is what makes the app hostable on a
single-service platform.

The demo library is generated during the image build. Audio analysis is the
expensive part of this app and librosa is imported lazily, so doing it at
build time takes a cold start from roughly a minute of analysis down to a few
seconds of loading an index. nginx and its configuration are gone with the
second container they served.

seed_demo.py gains --if-empty so a container with a persistent volume seeds
once instead of overwriting the library on every restart.
DEPLOY.md covers the steps, the environment variables, and what a free
instance does and does not give you. It leads with the two things a reader
needs to know before hosting this: there is no authentication, so a public
instance should not hold a private library, and free storage is ephemeral, so
the demo library is what you get back after a restart.
Building proves the Dockerfile is valid; it does not prove the container
serves anything. The job now starts the image, waits for the health endpoint,
checks the dashboard is served and that the baked demo library loaded.
SessionIQ is a single-user local app: it has no authentication and expects one
library per process. On a public host anyone with the URL can read, upload and
delete, and free storage is ephemeral so the instance cannot actually be used
for anything. It also cuts against the offline-first claim the README leads
with.

The container work stays, because that is the half that serves running it
locally: one command brings up the whole app, dashboard included, with a demo
library already baked into the image. That replaces a Python and Node
toolchain setup with a single docker run.

The container reference moves into the README, so there is no separate
deployment document to keep in step.
@xfznprojects xfznprojects changed the title Make SessionIQ deployable as a single service Run SessionIQ with one command as a single container Sep 17, 2026
@xfznprojects
xfznprojects merged commit e8964c4 into main Sep 17, 2026
4 checks passed
@xfznprojects
xfznprojects deleted the deploy-single-service branch September 17, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant