Publish to ghcr.io and simplify setup to compose + .env - #5
Merged
Merged
Conversation
Installing jellylook required cloning the repo and building the image locally. A GitHub Actions workflow now builds and publishes a multi-arch image to ghcr.io/dean1850/jellylook, so setup is two downloaded files and `docker compose up -d`. - Add .github/workflows/docker-publish.yml. It builds an amd64 image, boots it and checks /health, the UI, /api/status and /api/settings, asserts the container reports itself healthy and that startup fails fast on missing keys, and only then publishes linux/amd64 + linux/arm64. Tags: latest on main, semver on v* tags, short sha, and the branch name. - docker-compose.yml now pulls the published image; the local build path moves to docker-compose.build.yml for development. - Dockerfile gains OCI labels, tzdata so TZ actually applies to log timestamps, a HEALTHCHECK, and DATA_DIR. - Pin requirements so a given tag is reproducible. - Add .dockerignore. - Strip every comment and the hashed-out Tautulli block from .env.example; all three history sources are now listed uncommented and HISTORY_SOURCE alone selects which are required. The explanations move to README tables covering every variable, its default and where to get each key, alongside a no-clone quick start and update instructions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsEad8i4hYbwXXwAorPb6t
RECS_PER_SCAN in .env is overridden by the app_settings row that init_db() seeds, so it only applies before the database exists — say so rather than presenting it as the live batch size. Also stop listing semver tags as available before any release is tagged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsEad8i4hYbwXXwAorPb6t
init_db() seeded recs_per_scan=60 into app_settings, and _recs_per_scan() reads that table before falling back to .env, so RECS_PER_SCAN could never take effect on any install past its first run. recs_per_scan is no longer seeded. A missing row now means "use .env", and a row is written only when the user saves one in the Settings panel, so the panel still wins when it has been used deliberately. Saving the panel at the .env value clears the row instead of storing it, so routinely saving settings cannot silently pin the batch size and make a later .env edit look ignored. GET /api/settings returns the effective value rather than raw storage, so the panel shows the number a scan would really use instead of a hard-coded 60. Existing databases carry the seeded row, so a one-time migration drops it. A new schema_meta table records that it ran, so a value the user chooses later is never deleted on a subsequent start. Verified with an end-to-end suite driving the real app against stub upstreams: RECS_PER_SCAN=13 yields a 13-title batch, a saved override of 20 wins, saving 13 again returns control to .env, and a simulated pre-migration database picks up .env while keeping a later user choice across restarts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsEad8i4hYbwXXwAorPb6t
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.
Installing jellylook meant cloning the repo and building the image locally, and the setup instructions were split between the README and a wall of
#comments in.env.example— including a hashed-out Tautulli block users had to un-comment by hand.A GitHub Actions workflow now builds and publishes a multi-arch image to
ghcr.io/dean1850/jellylook, so installing is: download two files, fill in keys,docker compose up -d. Every comment is gone from.env.exampleand the explanations live in README tables instead.Changes
.github/workflows/docker-publish.yml— builds an amd64 image, boots it, and checks/health, the UI,/api/statusand/api/settings, asserts the container's ownHEALTHCHECKreportshealthy, and asserts startup fails fast on missing keys. Only then does it publishlinux/amd64+linux/arm64. Tags:latestonmain, semver onv*tags, short sha, and the branch name.docker-compose.ymlpulls the published image. The local build path moves todocker-compose.build.ymlfor development. The./databind mount is unchanged, so existing installs keep their SQLite database.Dockerfile— OCI labels (links the package to this repo),tzdatasoTZactually affects log timestamps, aHEALTHCHECK, andDATA_DIR. Still runs as root, matching the deliberate revert in Revert Dockerfile to run as root #2.requirements.txtpinned so a given tag is reproducible..env.example— all comments and the hashed-out Tautulli block removed. All three history sources are now listed uncommented;HISTORY_SOURCEalone decides which are required, so nothing needs commenting in or out.README.md— no-clone quick start, update instructions, a "building from source" section, and Configuration tables covering every variable, its default and where to get each key..dockerignoreadded.RECS_PER_SCANbug fix — see below.Fixing
RECS_PER_SCANTesting this migration surfaced a pre-existing bug:
RECS_PER_SCANin.envnever did anything.init_db()seededrecs_per_scan=60intoapp_settings, and_recs_per_scan()reads that table before falling back to.env, so the env var could not take effect on any install past its first run.recs_per_scanis no longer seeded. A missing row means "use.env"; a row is written only when the user saves one in the Settings panel, so a deliberate panel choice still wins. Two supporting details:.envvalue clears the row rather than storing it. The panel POSTsrecs_per_scanon every save, so without this, saving any setting once would silently pin the batch size and make a later.envedit look ignored all over again.GET /api/settingsreturns the effective value, so the panel shows the number a scan would really use instead of a hard-coded60.Existing databases already carry the seeded row, so a one-time migration drops it. A new
schema_metatable records that the migration ran, so a value the user picks later is never deleted on a subsequent start.Verification
Local end-to-end — 90/90 checks pass. The real FastAPI app was booted under uvicorn against stub Jellystat / Jellyfin / Tautulli / TMDb / OMDb / Seerr / LLM servers and driven over HTTP:
jellystatandtautullimodes, end to endfilmalias, and a rejected bad filterLLM_PROVIDERrejectedRECS_PER_SCAN=13yields a 13-title batch; a saved override of 20 wins; saving 13 again returns control to.env; a simulated pre-migration database picks up.envwhile keeping a later user choice across restarts.env.exampleparses as a real.env, its values coerce to the right types, and an unfilled copy reports exactly the five keys the README says are requiredIn CI on this branch every smoke-test step passed and the multi-arch push succeeded. The published manifest is a clean OCI index:
Confirmed pullable anonymously, so no registry login is needed. No
unknown/unknownplatform entries (provenance: false).I could not build the image on my own machine — this environment's egress policy blocks Docker Hub's blob CDN — so CI is the authority on the image itself. Everything above the image layer was verified locally.
One correction testing forced
I had written a README warning that trailing
#comments in.envbreak startup. I tested it: both Docker Compose and pydantic-settings strip them. The warning was wrong and was removed. Likewise, a note claiming forks' packages land private was removed — packages inherit the repo's visibility, verified with an anonymous pull.Note
The workflow also triggers on
claude/**branches, which is how the publish path was proven before merging. It means future branches publish a branch-tagged image (handy for testing, easy to drop — it's one line underon.push.branches). Theclaude-github-docker-ghcr-migration-x1x6pktag can be deleted from the package once this merges.