{"id":27234644,"url":"https://github.com/rycochet/media-server","last_synced_at":"2026-04-29T17:04:35.871Z","repository":{"id":282492920,"uuid":"938228624","full_name":"Rycochet/media-server","owner":"Rycochet","description":"Overkill media server setup","archived":false,"fork":false,"pushed_at":"2026-04-11T15:38:41.000Z","size":25867,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-11T17:17:04.076Z","etag":null,"topics":["docker-compose","media","server"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rycochet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-24T16:13:28.000Z","updated_at":"2026-04-11T15:38:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"49d4aa90-360e-4da0-8341-5d49363db50c","html_url":"https://github.com/Rycochet/media-server","commit_stats":null,"previous_names":["rycochet/server","rycochet/media-server"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Rycochet/media-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rycochet%2Fmedia-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rycochet%2Fmedia-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rycochet%2Fmedia-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rycochet%2Fmedia-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rycochet","download_url":"https://codeload.github.com/Rycochet/media-server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rycochet%2Fmedia-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31993695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker-compose","media","server"],"created_at":"2025-04-10T15:59:46.856Z","updated_at":"2026-04-29T17:04:35.863Z","avatar_url":"https://github.com/Rycochet.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Media Server with Docker Compose\n\n\u003e [!IMPORTANT]\n\u003e This uses Cloudflare for incoming connections, NordVPN for outgoing, and Google Auth for logging in. If you cannot figure those out with help from google then this might not be the setup for you!\n\n\u003e [!NOTE]\n\u003e This is the barebones setup for a media server, it does not include any config (although over time I may add more document and templates explaining what to do).\n\n\u003cimg width=\"1304\" height=\"715\" alt=\"image\" src=\"https://github.com/user-attachments/assets/4bf99c07-ac29-4233-863e-af6cd92f10aa\" /\u003e\n\n## Components\n\n\u003e This is a partial list, the individual folders have every service, and I'll maybe add information for each over time.\n\n### Media Server\n\n* **AudioBookShelf**: Audiobook media server.\n* **Kapowarr**: Comic Books.\n* **Manyfold**: 3d model server.\n* **Overseerr**: Requests for Sonarr / Radarr.\n* **Plex Media Server**: Main media server.\n\n### Content Management\n\n* **Bazarr**: Subtitle Management (for Movies and TV Shows).\n* **Kometa**: Add overlays to posters for tv and movies in Plex.\n* **Imagemaid**: Delete unused posters in Plex.\n* **Lidarr**: Music Management.\n* **Plex-Find-Mismatch**: Find incorrect matches in Plex.\n* **Prowlarr**: Usenet and Torrent Search.\n* **qBittorrent**: Torrent downloads.\n* **Radarr**: Movie Management.\n* **SABnzbd**: Usenet downloads.\n* **Sonarr**: TV Show Management.\n* **Tdarr**: Transcode media for cnosistency and size.\n* **Titlecardmaker**: Add consistent posters to episodes in Plex.\n\n### System / Networking\n\n* **Cloudflared**: Cloudflare Tunnel (incoming web requests).\n* **DeUnhealth**: Restart unhealthy services.\n* **Error-Pages**: Better looking error pages.\n* **NordLynx** + **Socks5-Proxy**: VPN (outgoing connections).\n* **OpenSpeedTest**: Speed test app to server.\n* **Scrutiny**: S.M.A.R.T. information.\n* **SyncThing**: Synchronise libraries between multiple computers.\n* **TinyAuth**: Google OAuth login security.\n* **Traefik**: Webapp Routing.\n* **Watchtower**: Automatic updating of services.\n\n### Information\n\n* **Glances**: (Hardware) Server Status.\n* **Homer**: Dashboard\n* **Tautulli**: Plex Server Status.\n\n## Concept\n\nEvery service uses a similar folder layout, this includes having a `config` folder inside the service folder for easier backup and configuration.\n\nWhen one service depends on another it should only be started first (with a couple of exceptions that require them to be healthy first).\n\n## Installation\n\n\u003e [!IMPORTANT]\n\u003e The `install.sh` script is not usable yet, these other steps are always going to be manual!\n\nIt is advised to use VSCode or similar that does syntax highlighting (ie, colors) for the files you edit!\n\nDuplicate the `.env.example` file as `.env`, all configuration needs to go in here.\n\nThe easiest way to disable services is to edit the root `compose.yaml` file and comment out the services you don't want by placing a `#` at the beginning of the line.\n\n### Google\n\n1. Add your email address as the `EMAIL` and `WHITELIST` in `.env`\n1. Follow these instructions: \u003chttps://developers.google.com/identity/protocols/oauth2\u003e\n1. Add the `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` in `.env`\n1. Place a long random hexadecimal value in `OAUTH_SECRET` in .env`\n    * The best way is to use the output of `openssl rand -hex 16`\n\n### Cloudflare\n\n#### Domain name\n\n1. Make an account if you haven't already.\n1. Buy a domain, or if you already have one you can transfer the domain servers accross.\n    * Set this as the `DOMAIN` in `.env`\n    * Replace the `$DOMAIN` in `PLEX_URL` with this.\n\n#### Tunnel (incoming security)\n\n1. Sign up for Zero Trust - you can choose the personal 0-cost.\n1. Go to Networks -\u003e Tunnels\n    1. Create a Tunnel, name it for your domain\n    1. Copy the \"Run the following command\" suggestion, paste it as `CLOUDFLARED_TOKEN` in `.env` then remove the `cloudflared.exe service install ` prefix (including space).\n    1. Create 2 public hostnames, one to your domain, and one to `*` at your domain\n        * Both have a service of `https://traefik`\n        * Both have Advanced -\u003e TLS -\u003e Origin Server Name as your domain\n        * Both have Advanced -\u003e TLS -\u003e HTTP2 connection turned on\n\n#### Make subdomains accessible\n\n1. Go back to Account Home, then click on your domain name.\n1. Under the Domain (Zone) settings go to SSL/TLS -\u003e Overview, and enable Full encryption.\n1. Under DNS -\u003e Records, create a CNAME entry for `*` pointing at your domain.\n1. Under DNS -\u003e Settings, enable DNSSEC.\n\n#### Allow ssl certificates to be created\n\n1. Click on your Profile in the top right, go to your profile, then click on API Tokens on the left.\n1. Create a Token using the Edit zone DNS template\n1. Allow it access to your domain under Zone Resources\n1. Copy the token to `CLOUDFLARE_API` in `.env`\n\n### NordVPN\n\n1. Make an account, click on NordVPN on the left, scroll down to API Key, create one and copy to `VPN_PRIVATE_KEY` in `.env`\n\n### Media Paths\n\n1. Make sure you set `PATH_DOWNLOADS` to a good download folder, this will be used by multiple services as a consistent location.\n1. Place all of your media paths in the `PATH_XYZ` variables in `.env` - add more as needed.\n\n### Plex\n\n1. Use these instructions to get `PLEX_TOKEN` in `.env` - \u003chttps://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/\u003e\n1. Ensure you have all the correct paths for Plex from the Media Paths section above. Internally we're going to map them all under the `/data/` folder.\n1. In your current Plex server go to Settings -\u003e Library, and disable (and save) the \"Empty trash automatically after every scan\" option!\n1. Stop Plex Media Server!\n1. Copy (move is risky, but it's your library) the Plex Config folder starting at `Library` into `plex/config/` - so there is a folder in there called `Library`.\n\n## Bootstrap\n\n\u003e [!IMPORTANT]\n\u003e The Plex library must have finished copying before you do this, and you must not run the old one again (unless you decide not to go ahead with this).\n\n1. Run `docker compose pull` - disable any services that you don't have permission for.\n1. Just before running go to \u003chttps://account.plex.tv/claim\u003e and copy the token to `PLEX_CLAIM` in `.env`\n1. Run `docker compose up -d` and wait for everything to come up.\n1. Go to `https://dozzle.\u003cdomain\u003e` and wait for all the red dots to turn green.\n1. Optional: Run `docker compose down` followed by `docker compose up -d dozzle plex` - this reduces load and lets you setup things one at a time.\n1. Go to Plex and tell it to rescan everything - every entry should get re-found as Plex uses file hashes for identification.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frycochet%2Fmedia-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frycochet%2Fmedia-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frycochet%2Fmedia-server/lists"}