There is no way to install this: no service unit, no image, no configuration example that is not the repository's own #115
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Everything measured so far runs out of a checkout with
cargo run. To be an install there needs to be:User=/Group=that owns the data directoryjellyfin-ffmpeg, because M5 settled that a stock distro ffmpeg answers differently about itself and earns arg strings no real install getsconfig.tomlat the repository rootNone of this is research. It is filed so that "production-ready" has something concrete under it, and so the ffmpeg pinning constraint is not rediscovered by whoever writes the image.
Where to start
Nothing here is research; it is filed so that "production-ready" has something
concrete under it and so the constraints below are not rediscovered.
User=/Group=that owns the data directory andthe hardening upstream's own packaging uses (take it from upstream's
debian/rather than writing one from memory).
jellyfin-ffmpegand not a distro build — M5 settled that upstream patchesits own (
tonemapx,alphasrc, therkrgafilters exist in no distro build)and that a stock binary answers differently about itself, which means it earns
arg strings no real install gets.
reference/pin.envis where the versionthat matters is pinned.
is not the repository's own
config.toml.README.mddocuments running froma checkout; an operator needs the other thing.
configuration file means the wizard (M9), and that is the supported way to set
a server up.
How to know it is done
Someone who has never seen the repository installs it from the artefact, reaches
the wizard, adds a library, and plays something — on a machine that is not this
one.
House rules
CLAUDE.mdis the short version and these are the parts that bite: tests rununder
cargo nextest; upstream's source is the checkout inupstream/at thepin (
v12.0-rc5,6d501ba4) and not the clone beside the repository;generated files are regenerated rather than edited; a comment says what the code
does, not how it got there; and
Dnreferences stay out of code and comments.ARCHITECTURE.mddecides which crate a thing goes in and which dependency edgesare illegal,
DECISIONS.mdsays why a rule exists.The reference pair is
cargo xtask reference up(andreference provision,which is idempotent); a run is
cargo run -p jellyfin-harness -- replay --upstream URL --ours URL --scenario FILE --out DIR,with
diff-dbfor the two databases.crates/jellyfin-harness/README.mdsayswhat a diff means and what an ignore entry has to carry — every entry needs a
reason and an expiry milestone, and an adds-only history is the smell the risk
table names.
Closed by
6f1515d, witha0ab72ebeside it.What is there
packaging/:Dockerfilecargo xtask packageentrypoint.sh/configand starts on itconfig.default.toml/config.example.tomlcompose.yamlsystemd/jellyfin-rs.servicesystemd/jellyfin-rs.sysusers.confdocs/install.mdis the operator's document: the data-directory layout for botharrangements, the two install paths, the first-run story, the reverse proxy, and
hardware acceleration.
The pinning constraint, so it is not rediscovered
The Dockerfile declares
RUST_VERSION, the twoWEB_*and the sevenFFMPEG_*arguments without defaults.
cargo xtask packagereads each from the filethat owns it —
rust-toolchain.tomlandreference/pin.env— andevery_pin_the_dockerfile_asks_for_is_passedfails if one is declared and notpassed. No version is spelled twice, so a moved pin cannot leave a stale copy
behind.
Three things the artefacts settled
choice. The first build was Debian trixie and the noble deb refused to
install:
Depends: libx265-199against trixie'slibx265-215.FFMPEG_DISTROis the base tag now. It also settles ICU — rust_icu links it rather than
bundling it, so the builder and the runtime have to be the same release.
debian/conf/jellyfin.service.confat the pinned ref is the whole listcommented out in a drop-in marked as an advanced feature, with several set to
falsewhere .NET needs them. Ours is on, because the binary was startedunder it and served — minus
PrivateDevices, which would hide/dev/drifromevery hardware transcode, and
MemoryDenyWriteExecute./etc. The serverwrites it: every dashboard save goes back to the file it was started on, and
ProtectSystem=strictleaves only the state, cache and log directorieswritable.
A bug packaging found
The server only watched for
SIGINT. systemd and docker both stop withSIGTERM, so every stop was a kill rather than a drain —a0ab72e. Verified bothways: the unit reports
ExecMainCode=exited/ExecMainStatus=0, anddocker stopreturns in 0.15s withshutting downlogged.How it was checked
systemd-analyze verifyclean, and the server started under the unit's fullhardening set with
systemd-run --user— serves, and stops cleanly./config/config.toml, theencoder it measures is
/usr/lib/jellyfin-ffmpeg/ffmpeg8.1.2 (the host's ownis 9.0.1, so the pin is what is inside), health check
healthy,/web/index.html200, and a second start does not rewrite the config.account, library, 4 films scanned,
PlaybackInfonegotiating direct play, anda
206withContent-Range: bytes 0-1023/97891.cargo nextest run --workspace: 2516 passed, 0 skipped. fmt and clippy clean.What the acceptance line still wants
"Someone who has never seen the repository installs it from the artefact … on a
machine that is not this one." Everything above ran on this machine, and no image
is published anywhere —
cargo xtask packagebuildsjellyfin-rs:devlocally.Publishing it, and an install on another host, is the part that is not done.