Ganymede: a Twitch archiving platform that renders chat into standalone files
Twitch VOD and Live Stream archiving platform. Includes a rendered and real-time chat for each archive.
At a glance
- What is it?
- Ganymede is a Go service, deployed as two Docker containers, that archives Twitch VODs and live streams, replays chat in real time, and writes each archive to disk in a layout that stays readable without the software.
- Who is it for?
- Ganymede suits people who want to keep Twitch broadcasts and their chat for the long term and do not mind running two containers, Postgres and a fair amount of disk. It is the wrong choice for a quick download, since the archiving stack is built around a persistent queue, a database and background workers rather than a one-off script.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The archive is designed to outlive the software
Ganymede archives past broadcasts and live streams from Twitch, and the central design decision is that the output does not depend on the program. Files are saved in a format that can be used without Ganymede, and every archive includes a rendered chat, so the video and the conversation can be watched outside the tool. The feature list names the file structure as a simple layout for long-term archival that will outlast Ganymede, with the details in a wiki page on file structure. The project is also the successor to an earlier archiving platform called Ceres, and it is licensed under GPL-3.0. Around the archiving core sit the ordinary features of such a service: full VOD, channel and user management, watched channels with advanced filtering, playlists, playback with progress saving, webhook notifications, and a recoverable queue system.
A Twitch application, Docker on Linux and fifty gigabytes
The requirements are short and specific. You need a Linux environment with Docker, optionally a network mounted storage volume, a Twitch application created through the Twitch developer console, and 50 GB or more of free storage with a separate wiki page for the storage requirements. The Twitch application is not optional, because the service authenticates against the Twitch API, and the compose file asks for a client id and a client secret to be filled in. The storage figure is the number most likely to surprise people, since a back catalogue of channels is measured in tens of gigabytes before chat rendering is added, and the video directory is where all of it lands.
Two containers, an admin account and a password change
The deployment is a server container and a Postgres database container, and the documentation notes that you can point the server at an existing Postgres container instead of starting a new one. The install is a matter of downloading the `docker-compose.yml` file, editing the environment variables it contains, starting the stack and changing the default credentials.
docker compose up -dYou then visit the address and port you set for the frontend and log in with the username `admin` and the password `ganymede`. The documentation is explicit about the next step: change the admin password or create a new user, grant that user admin permissions, and delete the admin user. That last instruction is the difference between a default install and a locked down one, and skipping it leaves a known password on a service that can download and serve video and accept credentials for Twitch.
Four tag styles decide which build you run
Images are published to ghcr.io and there are four kinds of tag. `latest` points to the latest release. A semver tag such as 4.10.0 gives the latest release in semver format. `dev` is a build of the main branch, intended for testing new features before a release. A pull request tag such as `pr-123` is a build of that pull request, and it is deleted when the pull request is closed. That last behaviour is worth remembering, because a container image referenced by a pull request tag will stop existing at an unpredictable time. The published releases are frequent, with v4.21.0 on 2026-09-22, v4.20.0 on 2026-08-25 and v4.19.1 on 2026-08-12, and the last push to the repository was on 2026-10-15.
Rootless mode trips over network storage that cannot chown
The API container can run as a non-root user, which is enabled by setting the `PUID` and `PGID` environment variables to the values of your own user, following the convention used by LinuxServer containers. On startup the container chowns the config, temp and logs directories, but it does not recursively chown the videos directory, so you have to make sure the mounted video path is readable by the set user. That omission becomes a real problem on network shares, and the documentation covers it: if the storage cannot support chown, such as an NFS or SMB mount with NFSv4 ACLs on TrueNAS for example, set `SKIP_CHOWN=true` and make sure the directories are already writable by the set user. Configuration is a JSON file generated on first start, by default at `/data/config/config.json`, and most settings are also editable in the web interface under Admin and Settings.
Concurrency per task type is the knob that matters
The compose file exposes a separate worker limit for each kind of background job, which is how you keep a large archive from saturating the disk or the CPU.
- MAX_CHAT_DOWNLOAD_EXECUTIONS=3
- MAX_CHAT_RENDER_EXECUTIONS=2
- MAX_VIDEO_DOWNLOAD_EXECUTIONS=2
- MAX_VIDEO_CONVERT_EXECUTIONS=3
- MAX_VIDEO_SPRITE_THUMBNAIL_EXECUTIONS=2There is also a pair of settings for live archive stall detection, where the stall check can be disabled and the timeout is set in seconds with a documented minimum of 30, defaulting to 180. Behind those environment variables sits a real architecture: the Go module depends on the River queue library with its SQL driver and a web interface for it, on the ent entity framework for the schema, on Echo for the HTTP layer, and on swaggo for the generated API documentation that lives in the docs folder.
The archiving tools are pinned versions inside the image
The container does not install the tools it needs at runtime. The Dockerfile pins versions at build time, with TwitchDownloader at 1.56.5, yt-dlp at 2026.07.04 and FFmpeg at 9.0, and it builds yt-dlp from source in a separate stage. It even selects between the Linux x64 and arm64 TwitchDownloader archives depending on the architecture. One detail shows the seam of this arrangement: the repository contains a patch file for yt-dlp adapted for Twitch, and the corresponding apply step in the Dockerfile is commented out, so the patch is present in the tree without being applied in the current build. Two further areas are worth a mention. Authentication can be extended with OAuth or single sign-on through the documented provider settings, and translations live as JSON files in the frontend messages directory, with a script that reports coverage and a flag to fill in missing keys.
Editorial conclusion
Ganymede suits people who want to keep Twitch broadcasts and their chat for the long term and do not mind running two containers, Postgres and a fair amount of disk. It is the wrong choice for a quick download, since the archiving stack is built around a persistent queue, a database and background workers rather than a one-off script. Before you start, create the Twitch application and set the client id and secret, decide where the video directory lives, and check the 50 GB storage guidance, because a large back catalogue will need more than the minimum.
Frequently asked questions
What does Ganymede do with Twitch streams?
It archives past broadcasts and live streams, replays the chat alongside them, and renders a chat track into each archive. The files are written in a layout that can be viewed without Ganymede itself.
What do I need before installing Ganymede?
A Linux environment with Docker, a Twitch application created in the Twitch developer console, and 50 GB or more of free storage. Network mounted storage is optional.
How do I run Ganymede as a non-root user?
Set the PUID and PGID environment variables to your own user and ids. On startup the container chowns the config, temp and logs directories but not the videos directory, and if your storage cannot chown, such as NFS or SMB, set SKIP_CHOWN=true and ensure the directories are writable already.
Where is the Ganymede API documentation?
In the docs folder of the repository, generated with swaggo from the server entry point, alongside a wiki with in-depth documentation on features.
Official sources
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.
[](https://hysenlabs.com/projects/zibbp-ganymede)Was this useful?