{"id":15695546,"url":"https://github.com/rosskevin/mediabox","last_synced_at":"2025-10-06T22:00:15.283Z","repository":{"id":72670931,"uuid":"485152081","full_name":"rosskevin/mediabox","owner":"rosskevin","description":"🐳 docker-compose based MEDIABOX 📺 ","archived":false,"fork":false,"pushed_at":"2025-09-27T16:35:54.000Z","size":440,"stargazers_count":2,"open_issues_count":0,"forks_count":11,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-28T06:56:18.639Z","etag":null,"topics":["docker-compose","plex","radarr","sabnzbd","sonarr"],"latest_commit_sha":null,"homepage":"","language":"CSS","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rosskevin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2022-04-24T22:11:32.000Z","updated_at":"2025-09-27T16:35:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"cb3e6613-289d-44f8-bc29-76abcb962735","html_url":"https://github.com/rosskevin/mediabox","commit_stats":{"total_commits":147,"total_committers":3,"mean_commits":49.0,"dds":0.5374149659863945,"last_synced_commit":"7a94d122b7066ffe8398477f392aad544ffe2ba5"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/rosskevin/mediabox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosskevin%2Fmediabox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosskevin%2Fmediabox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosskevin%2Fmediabox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosskevin%2Fmediabox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rosskevin","download_url":"https://codeload.github.com/rosskevin/mediabox/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rosskevin%2Fmediabox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278686632,"owners_count":26028326,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"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","plex","radarr","sabnzbd","sonarr"],"created_at":"2024-10-03T19:01:48.108Z","updated_at":"2025-10-06T22:00:15.271Z","avatar_url":"https://github.com/rosskevin.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# :tv: Mediabox\n\n![](https://github.com/rosskevin/mediabox/workflows/Multimedia%20Stack%20Deployment/badge.svg)\n\n![](assets/mb.jpeg)\n\n## TL;DR\nA home media server using `docker-compose` that enables SSL wildcard certificates via Cloudflare and LetsEncrypt.  The approach allows layering of complexity and features including Single sign on (SSO) via GCP.\n\n## What's in the stack?\n\nNOTE: These are listed in the order I recommend they are layered and tested during setup.\n\n### Baseline\n\u003csub\u003e`traefik-cloudflare.yml` and optional `traefik-oauth.yml`\u003c/sub\u003e\n* [Traefik](https://containo.us/traefik/) - Cloudflare DDNS, Service ingress, routing, etc, handles SSL certificates via DNS-01 challenge and LetsEncrypt\n\n### Misc\n\u003csub\u003e`misc.yml` and optional `misc-oauth.yml`\u003c/sub\u003e\n* [Watchtower](https://github.com/containrrr/watchtower) - A process for automating Docker container base image updates\n* [Duplicati](https://www.duplicati.com/) - Backup software to store encrypted backups\n* [Portainer](https://www.portainer.io/)\n\n### Multimedia\n\u003csub\u003e`multimedia.yml`, optional `multimedia-oauth.yml`\u003c/sub\u003e\n* [Prowlarr](https://wiki.servarr.com/prowlarr) - [quick start](https://wiki.servarr.com/prowlarr/quick-start-guide) - Indexer/manager manager/proxy that supports management of both Torrent Trackers and Usenet Indexers. It integrates seamlessly with Lidarr, Radarr, Readarr, and Sonarr offering complete management of your indexers with no per app Indexer setup required.  HINT: use local network names in settings e.g. http://prowlarr:9696, http://radarr:7878, http://sonarr:8989, http://sabnzbd:8080. \n* [SABnzbd](https://sabnzbd.org/) - Usenet downloader.  Use top level `DATA` env variable to avoid needing to specify \"Remote Path\" it the *arr applications.  This makes it easier to hardlink.  See #Layered setup stage 2\n* [Sonarr](https://sonarr.tv/) - Series manager - should pull indexer from prowlarr\n* [Radarr](https://radarr.video/) - Movie manager - should pull indexer from prowlarr\n* [Plex](https://www.plex.tv/) - Medial library - NOTE: in initial config, connect to `http://\u003cmy-local-ip\u003e:32400/web` first to complete the setup wizard.  Plex differs from every other container and uses `host` networking, therefore enable `Remote` access, port forward `32400` to `\u003cmy-local-ip\u003e` and then you may access remotely via https://app.plex.tv.  Using `host` networking makes configuration easier, and ensures traffic runs unrestricted and local devices can easily discover the server.  The not-so-big-deal-downside is that plex.example.com no longer is your go-to url.\n* [Organizr](https://github.com/causefx/Organizr) - Organize a single page with tabs to manage all services\n\n### Optional additions\nNOTE: updates likely needed here.\n* [OpenVPN](https://github.com/dperson/openvpn-client) - vpn client\n* [Deluge](https://deluge-torrent.org/) - torrent downloads\n\n## Prerequisites\n* [Docker](https://www.docker.com/)\n* [Docker-Compose](https://docs.docker.com/compose/)\n* [Get your Cloudflare `Global API Key`](https://dash.cloudflare.com/profile/api-tokens) for use as `CF_API_KEY` in the `.env`\n\n\n## Initial setup\n1. Fork this repo (so you can keep changes if you need to)\n1. Clone **_your_** forked repo\n1. `cd mediabox`\n1. `cp .env.template .env`\n1. Replace variables on `.env` with whatever makes sense to you (follow the comments above each property).  Don't worry, start with the basics and get to the rest later\n\nNOTE: set up duplicati.example.com later to make sure your repo and specifically your `.env` is backed up daily.\n\n## Layered setup\n\nSetting up a home server can be complex.  For all examples, we will assume you are using the domain `example.com`.  You usually need to setup your domain on cloudflare, forward ports on your router and set up dynamic dns.  Before attempting to configure additional applications, this repo is setup to allow you to layer in complexity by minimizing containers started using the `COMPOSE_FILE` variable.  The simple shell script wraps the `docker-compose` command to make it simple to execute `up`, `down`, `restart`, `logs`, `shell` and most any other typical `docker-compose` command (via `cmd`).  See [Usage](#usage) or simply execute `./mb` to see it.\n\n## Layered setup stage 1\n\nSuccessful completion of this stage means you can access both https://traefik.example.com and https://whoami.example.com, with optional IP whitelist restriction and/or optional Single Sign On.\n\n1. **Set up cloudflare DNS** for your example.com domain\n1. **Add wildcard CNAME** - Add a `* CNAME` to `@` \n1. **Set up dynamic DNS (DDNS)** to cloudflare to update the `A` record for your example.com (see `cf-ddns` container in `traefik-cloudflare.yml`)\n1. **Increase cloudflare security** - Configure increased security on your cloudflare zone, see [Cloudflare Settings for Traefik Docker: DDNS, CNAMEs, \u0026 Tweaks](https://www.smarthomebeginner.com/cloudflare-settings-for-traefik-docker/)\n1. **Verify HTTPS connectivity** - In `.env` set `COMPOSE_FILE=traefik-cloudflare.yml`, `DOMAIN,SSL_ACME_EMAIL,CF_API_EMAIL,CF_API_KEY` and `./mb up` - verify connectivity to both https://traefik.example.com and https://whoami.example.com.  Check logs with `./mb logs traefik` and make sure there are no errors.  `./mb down` when done.\n1. (optional) **Restrict IPs allowed** - Restrict your `EXPOSED_IP_ALLOWLIST` in `.env` to a minimal set of IP addresses, or if you want it public, leave it open by default `0.0.0.0/0`\n1. (optional) **Setup Single Sign On** - Set `COMPOSE_FILE=traefik-cloudflare.yml:traefik-oauth.yml` in `.env` and `./mb up` - set up GCP based SSO via OAUTH. [Some background is available here](https://www.smarthomebeginner.com/google-oauth-with-traefik-2-docker/) on the external steps, but as-is you only need to make sure your associated ENV variables are populated.  Now verify the auth challenge to both https://traefik.example.com and https://whoami.example.com.  `./mb down` when done.\n\n**All good?  If not do not continue.**\n\n## Layered setup stage 2\n\nPlan your disk layout and set up your NFS (or other) disk mounts (beyond the scope of this readme).  This setup follows best practices mentioned on [this article](https://wiki.servarr.com/Docker_Guide#The_Best_Docker_Setup) and [this reddit post](https://www.reddit.com/r/usenet/wiki/docker#wiki_the_best_docker_setup) to be able to use hardlinks and/or perform atomic `move` operations instead of `copy+delete` (which takes longer and requires more space).\n\nTL;DR from [Trash guides \"how to set up for docker\"](https://trash-guides.info/How-to-setup-for/Docker/):\n\n\u003e The paths you use on the inside matter. Because of how Docker’s volumes work, passing in two or three volumes such as the commonly suggested /tv, /movies and /downloads makes them look like two or three file systems, even if they aren’t. This means hard links won’t work and instead of an instant move, a slower and more I/O intensive copy + delete is used.\n\n```sh\n# My disks layout:\n#\n# ├── nas\n# │   └── mediabox (mounted as /data)\n# |       ├── backups\n# |       ├── torrents\n# │       |   ├── movies\n# │       |   ├── pictures\n# │       |   └── tv\n# |       └── usenet\n# │       |   ├── movies\n# │       |   ├── pictures\n# │       |   └── tv\n# |       └── media\n# │           ├── movies\n# │           ├── pictures\n# │           └── tv\n# └── ssd\n#     ├── containers\n#     └── repo\n#\n# CONTAINERS : Application docker container storage - SSD recommended.  Intend to backup this to the BACKUPS.\n# DATA       : This directory will be the top level mount point mounted in containers.  Configure relative paths inside the applications.\n# BACKUPS    : Target location for backups (can also use online services instead inside duplicati)\n#\nCONTAINERS=/containers\nDATA=/mnt/nfs/mediabox\nBACKUPS=/mnt/nfs/mediabox/backups\n```\n\n## Layered setup stage 3\nNow it is time to determine what services you want to run.  \n\n1. **Add primary applications** - Edit your `.env` and chain `mediabox.yml` on to your `COMPOSE_FILE` variable.  The same as above, `./mb up` then check the logs of the various containers like `./mb logs plex`.  You should now be able to access each by name e.g. https://plex.example.com. \n1. (optional) **Protect applications with SSO** - Edit your `.env` and chain `mediabox-oauth.yml` on to your `COMPOSE_FILE` variable.  Test again, but this time use an incognito browser (or other browser that has not utilized SSO in steps above) and be sure you receive a challenge for https://plex.example.com\n1. (optional) **Torrents, books, etc** - view the remainder of the compose files and see what services you want.  Using the same methodology, chain the compose file, and test your changes. (I am not using torrents or books, so these may need adjustments, feel free to PR changes)\n\n## Usage\n```sh\nusage: mb [help|-h|--help] \u003csubcommand\u003e\n\noptional arguments:\n  help | -h | --help\n    print this message and exit\n\nsubcommands:\n  start\n     starts the configured files\n  stop\n     stops\n  restart\n     restarts, a combination of stop and start\n  update\n     pulls updated images\n  shell\n     open a shell to the targeted container\n  logs\n     shows logs\n  docompose \u003ccommand\u003e\n     executes any arbitrary docker compose command. Use \"docompose help\" to list them\n\n\nThe logs subcommand can be appended by flags and specify the container(s). example: \n\n  mb logs -f --tail 500 plex\n    shows logs only for plex service\n\n\nBe sure to run commands either with sudo, or as a user who is part of the \"docker\" group\n```\n\n## Updating\nWatchtower automatically updates all apps (if docker image update is available) at 4 AM every day.\n\n## VPN (may need updating)\nWith OpenVPN you can use any VPN provider following these steps:\n\n1. Download your VPN OpenVPN config files (e.g: [NordVPN TCP/UDP config files](https://nordvpn.com/ovpn/))\n2. Download your VPN CA file (e.g: [NordVPN CA \u0026 TLS key files](https://downloads.nordcdn.com/configs/archives/certificates/servers.zip))\n3. Run the following (using NordVPN Brazil#65 as example)\n```bash\n# Copy required files\ncp ~/Downloads/br65.nordvpn.com.udp.ovpn ${OPENVPN}/vpn.conf\ncp ~/Downloads/br65_nordvpn_com_ca.crt ${OPENVPN}/vpn-ca.crt\n\n# Write credentials\ncat \u003c\u003cEOT \u003e\u003e ${OPENVPN}/vpn.auth\nyou@mail.com\nYourVPNP4ssw0rD\nEOT\n```\n\n## Credit\nMuch of this repo was developed by the original other and contributors at https://github.com/cristianmiranda/mediabox.  I did not choose to PR my changes because the repo was not very active.  While a PR from this repo could be created and applied upstream, I did not want to take the time to justify choices I made including some structural changes.  If someone wants to do that work to push this upstream, I welcome getting my changes contributed to the original body of work.\n\nAnyway, thanks to @christianmiranda and other contributors from the original repo.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosskevin%2Fmediabox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frosskevin%2Fmediabox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frosskevin%2Fmediabox/lists"}