Repository navigation
Ryot #2406
Description
Activity
The Ryot script is ready for testing. Run it in the Proxmox VE shell (or on an Incus host) to create a container:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/community-scripts/DevScripts/main/ct/ryot.sh)"There is no default account. Open http://:8000 and register: the first account becomes the administrator. Registration stays open to anyone who reaches the port, so once the accounts exist, set USERS_ALLOW_REGISTRATION=false in /opt/ryot_data/.env and run systemctl restart ryot-backend.
Books (OpenLibrary), anime and manga (AniList), podcasts (iTunes), audiobooks, music and visual novels work out of the box. Movies and shows need MOVIES_AND_SHOWS_TMDB_ACCESS_TOKEN, video games need VIDEO_GAMES_TWITCH_CLIENT_ID and VIDEO_GAMES_TWITCH_CLIENT_SECRET in /opt/ryot_data/.env, then systemctl restart ryot-backend. All options: https://docs.ryot.io/configuration.html
FRONTEND_URL in /opt/ryot_data/.env points at the container IP and is used for links in notifications and integrations. Change it when the IP changes or Ryot sits behind a reverse proxy or domain, then restart ryot-backend.
Ryot Pro keys (SERVER_PRO_KEY) are only verified by the official Docker images, which carry the vendor's verification key. A source build cannot validate them and always runs the community edition.
Install and every update compile the Rust backend and the React frontend from source, which takes about 30 minutes on 4 cores (longer on a busy host) and peaks at about 3 GB of RAM. The running app with PostgreSQL needs about 300 MB, so the RAM can be lowered after the install and raised again before an update.Note: This is not in the official repo yet—it's just a dev version! After merging into ProxmoxVE, it will need to be recreated.
Discord testing thread: https://discord.com/channels/1302816934508630047/1558036576561274935
ryot: nginx
Host $hoststrips port → all actions fail with 400 (react-router CSRF check)Body:
Script
ryot (testing, v10.5.0, Debian 13 LXC)
Symptom
GET /auth 200works, but everyPOST /auth.data?intent=login|registerfails with:
Error: Bad Request at singleFetchAction (chunk-4LKRSAEJ.mjs:847:31) POST /auth.data?intent=login 400Backend is healthy (
/backend/configOK,registerUser/loginUservia GraphQL directly returnStringIdObject/ApiKeyResponse).Root cause
install/ryot-install.shwrites nginx with:proxy_set_header Host $host; $host strips the port. Browser sends Origin: http://<ip>:8000, frontend sees Host: <ip> (no port). react-router 7.13 throwIfPotentialCSRFAttack() compares new URL(origin).host (<ip>:8000) vs Host header (<ip>) → mismatch → 400. Curl without Origin passes (422 from action validation), which confirms it. Relevant code: packages/react-router/lib/actions.ts → parseHostHeader() prefers x-forwarded-host, else host. Fix In /etc/nginx/sites-available/ryot: - proxy_set_header Host $host; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Host $http_host; then nginx -t && systemctl reload nginx. Login works immediately after. Suggestion Change the template in install/ryot-install.sh accordingly. Any app using @react-router/serve behind this nginx template will hit the same 400 on all actions when accessed via IP:port.
Name of the Script
Ryot
Script Type
CT (LXC Container)
Script path
No response
Where does it run?
Proxmox VE host
Does this script support arm64?
arm64 not tested
📋 Script Details
Ryot (Roll Your Own Tracker) is a self-hosted tracker for the media you consume and the workouts you do. It logs progress, ratings and reviews for movies, shows, books, audiobooks, anime, manga, comics, video games, podcasts, music and visual novels, pulls their metadata from providers such as TMDB, IGDB, OpenLibrary and AniList, imports history from Trakt, Goodreads, Jellyfin and others, and records workouts, exercises and body measurements. This script builds the Rust backend and the React frontend from source and runs them with PostgreSQL behind nginx.