Repository navigation
Releases
MediaTrail 0.25.7
MediaTrail 0.25.7 is a self-hosted media tracker image. The visible name is MediaTrail. The Python package name is still yamtrack. The application path inside the image is /mediatrail.
Image: ghcr.io/aicon/mediatrail:0.25.7
latest points at this build. ghcr.io/aicon/mediatrail:dev stays the moving test tag from the dev branch. A push to main does not build an image. The repository and the package are private.
Version numbers continue from 0.25.3 in small steps. This release is 0.25.7. The About page and GET /api/v1/info/ report the VERSION value baked into the image. A dev image reports dev.
Upgrade
From 0.25.6, keep the data mount and the secret:
volumes:
- ./db:/mediatrail/dbKeep the same SECRET. A new secret drops existing sessions and can no longer decrypt the stored Nuvio password.
From 0.25.5 or earlier, change the mount in the same step as pulling this image. Those images read /yamtrack/db. This image reads /mediatrail/db. If the old mount stays, the library looks empty. Stop the container and copy the host db folder before recreating it.
One nginx line, connect() failed (111: Connection refused) on GET /health/ to 127.0.0.1:8001, is normal at startup. nginx is up before gunicorn listens. The next health check should be 200.
Hungarian interface
English remains the source text and the default. A signed-in user with Magyar selected on /settings/preferences now gets Hungarian on the pages that were still English in 0.25.6.
Movie and series pages translate the interface: tracker, scores, history, actions, detail labels, cast, episodes, repeats, streaming, and the track, list, and history windows. Titles, episode names, synopsis, cast names, and collection names stay as the provider sent them. Known provider words in the details box are translated, including Released, Ended, and Returning Series.
The search page translates the heading, the source label, the grid and list controls, the page line, and the empty result.
Activity history rows are stored as English sentences and translated when the page opens. A Hungarian interface shows lines such as "Nézés folyamatban", "Megnézve", "Értékelés: 8.5/10", and "Kezdés: …". The English interface keeps the English sentence. Old rows translate the same way.
Admin link
When the container has ADMIN_ENABLED set to true, the sidebar shows an Admin link between Settings and Logout. It opens /admin/. The link is absent when the flag is off. The flag still defaults to off, and /admin/ is still not mounted until it is on.
Run
docker-compose.yml is the SQLite example. It starts one service, mediatrail, from ghcr.io/aicon/mediatrail:latest, publishes port 8000, and mounts ./db at /mediatrail/db. Redis runs inside the image. AOF data is /mediatrail/db/redis.
docker-compose.postgres.yml uses the same image and a Postgres service named db. Database name, user, and password are mediatrail. Postgres data is ./postgres. Application and Redis data stay on ./db:/mediatrail/db.
Provider keys, including a Gemini key, are runtime settings. They are not Docker build arguments and they are not copied into the image.
MediaTrail 0.25.6
MediaTrail 0.25.6 is a self-hosted media tracker image. The visible name is MediaTrail. The Python package name is still yamtrack. The application path inside the image is now /mediatrail.
Image: ghcr.io/aicon/mediatrail:0.25.6
latest points at this build. ghcr.io/aicon/mediatrail:dev stays the moving test tag from the dev branch. A push to main does not build an image. The repository and the package are private.
Version numbers continue from 0.25.3 in small steps. This release is 0.25.6. The About page and GET /api/v1/info/ report the VERSION value baked into the image. A dev image reports dev.
Upgrade
Change the data mount in the same step as pulling this image:
volumes:
- ./db:/mediatrail/db0.25.5 mounted ./db at /yamtrack/db. This image reads and writes /mediatrail/db. If the old mount stays, the process uses an empty /mediatrail/db and the library looks empty. The host db folder is unchanged. Stop the container and copy that folder before recreating it.
Keep the same SECRET. A new secret drops existing sessions and can no longer decrypt the stored Nuvio password.
The entrypoint runs python manage.py migrate --noinput. This release adds the user language column and the Nuvio account table.
One nginx line, connect() failed (111: Connection refused) on GET /health/ to 127.0.0.1:8001, is normal at startup. nginx is up before gunicorn listens. The next health check should be 200. The same line repeating about every 45 seconds means gunicorn is down. Redis "Memory overcommit" is a warning.
Run
docker-compose.yml is the SQLite example. It starts one service, mediatrail, from ghcr.io/aicon/mediatrail:latest, publishes port 8000, and mounts ./db at /mediatrail/db. It does not start Redis. Set SECRET and TZ in the runtime environment.
docker-compose.postgres.yml uses the same image. Postgres is the db service (postgres:16-alpine, container mediatrail-db). Database name, user, and password are mediatrail. Postgres data is ./postgres. Application and Redis data stay on ./db:/mediatrail/db.
docker-compose.local.yml can still build this directory as mediatrail:local. Its volume is ./db:/mediatrail/db.
Provider keys, including a Gemini key, are runtime settings. They are not Docker build arguments and they are not copied into the image. .env files are excluded from the build context.
The README in this tag still says docker-compose.yml and docker-compose.postgres.yml are upstream Yamtrack examples. That sentence is out of date. Both files are the MediaTrail examples described above.
Process layout
The runtime is Python 3.12 on Alpine. WORKDIR is /mediatrail. Supervisord runs Redis, nginx, gunicorn, Celery, and Celery beat in one container. nginx listens on port 8000 and proxies to gunicorn on 127.0.0.1:8001. Static files are served from /mediatrail/staticfiles/. The process user is abc, so PUID and PGID can be mapped at start. The image healthcheck requests http://127.0.0.1:8000/health/.
The preview API dependencies (Django REST framework and drf-spectacular) are installed in the image after the locked sync. GET /api/v1/info/ returns version, debug, frontend URL, language, and timezone.
Redis
Redis runs inside the image. It binds 127.0.0.1:6379 with protected mode on. AOF is enabled and the data directory is /mediatrail/db/redis, on the same volume as the application database. The image sets REDIS_URL=redis://127.0.0.1:6379. Socket timeouts are 5 seconds.
Set REDIS_URL only when cache and Celery should use a Redis server outside this container. CELERY_REDIS_URL defaults to REDIS_URL.
Language
Preferences at /settings/preferences store en or hu. The default is English. A signed-in user gets that language on every page. An anonymous request stays English.
English is the source text. Hungarian is a catalog (src/locale/hu). The catalog covers settings, import, lists, statistics, calendar, and the custom entry page. The sidebar label for a custom entry is "Egyéni bejegyzés" in Hungarian.
Import history is stored in English (Imported 1481 Movies and 5871 Episodes., No media was imported., Imported 1 Episode.). Opening the page in Hungarian shows those existing rows in Hungarian. The English interface keeps the English sentence. Counts keep a singular Hungarian noun after the number (1481 film és 5871 epizód importálva.).
Manual
The manual is public and separate from this private repository:
- English: https://aicon.github.io/mediatrail-docs/
- Hungarian: https://aicon.github.io/mediatrail-docs/hu/
- Source: https://github.com/aicon/mediatrail-docs
The import page links to the import chapter in the active interface language. The About page "MediaTrail documentation" link opens the manual home the same way. A later interface language that has no book opens the English manual.
The About page still names Yamtrack and links to the original project. The source-offer page is unchanged.
Nuvio import
Nuvio is the first source on /settings/import. It uses the shared Import Mode dropdown.
- New adds movies and episodes that are missing locally, including items whose Nuvio event was imported before and then removed locally.
- Overwrite also updates the watch date of a movie that is already tracked, and the date of the latest episode row. It does not delete rows, it does not wipe the series, and it leaves score and notes alone.
A scheduled overwrite run replays the history, so it rewrites those dates on every run. A scheduled new run does not.
The form saves the Nuvio email, password, and profile. Email and profile are filled in on the next visit. A blank password keeps the saved password. The password is encrypted with Fernet and is never rendered back into the page. Changing the email or the profile clears the cursor and the remembered ids.
The import reads Nuvio only. It signs in with the password grant, does not store a refresh token, and uses the public Nuvio client key. Metadata lookups use the TMDB key already configured for MediaTrail.
Each run reads the full watch history, then the delta after the stored cursor. Series rows that have no season and episode are skipped and remembered, so they are not retried. Delete events are ignored. Episode rows are written without a per-row TMDB refetch.
A TMDB or Nuvio failure that can succeed later stops the run and leaves the cursor where it is. The next run continues. A row TMDB does not know is remembered and skipped on later runs.
Scheduled imports
Repeating imports use the clock time selected on the form. A 3-hour schedule that starts at 14:19 runs at 14:19, 17:19, 20:19, and so on. The same anchoring applies to 1, 6, and 12 hours. Daily and multi-day schedules use the selected hour and minute.
Other changes
- CSV export file name is
mediatrail_<timestamp>.csv. - Error pages link to https://github.com/aicon/MediaTrail/issues.
- Calendar
PRODIDis-//MediaTrail//EN. - Open Library requests identify as MediaTrail.
- The page description no longer calls the product a Yamtrack fork. The license, the About page, and the source offer still name Yamtrack.
MediaTrail 0.25.5
MediaTrail 0.25.5 is a self-hosted media tracker image. The visible name is MediaTrail. Inside the image the application path is still /yamtrack and the Python package name is still yamtrack, so existing volume paths and imports stay the same.
Image: ghcr.io/aicon/mediatrail:0.25.5
latest points at this build. The repository and the package are private.
Version numbers continue from 0.25.3 in small steps. This release is 0.25.5. The About page and GET /api/v1/info/ report the VERSION value baked into the image.
Run
docker-compose.local.yml starts one service, mediatrail, and publishes port 8000. It does not start a Redis container. Mount ./db at /yamtrack/db. Set SECRET and TZ in the runtime environment.
docker-compose.yml and docker-compose.postgres.yml are the upstream examples. They are not this image.
Provider keys, including a Gemini key, are runtime settings. They are not Docker build arguments and they are not copied into the image. .env files are excluded from the build context.
Process layout
The runtime is Python 3.12 on Alpine. Supervisord runs Redis, nginx, gunicorn, and Celery in one container. nginx listens on port 8000, with an IPv6 listen line in the generated config. The process user is abc, so PUID and PGID can be mapped at start. The image healthcheck requests http://127.0.0.1:8000/health/.
The preview API dependencies (Django REST framework and drf-spectacular) are installed in the image after the locked sync. GET /api/v1/info/ returns version, debug, frontend URL, language, and timezone.
Redis
Redis runs inside the image. It binds 127.0.0.1:6379 with protected mode on. AOF is enabled and the data directory is /yamtrack/db/redis, on the same volume as the application database. The image sets REDIS_URL=redis://127.0.0.1:6379.
Set REDIS_URL only when cache and Celery should use a Redis server outside this container. CELERY_REDIS_URL defaults to REDIS_URL.
Now Watching
The home page shows a live playback strip while a client is reporting playback. The strip refreshes every 10 seconds from /now-watching/.
The strip shows a blurred backdrop, the poster, a status badge, and the start time. The badge is NOW WATCHING or PAUSED. It is a status label only. MediaTrail does not send pause or resume commands to the player. Playback stays in the client (Nuvio, Jellyfin, Stremio, and the rest).
The poster and the title open the media page. A movie shows title and year. An episode shows the series title and year, a season/episode code, and the episode title when one exists. Episode names come from TMDB in the configured language, with an English request when the local name is only a placeholder such as "Episode 21". If no real title exists, the strip shows the season/episode code only.
Progress is floor(100 * position / duration) when the duration is known. The strip then shows the percent, the time left, a soft elapsed wash, and a bottom progress bar at the same percent.
The top-right control dismisses a stuck strip. In 0.25.5 that control is a centered icon inside the square button. Dismiss deletes the live row only. It does not change watch history or tracked status. A later progress report can show the strip again while playback is still going.
Stale rows are removed without touching history:
watchingwith no update for 3 minutes (LIVE_PLAYBACK_WATCHING_STALE_SECONDS)pausedwith no update for 10 minutes (LIVE_PLAYBACK_PAUSED_STALE_SECONDS)
Progress and start events refresh the timestamp and set the status back to watching.
Playback API
Clients report playback on the preview API:
PUT /api/v1/playback/writes a watching or paused live rowGET /api/v1/playback/reads the current live rowGET /api/v1/playback/now/returns 204 when nothing is liveDELETE /api/v1/playback/clears one title without completing itDELETE /api/v1/playback/now/clears every live row for the user
start and progress with a position above zero mark the row watching. pause keeps the strip and marks it paused. stop below the watched threshold clears the live row and does not write history. stop at or above the threshold clears the live row and writes one history row. A repeated stop does not write a second history row. Clearing a live row never changes episode or movie history.
This release
0.25.5 centers the Now Watching dismiss icon in its button and publishes that build as ghcr.io/aicon/mediatrail:0.25.5.