-
Notifications
You must be signed in to change notification settings - Fork 76
Joal & VPN & qbittorrent & Reverse proxy (with docker)
Using docker to deploy JOAL behind a VPN and accessing the services from a reverse proxy
This file is not a guide on how to use or configure JOAL you must be confident what you are doing and understand what's going on
- Docker 18.06.0+
- docker-compose 1.22.0+
- an internet router that supports local loopback
- a DNS name (The DNS provider MUST resolves subdomains as well, see below). If you don't have a DNS you can use DuckDns, it works great and it's free.
Your DNS must resolve subdomain, by this sentence i mean that if your domains is bar.example.com, the address foo.bar.example.com should also resolve to your IP.
This is the folder structure i'm using along that guide.
/home/you/data/
├─ joal/
│ ├─ clients/
│ ├─ torrents/
│ ├─ config.json
├─ openvpn/
│ ├─ vpn.ovpn
├─ traefik/
│ ├─ acme/
│ ├─ dynamics/
│ │ ├─ global.yaml
│ ├─ traefik.yaml
├─ .env
├─ docker-compose.yml
This file is used to store variable automatically resolved by the by the docker-compose.
TZ=Europe/Paris
PUID=1000
PGID=1000
ROOT=/home/you/data
# Traefik config for letsencrypt dns challenge
DUCKDNS_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx
DOMAIN_NAME=xxxxxxxxxx.duckdns.org
#JOAL
JOAL_PATH_PREFIX=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
JOAL_SECRET_TOKEN=XXXXXXXXXXXXXXXXX
Adapt to your wishes:
-
ROOT: The base path for all the configuration (see tree above). -
DUCKDNS_TOKEN: Your duckdns token (if using duckdns) -
DOMAIN_NAME: Your domain name -
JOAL_PATH_PREFIX: joal path prefix -
JOAL_SECRET_TOKEN: joal secret token
Your openvpn file, you can most likely have one from your VPN provider, if not... well find a proper VPN provider.
An empty folder but please create it yourself
http:
middlewares:
gzip-compress:
compress:
excludedContentTypes:
- text/event-stream
basic-auth:
basicAuth:
users:
- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
redirect-to-https:
redirectScheme:
scheme: https
permanent: true
tls:
options:
default:
minVersion: VersionTLS12
Replace to your wishes:
-
http.middleware.basic-auth.basicAuth.users: This basic auth will be use to protect traefik webui. You must provide a basicauth a basic name:encoded-password pair if you don't know how to generate this couple use thi htpasswd-generator website
#log:
# level: DEBUG
global:
sendAnonymousUsage: false
checknewversion: true
api:
dashboard: true
providers:
docker:
exposedByDefault: false
file:
directory: /etc/traefik/dynamics
watch: false
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
tcp-qbittorrent:
address: ":6881"
udp-qbittorrent:
address: ":6881/udp"
certificatesResolvers:
letsencrypt:
acme:
email: "do-not-email@xxxxxxxxxxxxx.duckdns.org"
storage: /etc/traefik/acme/acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
# caServer: "https://acme-staging-v02.api.letsencrypt.org/directory"
dnsChallenge:
provider: duckdns
Adapt to your wishes:
certificatesResolvers.letsencrypt.email
version: '3.7'
services:
vpn:
container_name: vpn
image: dperson/openvpn-client:latest
restart: always
devices:
- /dev/net/tun
cap_add:
- NET_ADMIN
volumes:
- ${ROOT}/openvpn:/vpn:ro
dns:
- "8.8.8.8"
- "8.8.4.4"
logging:
options:
max-size: "2m"
max-file: "3"
environment:
- FIREWALL
- TZ=${TZ}
traefik:
image: traefik:2.5.3
container_name: "traefik"
restart: always
volumes:
- ${ROOT}/traefik/traefik.yaml:/etc/traefik/traefik.yaml:ro
- ${ROOT}/traefik/dynamics:/etc/traefik/dynamics:ro
- ${ROOT}/traefik/acme:/etc/traefik/acme:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- DUCKDNS_TOKEN=${DUCKDNS_TOKEN}
ports:
- "80:80"
- "443:443"
- "6881:6881"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard-redir.rule=Host(`traefik.${DOMAIN_NAME}`)"
- "traefik.http.routers.dashboard-redir.entrypoints=web"
- "traefik.http.routers.dashboard-redir.middlewares=redirect-to-https@file"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.rule=Host(`traefik.${DOMAIN_NAME}`)"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls=true"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.tls.domains[0].main=${DOMAIN_NAME}"
- "traefik.http.routers.dashboard.tls.domains[0].sans=*.${DOMAIN_NAME}"
- "traefik.http.routers.dashboard.middlewares=gzip-compress@file"
- "traefik.http.routers.dashboard.middlewares=basic-auth@file"
joal:
depends_on:
- vpn
- traefik
container_name: joal
image: anthonyraymond/joal:2.1.26
restart: always
network_mode: "service:vpn"
volumes:
- ${ROOT}/joal:/data
command: ["--joal-conf=/data", "--spring.main.web-environment=true", "--server.port=80", "--joal.ui.path.prefix=${JOAL_PATH_PREFIX}", "--joal.ui.secret-token=${JOAL_SECRET_TOKEN}"]
labels:
- "traefik.enable=true"
- "traefik.http.routers.joal-redir.rule=Host(`joal.${DOMAIN_NAME}`)"
- "traefik.http.routers.joal-redir.entrypoints=web"
- "traefik.http.routers.joal-redir.middlewares=redirect-to-https@file"
- "traefik.http.services.joal-service.loadbalancer.server.port=80"
- "traefik.http.routers.joal-router.entrypoints=websecure"
- "traefik.http.routers.joal-router.rule=Host(`joal.${DOMAIN_NAME}`)"
- "traefik.http.routers.joal-router.middlewares=gzip-compress@file"
- "traefik.http.routers.joal-router.service=joal-service"
- "traefik.http.routers.joal-router.tls=true"
qbittorrent:
depends_on:
- vpn
- traefik
container_name: qbittorrent
image: linuxserver/qbittorrent:unstable-version-4.4.0202106140855-7320-2bd5aca3aubuntu20.04.1
restart: always
network_mode: "service:vpn"
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
- WEBUI_PORT=8080
volumes:
- /etc/localtime:/etc/localtime:ro
- ${ROOT}/qbittorrent/config:/config:rw
- ${ROOT}/qbittorrent/downloads:/downloads:rw
- ${ROOT}/joal/torrents:/completed-torrents-files:rw
labels:
- "traefik.enable=true"
- "traefik.http.routers.qbittorrent-ui-redir.rule=Host(`qbittorrent.${DOMAIN_NAME}`)"
- "traefik.http.routers.qbittorrent-ui-redir.entrypoints=web"
- "traefik.http.routers.qbittorrent-ui-redir.middlewares=redirect-to-https@file"
- "traefik.http.services.qbittorrent-service.loadbalancer.server.port=8080"
- "traefik.http.routers.qbittorrent-ui-router.entrypoints=websecure"
- "traefik.http.routers.qbittorrent-ui-router.rule=Host(`qbittorrent.${DOMAIN_NAME}`)"
- "traefik.http.routers.qbittorrent-ui-router.middlewares=gzip-compress@file"
- "traefik.http.routers.qbittorrent-ui-router.service=qbittorrent-service"
- "traefik.http.routers.qbittorrent-ui-router.tls=true"
- "traefik.tcp.services.qbittorrent-tcp-service.loadbalancer.server.port=6881"
- "traefik.tcp.routers.qbittorrent-tcp-router.entrypoints=tcp-qbittorrent"
- "traefik.tcp.routers.qbittorrent-tcp-router.rule=HostSNI(`*`)"
- "traefik.tcp.routers.qbittorrent-tcp-router.service=qbittorrent-tcp-service"
- "traefik.udp.services.qbittorrent-udp-service.loadbalancer.server.port=6881"
- "traefik.udp.routers.qbittorrent-udp-router.service=qbittorrent-udp-service"
- "traefik.udp.routers.qbittorrent-udp-router.entrypoints=udp-qbittorrent"
Nothing to change in this file because every variables are extracted to .env
Done !
After obtaining the certificates you'll be able to reach your services at (assuming you have the domain name example.duckdns.org):
https:traefik.example.duckdns.org (you'll be presented a basic login form, use the basic auth credential generated earlier)
https:joal.example.duckdns.org (connection settings within webui: serverAddress=joal.example.duckdns.org, serverPort=443, path prefix and secret token are the value you haved defined in the .env file)
https:qbitorrent.example.duckdns.org
If you want to, adding sonarr, radarr, jackett and flaresolver is a matter of second. Simply add those to yout docker-compose:
sonarr:
depends_on:
- traefik
- qbittorrent
container_name: sonarr
image: linuxserver/sonarr:version-3.0.6.1265
restart: always
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
volumes:
- /etc/localtime:/etc/localtime:ro
- ${ROOT}/sonarr/config:/config:rw
- /xxxxxxxxxxxxxxxxxxxxxxxxxxx/path/to/your/tv/show/folder:/tv
- ${ROOT}/qbittorrent/downloads:/downloads
labels:
- "traefik.enable=true"
- "traefik.http.routers.sonarr-redir.rule=Host(`sonarr.${DOMAIN_NAME}`)"
- "traefik.http.routers.sonarr-redir.entrypoints=web"
- "traefik.http.routers.sonarr-redir.middlewares=redirect-to-https@file"
- "traefik.http.services.sonarr-service.loadbalancer.server.port=8989"
- "traefik.http.routers.sonarr-router.entrypoints=websecure"
- "traefik.http.routers.sonarr-router.rule=Host(`sonarr.${DOMAIN_NAME}`)"
- "traefik.http.routers.sonarr-router.middlewares=gzip-compress@file"
- "traefik.http.routers.sonarr-router.service=sonarr-service"
- "traefik.http.routers.sonarr-router.tls=true"
radarr:
depends_on:
- traefik
- qbittorrent
container_name: radarr
image: linuxserver/radarr:version-3.2.2.5080
restart: always
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
volumes:
- /etc/localtime:/etc/localtime:ro
- ${ROOT}/radarr/config:/config:rw
- /xxxxxxxxxxxxxxxxxxxxxxxxxxx/path/to/your/movies/folder:/movies
- ${ROOT}/qbittorrent/downloads:/downloads
labels:
- "traefik.enable=true"
- "traefik.http.routers.radarr-redir.rule=Host(`radarr.${DOMAIN_NAME}`)"
- "traefik.http.routers.radarr-redir.entrypoints=web"
- "traefik.http.routers.radarr-redir.middlewares=redirect-to-https@file"
- "traefik.http.services.radarr-service.loadbalancer.server.port=7878"
- "traefik.http.routers.radarr-router.entrypoints=websecure"
- "traefik.http.routers.radarr-router.rule=Host(`radarr.${DOMAIN_NAME}`)"
- "traefik.http.routers.radarr-router.middlewares=gzip-compress@file"
- "traefik.http.routers.radarr-router.service=radarr-service"
- "traefik.http.routers.radarr-router.tls=true"
flaresolverr:
container_name: flaresolverr
image: flaresolverr/flaresolverr:v1.2.9
restart: always
network_mode: "service:vpn"
environment:
- LOG_LEVEL=info
- LOG_HTML=false
- CAPTCHA_SOLVER=none
jackett:
depends_on:
- traefik
- flaresolverr
container_name: jackett
image: linuxserver/jackett:version-v0.18.795
restart: always
network_mode: "service:vpn"
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
volumes:
- /etc/localtime:/etc/localtime:ro
- ${ROOT}/jackett/config:/config:rw
labels:
- "traefik.enable=true"
- "traefik.http.routers.jackett-redir.rule=Host(`jackett.${DOMAIN_NAME}`)"
- "traefik.http.routers.jackett-redir.entrypoints=web"
- "traefik.http.routers.jackett-redir.middlewares=redirect-to-https@file"
- "traefik.http.services.jackett-service.loadbalancer.server.port=9117"
- "traefik.http.routers.jackett-router.entrypoints=websecure"
- "traefik.http.routers.jackett-router.rule=Host(`jackett.${DOMAIN_NAME}`)"
- "traefik.http.routers.jackett-router.middlewares=gzip-compress@file"
- "traefik.http.routers.jackett-router.service=jackett-service"
- "traefik.http.routers.jackett-router.tls=true"