Skip to content
3 changes: 0 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ ACME_EMAIL=your@email.com

# ProtonVPN WireGuard — main tunnel (NL/CH, P2P)
WG_PRIVATE_KEY=your_wireguard_private_key
WG_PUBLIC_KEY=your_wireguard_public_key
WIREGUARD_ADDRESSES=10.2.0.2/32

# ProtonVPN credentials (OpenVPN fallback)
Expand All @@ -32,7 +31,5 @@ MEDIA_TV_DIR=/mnt/user/media/tv
MEDIA_MOVIES_DIR=/mnt/user/media/movies

# qBittorrent
QB_USERNAME=admin
QB_PASSWORD=change_me
BT_PORT=51413

28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,34 @@ docker compose -f arr/docker-compose.yml up -d # media pipeline (9 container

Each compose file declares `env_file: ./.env`, resolved relative to its own directory — so `arr/docker-compose.yml` needs `arr/.env`. Symlinking keeps one source of truth at the repo root.

### Configuring each services
To configure each service, be sure to use docker internal DNS to let services reach each other on the network `arr_internal` :
- http://prowlarr:9696
- http://radarr:7878
- http://gluetun:8080 (qbittorrent)
- http://jellyfin:8096
- http://sonarr:8989
- http://bazarr:6767
- http://seerr:5055

### Subdomains
This is the list of subdomains for which you must create `A` records pointing to the Tailscale IP of the machine that hosts Traefik:
- traefik
- bazarr
- jellyfin
- prowlarr
- qbit
- radarr
- seerr
- sonarr

Note: create full FQDNs (e.g., traefik.example.com) in your DNS zone (alternatively, add them to your hosts file), each pointing to your host's Tailscale IP.
Comment on lines +71 to +81
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wildcard option would be more elegant

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh well, that's exactly what I was running against with this section. I have at least 20 other subdomains that are not routed through this stack and I would not want the people following this guide to introduce problems with a wildcard (If they already have a domain, they probably already have some subdomains registered).

In fact, in this section, I wanted to list the subdomains so that people would know and understand which one to use to access each service (the qbit one was a bit of a surprise for me since I was trying "qbittorrent" at first)!

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those are good comments, I will try to improve them a bit and merge


### qBittorrent
The web UI is at `qbit.example.com` and a temporary password for the `admin` user will be printed to the container log on startup.

You must then change username/password in the web UI section of settings. If you do not change the password a new one will be generated every time the container starts.

## Networking & Security

This is the part that's actually interesting. The services themselves are standard — the value is in how they're wired together.
Expand Down
15 changes: 6 additions & 9 deletions arr/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,16 @@ services:
VPN_SERVICE_PROVIDER: protonvpn
VPN_TYPE: wireguard
WIREGUARD_PRIVATE_KEY: ${WG_PRIVATE_KEY}
WIREGUARD_PUBLIC_KEY: ${WG_PUBLIC_KEY}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/wireguard.md shouldn't that be still here? Might be wrong, but some providers require it

Copy link
Copy Markdown
Author

@kevinstsauveur kevinstsauveur Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably right that some service need it.

I had problems to connect to protonvpn with the default stack. I'm not sure if it's this part or the other changes to gluetun service that resolve the problem. Maybe we can comment it by default?

Feel free to commit some change, it's your stack after all!

OPENVPN_USER: ${PROTONVPN_USERNAME}
OPENVPN_PASSWORD: ${PROTONVPN_PASSWORD}
WIREGUARD_ADDRESSES: ${WG_ADDRESSES:-10.2.0.2/32}
# Improved stability settings
WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL: 25s # Increased for better stability
SERVER_COUNTRIES: Netherlands,Switzerland
SERVER_FEATURES: p2p
# Port-forwarding
VPN_PORT_FORWARDING: "on"
VPN_PORT_FORWARDING_PROVIDER: protonvpn
VPN_PORT_FORWARD_ONLY: "on"
PORT_FORWARD_ONLY: "on"
VPN_PORT_FORWARDING: on
PORT_FORWARD_ONLY: on
FIREWALL_VPN_INPUT_PORTS: "8080,9999"
HEALTH_SERVER_ADDRESS: 0.0.0.0:9999
# DNS Configuration for better resolution
Expand Down Expand Up @@ -100,9 +99,7 @@ services:
PGID: ${PGID:-100}
TZ: ${TZ:-Europe/Warsaw}
WEBUI_PORT: 8080
WEBUI_USERNAME: ${QB_USERNAME:-admin}
WEBUI_PASSWORD: ${QB_PASSWORD:?Set QB_PASSWORD in .env}
TORRENTING_PORT: 51413
TORRENTING_PORT: ${BT_PORT}
BIND_TO_INTERFACE: tun0 # Bind qBittorrent to the VPN interface
volumes:
- ${DATA_DIR}/qbittorrent:/config
Expand Down Expand Up @@ -248,7 +245,7 @@ services:
PGID: ${PGID:-1000}
TZ: ${TZ:-Europe/Warsaw}
volumes:
- ${DATA_DIR}/seerr/config:/config
- ${DATA_DIR}/seerr/config:/app/config
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:5055/health"]
Expand Down
5 changes: 3 additions & 2 deletions infra/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ networks:

services:
traefik:
image: traefik:v2.10.7
image: traefik:v3.6.13
container_name: traefik
restart: unless-stopped
env_file:
Expand All @@ -20,6 +20,7 @@ services:
- CF_API_EMAIL=${CF_API_EMAIL}
- CF_DNS_API_TOKEN=${CF_DNS_API_TOKEN}
- TZ=${TZ:-Europe/London}
- DOCKER_API_VERSION=1.52
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ${DATA_DIR}/letsencrypt:/letsencrypt
Expand Down Expand Up @@ -57,4 +58,4 @@ services:
- "traefik.http.middlewares.secureHeaders.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.secureHeaders.headers.stsPreload=true"
- "traefik.http.middlewares.secureHeaders.headers.stsSeconds=31536000"
- "traefik.http.routers.dashboard.middlewares=secureHeaders@docker"
- "traefik.http.routers.dashboard.middlewares=secureHeaders@docker"