Run SessionIQ with one command as a single container - #7
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
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_audioimports 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.pygains--if-emptyso 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_DIRandSESSIONIQ_SEED_DEMO, and the bind port falls back toPORT.web/Dockerfile,web/nginx.confandweb/.dockerignoreare gone with the second container they served.Verification
ruffclean/returns the SPA,/assets/*.jsreturns 200 with the right content type,/api/*is not shadowed by the catch-all mount/api/health, asserts the dashboard is served and that the baked library loaded — reportedassets: 17Removed: 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.