Media server template using Docker Compose. Supports VPNs, media automation, streaming, and torrent management.
Barrel also provides utilies to generate homepage services for your apps, as well as Headscale for self-hosted mesh VPN with access controls.
| Service | Description | External Port (.shared.env) |
|---|---|---|
| qBittorrent | Torrent client | 8085 |
| Aurral | Music discovery and requests for Lidarr | 8086 |
| Jellyfin | Media server | 8087 |
| Prowlarr | Indexer manager | 8088 |
| Radarr | Movie automation | 8089 |
| Sonarr | TV automation | 8090 |
| Seerr | Media request manager | 8091 |
| Cleanuparr | Download client cleaner | 8092 |
| Bazarr | Subtitle automation | 8095 |
| Lidarr | Music automation | 8093 |
| Navidrome | Subsonic music streaming server | 8094 |
| FlareSolverr | Cloudflare challenge solver | 8191 |
| Gluetun | Wireguard/OpenVPN client | n/a |
| Headscale | Self-hosted Tailscale control server | 8096 |
| Headplane | Headscale UI | 8097 |
| Tailscale | Mesh VPN (subnet router) | n/a |
-
Copy the example env files and fill in your secrets:
cp config/templates/.local.* config/ -
Review
config/.shared.envandconfig/.compose.envfor any configuration updates you might want to make. -
Create the media directories in your downloads path, matching
DOWNLOADS_PATHin.compose.env:mkdir -p /path/to/volume/downloads/{movies,tv,music,torrents} -
Set up Headscale:
mkdir -p headscale/{config,lib,run} cp config/templates/headscale.config.yaml headscale/config/config.yaml cp config/templates/headscale.acl.json headscale/config/acl.jsonUpdate
headscale/config/config.yamlwith your domain andheadscale/config/acl.jsonwith your users. -
Build the Homepage services file using
pnpm i && pnpm build. Move the_homepage.compose.yamlservice tocompose.yamlif you wish to run it along with the media suite. -
Start the media suite:
./start.sh
After starting the suite for the first time, create your users and auth keys:
# create admin user
docker exec headscale headscale users create admin
# get the admin user id
docker exec headscale headscale users list
# generate a pre-auth key for the subnet router and set it as TS_AUTHKEY in config/.local.compose.env
docker exec headscale headscale preauthkeys create --user 1 --reusable -e 2160h
# create a user for each friend
docker exec headscale headscale users create friend1
# generate a one-time auth key for them to connect
docker exec headscale headscale preauthkeys create --user <friend user id> -e 48hYour friends can connect their Tailscale client with:
tailscale up --login-server=https://headscale.yourdomain.com --authkey=<key>You can optionally add an admin UI for headscale.
-
Ensure barrel is running.
-
Run
scripts/setup-headplane.shto create a config file. -
Add the service in
_headplane.compose.yamland restart barrel.
Headscale must be directly reachable by Tailscale clients. It cannot run behind a Cloudflare Tunnel due to incompatible WebSocket upgrade headers.
-
Generate a TLS certificate using Cloudflare DNS validation:
CF_API_TOKEN=secret HEADSCALE_DOMAIN=headscale.yourdomain.com ./scripts/setup-cert.sh
Renewal is automatic via certbot's systemd timer. Headscale is restarted on renewal automatically.
-
Enable TCP port forwarding for
HEADSCALE_PORTon your router. -
Add an unproxied DNS address record for
headscale.yourdomain.compointing to your public IP. If you don't have a static IP, use these crontab entries to keep it updated:PATH=/usr/local/bin:/usr/bin:/bin */3 * * * * CF_API_TOKEN=secret CF_ZONE_ID=secret CF_RECORD_NAME=headscale.yourdomain.com /path/to/barrel/scripts/update-dns.sh 2>&1 | tee -a /path/to/barrel/update-dns.log