Seedbox

Ubuntu 20.04 / Debian 10 – An Anonymous and Secured Seedbox – (Part 2) Remote access with Traefik

A reverse proxy is a server that sits in front of web servers and forwards client HTTP requests to the appropriate backend service. In our case, a reverse proxy directs client requests to the appropriate Docker container. We have a multitude of Docker containers and we cannot listen to them all on port 80 or 443, hence the use of a reverse proxy. Add to that a nice domain name to your seedbox by securing everything with the SSL / TLS protocol and a Let’s Encrypt certificate.

5 – Traefik

Traefik is a modern reverse-proxy and load-balancer designed to facilitate the deployment of microservices (Docker, Kubernetes, AWS, etc.). Traefik is extremely simple to configure and automatically manages your certificates issued by Let’s Encrypt. In addition, it is able to load your containers dynamically without service interruption and has a dashboard displaying all of your configured routes.

We will detail here the procedure with the Deluge AirVPN image but it remains of course compatible with PIA images and without VPN if it is followed conscientiously.

5.1 – Traefik user

If you have several docker-compose.yml or if you plan to create one later, it is better to isolate and dedicate a docker-compose.yml for Traefik. It is not recommended to launch it under your superuser, so it’s better to create a dedicated user.

  1. Create a traefik user:

    sudo adduser traefik
  2. Add it to the docker group:

    sudo adduser traefik docker

5.2 – Traefik network

In the first part of this howto, each Docker container shares the network of your machine to be accessible locally with the network_mode: "host" property. With a reverse proxy, this configuration is no longer necessary and we will take the opportunity to add a little more security by isolating your containers in a network only accessible by Traefik.

  1. Log in under the traefik user:

    su traefik
  2. Move to the home directory of this user:

    cd
  3. Create the network dedicated to Traefik and all of your containers:

    docker network create traefik_network

5.3 – Network isolation between containers and the Docker host

Create the file /home/traefik/docker-compose.yml with the following content (do not change anything):

version: '3.7'
services:
  traefik:
    image: "traefik:v2.2"
    container_name: "traefik"
    restart: unless-stopped
    networks:
      - traefik_network
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /home/traefik/traefik.toml:/traefik.toml:ro
      - /home/traefik/acme.json:/acme.json

networks:
  traefik_network:
    external: true
  • /var/run/docker.sock:/var/run/docker.sock:ro : specifies the Unix socket of your docker. Leave this default.
  • /home/traefik/traefik.toml:/traefik.toml:ro : specifies the path to the Traefik configuration file. We will create it in the next step.
  • /home/traefik/acme.json:/acme.json : specifies the path of the file containing the information relating to your certificates.
  • traefik_network : specifies the network created previously and dedicated to Traefik. We will add the different containers to this network later.

5.4 – Traefik configuration

Traefik can be configured in different ways, we will detail here, the configuration recommended by Traefik, namely by a static file in TOML format.

  1. Traefik stores information related to the certificate in an acme.json file. First you must create the file and assign it a minimum of permissions:

    touch /home/traefik/acme.json && chmod 600 /home/traefik/acme.json
  2. Create the Traefik configuration file /home/media/traefik/traefik.toml by adding the following lines (you just need to edit the email property):

    [providers.docker]
      endpoint = "unix:///var/run/docker.sock"
      watch = true
      exposedByDefault = false
    
    [entryPoints.web]
      address = ":80"
      [entryPoints.web.http.redirections.entryPoint]
        to = "websecure"
        scheme = "https"
    
    [entryPoints.websecure]
      address = ":443"
    
    [certificatesResolvers.leresolver.acme]
      email = "votre-adresse@email.com"
      storage = "acme.json"
      [certificatesResolvers.leresolver.acme.httpChallenge]
        entryPoint = "web"
      
    • [providers.docker]: this option enables Docker support.
    • endpoint = "unix:///var/run/docker.sock": specifies the Unix socket of your Docker at Traefik. Leave the default.
    • watch = true: allows hot deployment of containers as soon as a change in configuration is detected.
    • exposedByDefault = false: does not expose containers by default to the outside world. It is preferable to activate this option in the docker-compose.yml file because, if for some reason, you no longer wish to make a container accessible from the outside.
    • [entryPoints.web] and [entryPoints.websecure]: these options define the entry points for your Traefik. web and websecure are purely indicative, you can name them differently but they must correspond to the labels that we will define later in the docker-compose.yml file. The adress properties specify the ports on which Traefik « listens » depending on the entry point.
    • [entryPoints.web.http.redirections.entryPoint]: forces port 80 to port 443 forwarding so forces HTTP over HTTPS.
    • [certificatesResolvers.[NOM_RESOLVEUR].acme]: we indicate that we wish to use the ACME protocol (therefore the Let’s Encrypt service) to obtain a certificate. The name of the resolver is purely indicative, it must simply correspond to the labels that we will define later in the docker-compose.yml file.
    • storage = "acme.json": the storage property specifies to Traefik the file (which we created previously) where the information relating to certificates will be stored. The common error is to indicate the absolute path (/home/media/traefik/acme.json in our case), here the path to be filled in is the one inside the Traefik container, so you must leave this value by default.
    • [certificatesResolvers.[NOM_RESOLVEUR].acme.httpChallenge]: this option simply specifies by which entry point (in our case port 80) Traefik can obtain a certificate.
  3. Move to the home directory of the traefik user and start the container:

    cd
    docker-compose up -d

5.5 – Labels and traefik network


Do not forget to add dns rules for each of the subdomains in the administrator interface of the provider of your domain name to point to the ip of your server. the rules to be added, including type “A”. if your server is hosted at your home, it will also be necessary to create a redirection of port 80 and 443 to your server in the configuration interface of your internet box (or router).


  1. Log in under the media user and move to the home directory of this user:

    su media
    cd
  2. Start by declaring your domain in the /home/media/.env file by adding the NETWORK and BASE_HOST properties by modifying the value by your domain. Be careful here to fill in the base of your domain (no sub-domain or even www):

    [...]
    NETWORK=traefik_network
    BASE_HOST=mondomaine.com
  3. Edit your /home/media/docker-compose.yml file and replace all network_mode: "host" properties through your new network.

    Please note, the Deluge image without VPN also has this directive. In addition, all port exposures are useless, you can delete all directives ports: with associated ports.

    Then, add the labels allowing to communicate with Traefik and finish by adding the network traefik_network at the end of the file:

    version: '3.7'
    services:
      deluge:
        image: binhex/arch-delugevpn:latest
        container_name: deluge
        restart: unless-stopped
        networks:
          - ${NETWORK}
        cap_add:
          - NET_ADMIN
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - VPN_ENABLED=yes
          - VPN_PROV=airvpn
          - ENABLE_PRIVOXY=yes
          - LAN_NETWORK=${LAN_NETWORK}
          - NAME_SERVERS=209.222.18.222,37.235.1.174,8.8.8.8,209.222.18.218,37.235.1.177,8.8.4.4
          - UMASK=000
          - DEBUG=false
        volumes:
          - /home/deluge/config:/config
          - /etc/localtime:/etc/localtime:ro
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.deluge.entrypoints=web,websecure"
          - "traefik.http.routers.deluge.rule=Host(`deluge.${BASE_HOST}`)"
          - "traefik.http.services.deluge.loadbalancer.server.port=8112"
          - "traefik.http.routers.deluge.tls=true"
          - "traefik.http.routers.deluge.tls.certresolver=leresolver"
      
      jackett:
        image: linuxserver/jackett:latest
        container_name: jackett
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/jackett/config:/config
          - /etc/localtime:/etc/localtime:ro
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.jackett.entrypoints=web,websecure"
          - "traefik.http.routers.jackett.rule=Host(`jackett.${BASE_HOST}`)"
          - "traefik.http.services.jackett.loadbalancer.server.port=9117"
          - "traefik.http.routers.jackett.tls=true"
          - "traefik.http.routers.jackett.tls.certresolver=leresolver"
    
      sonarr:
        image: linuxserver/sonarr:latest
        container_name: sonarr
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/sonarr/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.sonarr.entrypoints=web,websecure"
          - "traefik.http.routers.sonarr.rule=Host(`sonarr.${BASE_HOST}`)"
          - "traefik.http.services.sonarr.loadbalancer.server.port=8989"
          - "traefik.http.routers.sonarr.tls=true"
          - "traefik.http.routers.sonarr.tls.certresolver=leresolver"
    
      radarr:
        image: linuxserver/radarr:latest
        container_name: radarr
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/radarr/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.radarr.entrypoints=web,websecure"
          - "traefik.http.routers.radarr.rule=Host(`radarr.${BASE_HOST}`)"
          - "traefik.http.services.radarr.loadbalancer.server.port=7878"
          - "traefik.http.routers.radarr.tls=true"
          - "traefik.http.routers.radarr.tls.certresolver=leresolver"
    
      lidarr:
        image: linuxserver/lidarr:latest
        container_name: lidarr
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/lidarr/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.lidarr.entrypoints=web,websecure"
          - "traefik.http.routers.lidarr.rule=Host(`lidarr.${BASE_HOST}`)"
          - "traefik.http.services.lidarr.loadbalancer.server.port=8686"
          - "traefik.http.routers.lidarr.tls=true"
          - "traefik.http.routers.lidarr.tls.certresolver=leresolver"
    
      plex:
        image: linuxserver/plex:latest
        container_name: plex
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - VERSION=latest
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
        volumes:
          - /home/media/plex/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.plex.entrypoints=web,websecure"
          - "traefik.http.routers.plex.rule=Host(`plex.${BASE_HOST}`)"
          - "traefik.http.services.plex.loadbalancer.server.port=32400"
          - "traefik.http.routers.plex.tls=true"
          - "traefik.http.routers.plex.tls.certresolver=leresolver"
    
    networks:
      traefik_network:
        external: true
    
    • traefik.enable=true: this label exposes the container to the outside world. It overloads the exposedByDefault property of your /home/media/traefik/traefik.toml file.
    • traefik.docker.network=traefik_network : this label specifies to Traefik the network to use.
    • traefik.http.routers.[NOM_DU_CONTAINER].entrypoints: each routing rule specific to a container must be specified by a name, here we simply use the name of the container. The entrypoints label specifies that incoming requests on the web (port 80) and websecure (port 443) entry points will be transmitted to the container.
    • traefik.http.routers.[NOM_DU_CONTAINER].rule=Host(`[SERVICE].${BASE_HOST}`): here we specify a rule, any request arriving on http://SERVICE.mydomain.com will be transmitted to the associated Docker container.
    • traefik.http.services.[NOM_DU_CONTAINER].loadbalancer.server.port=[PORT]: we specify the port of the container on which the requests must be transmitted.
    • traefik.http.routers.[NOM_CONTAINER].tls: enable SSL/TLS support.
    • traefik.http.routers.[NOM_CONTAINER].tls.certresolver: specifies the resolver and therefore the certificates to be used.
  4. Move to the home directory of the media user and start all the containers with the command:

    cd
    docker-compose up -d

5.6 – Services configuration

Plex

For remote access, it is necessary to associate the Plex web interface with your server. For this, you must specify the URL and an association code whose validity is 4 minutes.
  1. Ask for the association code at the following address: https://www.plex.tv/claim/

  2. Edit your /home/media/docker-compose.yml file and add the following lines, specifying the code obtained previously:

    version: '3.7'
    services:
      [...]
    
      plex:
        image: linuxserver/plex:latest
        container_name: plex
        restart: unless-stopped
        networks:
          - ${NETWORK}
        environment:
          - VERSION=latest
          - PUID=${PUID}
          - PGID=${PGID}
          - TZ=Europe/Paris
          - PLEX_CLAIM=claim-424242424242
          - ADVERTISE_IP=plex.${BASE_HOST}:443
        volumes:
          - /home/media/plex/config:/config
          - ${PATH_MEDIA}:/data
        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=${NETWORK}"
          - "traefik.http.routers.plex.entrypoints=web,websecure"
          - "traefik.http.routers.plex.rule=Host(`plex.${BASE_HOST}`)"
          - "traefik.http.services.plex.loadbalancer.server.port=32400"
          - "traefik.http.routers.plex.tls=true"
          - "traefik.http.routers.plex.tls.certresolver=media-resolver"
    
    [...]
    
  3. Restart the Plex container with the command:

    docker-compose up -d
Services are now available at the following addresses:
  • Deluge : http://deluge.mydomain.com
  • Jackett : http://jackett.mydomain.com
  • Sonarr : http://sonarr.mydomain.com
  • Radarr : http://radarr.mydomain.com
  • Lidarr : http://lidarr.mydomain.com
  • Plex : http://plex.mydomain.com

6 – Configuration

We will now configure the applications so that they can communicate with each other and that each of them has a minimum of security.

Next (configuration and issues)



Debian

Debian 10 BlusterDocker 19.03.8
Docker Compose 1.25.5
Nginx 1.17.10
Deluge 2.0.4
Jackett 0.16.105.0
Sonarr 2.0.0.5344
Radarr 0.2.0.1480
Lidarr 0.7.1.1381



Evaluez ce tutoriel !
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *