Self-hosted service
meeb/tubesync avatar
meeb/tubesync

TubeSync: a YouTube PVR that files downloads into your Plex or Jellyfin library

Syncs YouTube channels and playlists to a locally hosted media server

2,795 stars172 forksPythonAGPL-3.0

At a glance

What is it?
TubeSync wraps yt-dlp and ffmpeg in a scheduler and web UI, then points your media server at the result. It is a container-first tool for people who want channels and playlists mirrored locally on a timer, not a one-off downloader.
Who is it for?
Adopt TubeSync if you already run Docker or Podman and want channels and playlists mirrored into a media server without clicking download on each video. Skip it if you want a one-off grab, a mobile app, or a native Windows install, because the project ships as a container image and the README documents no other route.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap TubeSync fills between yt-dlp and a media server

yt-dlp downloads a URL. It does not remember that a channel has a new upload next Tuesday, and it does not tell Plex that a file appeared. TubeSync is the layer in between: a web interface wrapper on yt-dlp and ffmpeg with a task scheduler, as the README puts it, aimed at people who want a personal video recorder for YouTube rather than a command-line download.

The audience is narrow and specific. You need somewhere to run a container, a directory you are willing to fill with video and thumbnails, and ideally a media server. The README supports Jellyfin and Plex, and describes the media server step as optional, which is honest: without one you still get organized files on disk. If you only ever download one video, TubeSync is more machinery than the job needs.

Sources, a scheduler, and a downloads tree with two subdirectories

The unit of work is a source, which is a YouTube channel or a playlist. When you add one, TubeSync extracts the channel name or playlist ID from the URL and validates it. Each source carries its own settings, including how often it is indexed and what quality to download. After that, scheduled tasks do the rest; the tasks tab shows what the instance is currently doing.

The output layout is fixed and simple. Inside the directory you map to /downloads, TubeSync creates a video subdirectory and an audio subdirectory. Media with only an audio stream, such as music, lands in audio; anything with a video stream lands in video. That split is what makes the media server integration work without manual sorting.

The failure handling is the part worth noting. Rather than giving up on a failed download, TubeSync retries with back-off timers over an extended period. For a PVR that runs unattended, that is the difference between a gap in your library and a transient network error that resolves itself.

Installing TubeSync with Docker and adding your first source

The README states that TubeSync is designed to run in a container, via Docker or Podman, and that amd64 and arm64 are supported. The container image is ghcr.io/meeb/tubesync:latest. The published example starts by finding your user and group IDs, since the container runs as the user you specify.

bash
$ id
# Example output, in this example, user ID = 1000, group ID = 1000
# id uid=1000(username) gid=1000(username) groups=1000(username),129(docker)

Create the two host directories the container expects, one for config data and one for downloads.

bash
$ mkdir /some/directory/tubesync-config
$ mkdir /some/directory/tubesync-downloads

Then pull the image and run it, substituting your own IDs, timezone and paths. If TZ is unset it defaults to UTC. The stop-timeout of 1800 seconds gives the scheduler time to shut down cleanly.

bash
# Pull image
$ docker pull ghcr.io/meeb/tubesync:latest
# Start the container using your user ID and group ID
$ docker run \
  -d \
  --name tubesync \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Europe/London \
  -v /some/directory/tubesync-config:/config \
  -v /some/directory/tubesync-downloads:/downloads \
  -p 4848:4848 \
  --stop-timeout 1800 \
  ghcr.io/meeb/tubesync:latest

Open http://localhost:4848 and the dashboard should appear. If it does not, the README points at docker logs tubesync, and notes that file permission problems are a typical cause. From the sources tab, add a channel or playlist URL, validate it, choose the indexing interval and quality, and save. Everything after that runs on timers.

bash
$ docker logs tubesync

Compose users get the same result from a service definition. Note the stop_grace_period, which mirrors the stop-timeout flag above.

yml
services:
  tubesync:
    image: ghcr.io/meeb/tubesync:latest
    container_name: tubesync
    restart: unless-stopped
    stop_grace_period: 30m
    ports:
      - 4848:4848
    volumes:
      - /some/directory/tubesync-config:/config
      - /some/directory/tubesync-downloads:/downloads
    environment:
      - TZ=Europe/London
      - PUID=1000
      - PGID=1000

Optional basic HTTP authentication is available by setting HTTP_USER and HTTP_PASS. The README links to an environment variables reference in the project wiki for the details, and does not reproduce the full list in the main document.

Where TubeSync gets awkward: permissions, storage and database drift

The most common failure mode is ownership. TubeSync writes metadata and media as PUID and PGID, and the README warns explicitly about Samba-backed volumes: if /downloads comes from a CIFS or Samba mount, you must also pass matching uid and gid mount parameters in the driver options. Mismatched IDs break file actions such as writing metadata. This is not a bug so much as a consequence of running as a non-root user, but it is the first thing to check when files appear with the wrong owner.

Storage is the second constraint. The README says you need as much space as you want to allocate to downloaded media and thumbnails, and adds that high-resolution downloads can be very large. There is no quota mechanism described. A channel with a deep back catalogue and a preference for high quality will consume the volume you gave it.

Database migrations are automatic on update, with one documented exception: MariaDB was not automatically upgraded for UUID column types. The project provides a dry run so you can see the statements before applying them.

bash
$ docker exec -it tubesync python3 /app/manage.py fix-mariadb --dry-run --uuid-columns

Removing --dry-run executes the statements against the configured database connection. If you use the default container, the database is SQLite inside /config, and the README says copying that directory with correct permissions is enough to move, back up or migrate the install. That makes backup cheap, but it also means the config directory is state you should not delete casually.

TubeSync against Pinchflat and Tube Archivist

The comparison people search for is TubeSync versus Pinchflat and TubeSync versus Tube Archivist, and the README itself frames the difference: there are several other web interfaces to YouTube and yt-dlp, and TubeSync's stated distinction is a full PVR experience of updating media servers plus better selection of media formats.

That framing is worth taking literally. TubeSync's design center is the handoff to Jellyfin or Plex, with a video/audio directory split and media server refresh as the end of the pipeline. If your goal is an archive you browse inside its own web UI, a tool built around that premise will fit better, because TubeSync's own interface is administration rather than a viewing front end. If your goal is that a show appears in the library you already use, the media server integration is the feature you are paying the container overhead for.

On format selection, the README claims an advantage but does not enumerate the options in the main document, so evaluate that against your own quality requirements rather than the claim.

Updating, licensing and what a version bump costs you

Updating is a pull. The README shows docker pull ghcr.io/meeb/tubesync:v[number], and states that back-end updates such as database migrations should be automatic. The release history shows a steady cadence, with v0.18.3 in August 2026 and v0.18.4 in September 2026, plus a release candidate two weeks before the stable tag. That pattern suggests testing happens on rc tags before stable, which is useful if you want to be early.

The repository's last push was on 2026-09-24, and it is not archived. The practical upgrade cost is low for the container itself and higher for the database, since the MariaDB UUID caveat is the one migration the project calls out as not automatic. If you run the default SQLite setup, the README does not document an equivalent manual step.

TubeSync is licensed AGPL-3.0. For self-hosting that is unremarkable. If you plan to modify TubeSync and expose it to users over a network, the AGPL's network clause is the part to read with your own counsel; this article does not give legal advice, and the LICENSE file in the repository is the authoritative text.

Editorial conclusion

Adopt TubeSync if you already run Docker or Podman and want channels and playlists mirrored into a media server without clicking download on each video. Skip it if you want a one-off grab, a mobile app, or a native Windows install, because the project ships as a container image and the README documents no other route. Before committing, confirm your PUID and PGID, check that the /downloads mount has room for the resolutions you picked, and if your database predates the UUID column change, run the fix-mariadb dry run first.

Frequently asked questions

How do I sync my YouTube channels with TubeSync?

Run the container, open the dashboard on port 4848, and add a channel URL from the sources tab. TubeSync validates the URL, extracts the channel name, and then indexes and downloads on the schedule you set for that source.

What is the difference between TubeSync and MeTube?

The README describes TubeSync as a PVR with a task scheduler that updates a media server, whereas its stated distinction from other yt-dlp web interfaces is the full PVR experience and media format selection. MeTube is not mentioned anywhere in the repository, so this article cannot compare the two on specifics.

Does TubeSync have a Windows or Android app?

The README documents only a container image, ghcr.io/meeb/tubesync:latest, run through Docker or Podman on amd64 or arm64. It describes no native Windows build and no mobile app; you would reach the web interface at port 4848 from a browser on your network.

Why is TubeSync not downloading anything?

The README names file permission issues as a typical cause and points at docker logs tubesync for errors. If your /downloads directory is a Samba volume, the uid and gid mount parameters must match the PUID and PGID environment variables, or file actions such as writing metadata will fail.

How do I update TubeSync and does it migrate the database?

Pull the newer image tag, and back-end updates such as database migrations should be automatic. The documented exception is MariaDB, which was not automatically upgraded for UUID column types; the project provides a fix-mariadb management command with a --dry-run flag so you can inspect the statements first.

Official sources

  1. Issues
  2. License: AGPL-3.0
  3. meeb/tubesync on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/meeb-tubesync.svg)](https://hysenlabs.com/projects/meeb-tubesync)