Streaming Está Quebrado VI: A Pilha Completa

Este post foi originalmente escrito em inglês. A tradução pode não refletir 100% das ideias originais do autor.

Chega de enrolar, né?

Brincadeiras à parte, considero os posts anteriores desta série extremamente importantes. Cada um cobre uma peça crítica:

  • Streaming is Broken II: Choosing Hardware. Onde aprendemos sobre uma configuração de homeserver de baixo custo com meus dois centavos sobre armazenamento.
  • Streaming is Broken III: The Foundation (OS, Docker, and “Day One”). Onde configuramos nosso SO, Docker e preparamos o terreno para o que viria a seguir.
  • Streaming is Broken IV: The Fortress: VPN and Gluetun. Um capítulo que você normalmente não encontrará em outros tutoriais, focado em segurança e privacidade.
  • Streaming is Broken V: Hardlinks and Permissions. Dicas para evitar dores de cabeça futuras em nossas configurações.

Mas se eu tivesse que escolher apenas um post para explicar como configurar um homeserver, seria este.

Sem mais delongas, vamos começar.

A Pilha Multimídia

qBittorrent

Como eu disse em posts anteriores, pirataria é o pior crime do mundo, eu amo empresas que oferecem serviços ruins, e gosto de pagar mais por menos. Claro, por motivos legais, digo isso.

Qbittorrent

Agora, falando sério, o fluxo do nosso servidor de mídia doméstico será o seguinte:

  • Vamos procurar filmes e séries no Overseerr (tudo será explicado mais abaixo)
  • O Overseerr enviará solicitações para o Radarr (Filmes) e Sonarr (Séries)
  • O Radarr e o Sonarr procurarão o material em sites indexados pelo Prowlarr, cuja única função será gerenciar esses indexadores
  • O qBittorrent fará o download do arquivo. O Radarr e o Sonarr identificarão automaticamente o arquivo e moverão o download para suas próprias pastas
  • O Jellyfin será nosso aplicativo de streaming na TV, iPad, computador, etc. É onde assistiremos ao conteúdo adquirido

Com isso em mente, vamos começar com o primeiro item a ser configurado em nossa lista: o cliente de download.

Em nosso docker compose, teremos algo assim:

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - WEBUI_PORT=8080
    volumes:
      - /home/donkey/EmuleVision/Settings/Qbittorrent:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Aqui, como expliquei no meu post sobre segurança, o qBittorrent será protegido via VPN, e o Gluetun será quem protegerá nosso container. No meu caso, conectado a um serviço de VPN pago (ele tem integrações com NordVPN, Surfshark, etc.). Como estamos falando de baixar arquivos multimídia, esqueça VPNs gratuitas: além de serem limitadas por razões óbvias, são extremamente inseguras.

É importante deixar claro que para evitar vazamentos de IP, o qBittorrent dependerá absolutamente do Gluetun estar funcional. Se a VPN cair, o qBittorrent será interrompido automaticamente. Essa é a beleza do depends_on com condition: service_healthy. O container nem mesmo iniciará se o Gluetun não estiver pronto.

Neste caso e daqui em diante, estaremos configurando permissões e fuso horário (PUID, PGID e TZ) da mesma forma. Para isso, crie um arquivo .env para esses parâmetros.

Exemplo simples:

PUID=1000
PGID=1000
TZ=Etc/UTC

Para configurar o aplicativo em si, não vou reinventar a roda. Vou linkar o tutorial correspondente do TRaSH Guides para cada tecnologia:

  • Basic-Setup - Configuração básica das configurações mais comuns.
  • Paths - Onde definir sua localização raiz de download.
  • How to add Categories - Como configurar categorias para o qBittorrent e como você pode gerenciar e organizar seus torrents em grupos. Os aplicativos Starr podem usar categorias no qBittorrent para rastrear downloads para monitorar, em vez de assistir a todos os torrents em seu cliente.
  • Port forwarding - Onde em seu cliente de download você deve adicionar a porta que você encaminhou com seu serviço de VPN.

Prowlarr: O Gerenciador de Indexadores

O Prowlarr é o herói anônimo desta pilha. É o intermediário que conecta seu Radarr e Sonarr aos indexadores de torrent. Pense nele como uma telefonista dos anos 1950, exceto que em vez de conectar chamadas telefônicas, está conectando suas solicitações de download a sites de torrent.

  prowlarr:
    image: ghcr.io/hotio/prowlarr:latest
    container_name: prowlarr
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Prowlarr:/config
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Prowlarr

Percebeu o padrão aqui? Ele também está atrás do Gluetun. Tudo o que toca a internet pública para “métodos alternativos de aquisição” fica atrás da VPN. Sem exceções.

A configuração do Prowlarr é direta:

  1. Adicione seus indexadores (rastreadores públicos ou privados)
  2. Conecte-o ao Radarr e Sonarr via chaves de API
  3. Deixe-o sincronizar automaticamente

A beleza é que você configura os indexadores uma vez no Prowlarr, e eles se propagam para todos os seus aplicativos Arr. Chega de copiar e colar URLs de rastreadores em cinco interfaces diferentes.

Para configuração detalhada, confira TRaSH Guides - Prowlarr.

FlareSolverr: O Contornador do Cloudflare

Alguns indexadores se protegem com as medidas anti-bot do Cloudflare. O FlareSolverr é um navegador headless que resolve esses desafios automaticamente.

  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    network_mode: "service:gluetun"
    environment:
      - TZ=${TZ}
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Você o configura uma vez no Prowlarr, e ele cuida do resto. Quando o Prowlarr acessa um site protegido pelo Cloudflare, o FlareSolverr entra em ação, resolve o desafio e retorna os resultados. É como ter um advogado robô especializado em passar pelos seguranças da porta. O guia está aqui

Sonarr: O Gerenciador de Séries de TV

O Sonarr é onde a mágica acontece para séries de TV. Ele monitora sua “lista de desejos”, busca novos episódios no Prowlarr, os envia para o qBittorrent e organiza tudo automaticamente.

  sonarr:
    image: ghcr.io/linuxserver/sonarr:latest
    container_name: sonarr
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Sonarr:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Sonarr

Pontos-chave de configuração:

  • Pastas Raiz: Defina como /data/media/tv
  • Cliente de Download: Aponte para o qBittorrent em localhost:8080 (lembre-se, eles compartilham a mesma pilha de rede via Gluetun)
  • Perfis de Qualidade: Use as Configurações de Qualidade do TRaSH Guides para evitar baixar releases de qualidade ruim

O Sonarr irá automaticamente:

  • Buscar novos episódios quando eles forem ao ar
  • Atualizar episódios existentes se versões de melhor qualidade aparecerem
  • Renomear arquivos de acordo com seu esquema de nomenclatura preferido
  • Mover downloads completos para sua biblioteca de mídia usando Hardlinks (lembra daquele post?)

Radarr: O Gerenciador de Filmes

O Radarr é o irmão do Sonarr, mas para filmes. Mesma lógica, tipo de conteúdo diferente.

  radarr:
    image: ghcr.io/linuxserver/radarr:latest
    container_name: radarr
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Radarr:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Radarr

A configuração espelha a do Sonarr:

  • Pasta Raiz: /data/media/movies
  • Cliente de Download: qBittorrent em localhost:8080
  • Perfis de Qualidade: TRaSH Guides para Radarr

A diferença é o tipo de conteúdo. O Radarr rastreia filmes individuais em vez de séries/temporadas/episódios. Ele também se integra perfeitamente com serviços como listas do Trakt ou IMDb se você quiser automatizar a adição de filmes à sua coleção.

Bazarr: O Especialista em Legendas

Lembra quando eu reclamei da qualidade péssima das legendas da Netflix no primeiro post? O Bazarr resolve isso.

  bazarr:
    image: ghcr.io/linuxserver/bazarr:latest
    container_name: bazarr
    restart: unless-stopped
    network_mode: "service:gluetun"
    environment:
      - TZ=${TZ}
      - PUID=${PUID}
      - PGID=${PGID}
    volumes:
      - /home/donkey/EmuleVision/media/movies:/movies
      - /home/donkey/EmuleVision/media/tv:/tv
      - /home/donkey/EmuleVision/Settings/Bazarr:/config
    depends_on:
      gluetun:
        condition: service_healthy

Bazarr

O Bazarr automaticamente:

  • Baixa legendas para seus filmes e séries
  • Suporta múltiplos idiomas
  • Sincroniza com OpenSubtitles, Subscene e outros provedores
  • Pode até atualizar legendas existentes se versões melhores aparecerem

A configuração é simples: conecte-o ao Sonarr e Radarr via chaves de API, selecione seus idiomas e provedores preferidos e deixe-o rodar. Seu thriller polonês finalmente terá legendas em inglês compreensíveis.

Kaizoku: O Baixador de Mangá

Para quem consome mais do que apenas filmes e séries, o Kaizoku cuida da aquisição de mangás.

  kaizoku:
    image: ghcr.io/oae/kaizoku:latest
    container_name: kaizoku
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - KAIZOKU_PORT=3002
    volumes:
      - /home/donkey/EmuleVision/Settings/Kaizoku:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Ele rastreia séries de mangá, baixa automaticamente novos capítulos e os organiza para seu prazer de leitura. Pense nele como o Sonarr, mas para quadrinhos.

Overseerr: O Gerenciador de Solicitações

Este é o componente voltado para o usuário. O Overseerr é com o que seus familiares interagem quando querem assistir algo.

  overseerr:
    image: lscr.io/linuxserver/overseerr:latest
    container_name: overseerr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    ports:
      - "5055:5055"
    volumes:
      - /home/donkey/EmuleVision/Settings/Overseerr:/config
    restart: unless-stopped

Overserr

Percebeu algo diferente? Sem Gluetun. O Overseerr não baixa nada. É apenas uma interface de solicitação. Sua esposa quer assistir Gossip Girl? Ela abre o Overseerr, procura pela série, clica em “Solicitar”, e o Sonarr cuida do resto.

Plex: O Frontend de Streaming

É aqui que tudo se junta. O Plex é o seu serviço de streaming pessoal.

  plex:
    image: lscr.io/linuxserver/plex:latest
    container_name: plex
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - VERSION=docker
      - PLEX_CLAIM=claim-6DcZ6Chj7tSXYU4n6GS7
    network_mode: host
    volumes:
      - /home/donkey/EmuleVision/Settings/Plex:/config
      - /home/donkey/EmuleVision/media/movies:/data/movies
      - /home/donkey/EmuleVision/media/tv:/data/tvshows
    devices:
      - /dev/dri:/dev/dri
    restart: unless-stopped

Plex

Detalhes críticos:

  1. network_mode: host - Ao contrário dos outros containers, o Plex precisa de acesso direto à rede para descoberta DLNA e desempenho máximo de streaming. Lembra do diagrama de arquitetura do post sobre VPN? Este é o “Clean Group”.

  2. devices: /dev/dri - Isso expõe o codificador de hardware Intel QuickSync ao container. Sem isso, a transcodificação assassinaria sua CPU. Com ele, a GPU do seu N100 lida com a transcodificação 4K enquanto a CPU tira uma soneca.

  3. PLEX_CLAIM - Este token vincula seu servidor Plex à sua conta Plex na primeira inicialização. Você o obtém em plex.tv/claim. Ele expira após 4 minutos, então gere-o logo antes do seu primeiro docker compose up.

  4. Sem dependência do Gluetun - O Plex faz streaming localmente. Passar vídeo 4K de 80Mbps por um túnel VPN é insano. Este tráfego permanece na sua LAN, rápido e limpo.

Configurações essenciais:

  • Habilite a Aceleração por Hardware (Intel QuickSync) em Configurações → Transcoder
  • Configure suas bibliotecas (Filmes apontando para /data/movies, Séries apontando para /data/tvshows)
  • Configure o acesso remoto (o Plex faz isso automaticamente, mas você pode desativá-lo para uso apenas na LAN)
  • Instale o aplicativo Plex na sua TV, celular, tablet

A beleza do Plex sobre as alternativas de código aberto é o polimento. Os aplicativos são nativos, rápidos e funcionam perfeitamente em todos os dispositivos imagináveis. Sua esposa não precisará de um tutorial para assistir Gossip Girl no iPad dela.

Para configuração detalhada, consulte a documentação oficial do Plex.

A Pilha de Suporte

Portainer: O Painel de Controle do Docker

Gerenciar containers via CLI é bom quando você está configurando as coisas. Mas quando algo quebra às 2 da manhã e você precisa reiniciar um serviço rapidamente, uma interface web é inestimável.

  portainer:
    image: portainer/portainer-ce:2.20.2
    container_name: portainer
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/donkey/EmuleVision/Settings/Portainer:/data
    ports:
      - "9000:9000"
    restart: unless-stopped

O Portainer oferece:

  • Status dos containers de relance
  • Reiniciar/parar/remover com um clique
  • Visualização de logs sem precisar de SSH
  • Monitoramento de uso de recursos

Acesse-o em http://seu-ip-do-servidor:9000.

Homepage: O Painel de Controle Unificado

O Homepage é o seu centro de comando. Ele agrega todos os seus serviços em uma única interface bonita.

  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    volumes:
      - /home/donkey/EmuleVision/Settings/Homepage:/app/config
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - HOMEPAGE_ALLOWED_HOSTS=*
    ports:
      - "3000:3000"
    restart: unless-stopped

Homepage

Você o configura com arquivos YAML para exibir:

  • Status dos serviços
  • Links rápidos
  • Integrações de API (fila de downloads do Sonarr, adições recentes do Jellyfin)
  • Estatísticas do sistema

Isso se torna a sua homepage favorita. Chega de memorizar qual serviço está em qual porta.

Scrutiny: O Monitor de Saúde dos Discos

Lembra daquele SSD de 512GB no qual estamos confiando? Precisamos monitorar sua saúde.

  scrutiny:
    image: ghcr.io/analogj/scrutiny:master-omnibus
    container_name: scrutiny
    cap_add:
      - SYS_RAWIO
    devices:
      - /dev/sda:/dev/sda
    volumes:
      - /run/udev:/run/udev:ro
      - /home/donkey/EmuleVision/Settings/Scrutiny:/opt/scrutiny/config
      - /home/donkey/EmuleVision/Settings/Scrutiny/influxdb:/opt/scrutiny/influxdb
    ports:
      - "8086:8080"
    restart: unless-stopped

Scrutiny

O Scrutiny lê dados S.M.A.R.T. do seu disco e alerta você se detectar degradação. SSDs não falham gradualmente; eles falham subitamente. Isso lhe dá um aviso antes de uma perda catastrófica de dados.

FileBrowser: O Gerenciador de Arquivos Web

Às vezes você precisa acessar arquivos diretamente sem usar SSH ou montar um compartilhamento Samba.

  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
    volumes:
      - /home/donkey/EmuleVision/Settings/Filebrowser/filebrowser.db:/database.db
      - /home/donkey/EmuleVision/Settings/Filebrowser/.filebrowser.json:/.filebrowser.json
      - /home/donkey/EmuleVision:/srv
    ports:
      - "8082:80"
    restart: unless-stopped

O FileBrowser fornece:

  • Gerenciamento de arquivos baseado na web
  • Capacidades de upload/download
  • Controles de permissão de usuário
  • Links de compartilhamento de arquivos

Útil para aquelas raras vezes em que você precisa adicionar um arquivo manualmente ou verificar algo sem acesso ao terminal.

Kavita e Calibre-Web: A Pilha de Leitura

Para os entusiastas de livros:

  kavita:
    image: jvmilazz0/kavita:latest
    container_name: kavita
    environment:
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Kavita:/kavita/config
      - /home/donkey/EmuleVision/media/manga:/manga
      - /home/donkey/EmuleVision/media/comics:/comics
    ports:
      - "5000:5000"
    restart: unless-stopped

  calibre-web:
    image: lscr.io/linuxserver/calibre-web:latest
    container_name: calibre-web
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/CalibreWeb:/config
      - /home/donkey/EmuleVision/books:/books
    ports:
      - "8083:8083"
    restart: unless-stopped
  • Kavita: Para mangás e quadrinhos (arquivos CBZ/CBR)
  • Calibre-Web: Para ebooks (EPUB, MOBI, PDF)

Calibre

Ambos oferecem interfaces de leitura baseadas na web com rastreamento de progresso, gerenciamento de metadados e suporte a aplicativos móveis.

O Docker Compose Completo

Veja como tudo se encaixa. Observe a segregação de rede entre o grupo VPN (Gluetun + clientes de download) e o grupo limpo (Jellyfin, Overseerr, etc.):

version: '3'

services:
  gluetun:
    image: qmcgaw/gluetun
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - "8080:8080" # Qbittorrent
      - "9696:9696" # Prowlarr
      - "8191:8191" # Flaresolverr
      - "8989:8989" # Sonarr
      - "7878:7878" # Radarr
      - "3002:3002" # Kaizoku
      - "6881:6881" # Porta de Torrent
      - "6881:6881/udp"
      - "6767:6767" # Bazarr
      - "8090:8090"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - VPN_SERVICE_PROVIDER=custom
      - VPN_TYPE=openvpn
      - OPENVPN_USER=${VPN_USER}
      - OPENVPN_PASSWORD=${VPN_PASS}
      - OPENVPN_CUSTOM_CONFIG=/gluetun/custom.conf
      - FIREWALL_VPN_INPUT_PORTS=6881
      - BLOCK_MALICIOUS=no
      - BLOCK_ADS=no
      - BLOCK_SURVEILLANCE=no
      - FIREWALL_INPUT_PORTS=8080,9696,8191,8989,7878,3002,6767,8090
    volumes:
      - ./Settings/Gluetun:/gluetun
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "ping -c 1 1.1.1.1 || ping -c 1 8.8.8.8 || ping -c 1 9.9.9.9 || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - WEBUI_PORT=8080
    volumes:
      - /home/donkey/EmuleVision/Settings/Qbittorrent:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  prowlarr:
    image: ghcr.io/hotio/prowlarr:latest
    container_name: prowlarr
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Prowlarr:/config
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  flaresolverr:
    image: ghcr.io/flaresolverr/flaresolverr:latest
    container_name: flaresolverr
    network_mode: "service:gluetun"
    environment:
      - TZ=${TZ}
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  sonarr:
    image: ghcr.io/linuxserver/sonarr:latest
    container_name: sonarr
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Sonarr:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  radarr:
    image: ghcr.io/linuxserver/radarr:latest
    container_name: radarr
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Radarr:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  bazarr:
    image: ghcr.io/linuxserver/bazarr:latest
    container_name: bazarr
    restart: unless-stopped
    network_mode: "service:gluetun"
    environment:
      - TZ=${TZ}
      - PUID=${PUID}
      - PGID=${PGID}
    volumes:
      - /home/donkey/EmuleVision/media/movies:/movies
      - /home/donkey/EmuleVision/media/tv:/tv
      - /home/donkey/EmuleVision/Settings/Bazarr:/config
    depends_on:
      gluetun:
        condition: service_healthy

  kaizoku:
    image: ghcr.io/oae/kaizoku:latest
    container_name: kaizoku
    network_mode: "service:gluetun"
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - KAIZOKU_PORT=3002
    volumes:
      - /home/donkey/EmuleVision/Settings/Kaizoku:/config
      - /home/donkey/EmuleVision:/data
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  overseerr:
    image: lscr.io/linuxserver/overseerr:latest
    container_name: overseerr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    ports:
      - "5055:5055"
    volumes:
      - /home/donkey/EmuleVision/Settings/Overseerr:/config
    restart: unless-stopped

  adguardhome:
    image: adguard/adguardhome
    container_name: adguardhome
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "3001:3000"
    volumes:
      - /home/donkey/EmuleVision/Settings/AdGuard/work:/opt/adguardhome/work
      - /home/donkey/EmuleVision/Settings/AdGuard/conf:/opt/adguardhome/conf
    restart: unless-stopped

  calibre-web:
    image: lscr.io/linuxserver/calibre-web:latest
    container_name: calibre-web
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/CalibreWeb:/config
      - /home/donkey/EmuleVision/books:/books
    ports:
      - "8083:8083"
    restart: unless-stopped

  kavita:
    image: jvmilazz0/kavita:latest
    container_name: kavita
    environment:
      - TZ=${TZ}
    volumes:
      - /home/donkey/EmuleVision/Settings/Kavita:/kavita/config
      - /home/donkey/EmuleVision/media/manga:/manga
      - /home/donkey/EmuleVision/media/comics:/comics
    ports:
      - "5000:5000"
    restart: unless-stopped

  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
    volumes:
      - /home/donkey/EmuleVision/Settings/Filebrowser/filebrowser.db:/database.db
      - /home/donkey/EmuleVision/Settings/Filebrowser/.filebrowser.json:/.filebrowser.json
      - /home/donkey/EmuleVision:/srv
    ports:
      - "8082:80"
    restart: unless-stopped

  portainer:
    image: portainer/portainer-ce:2.20.2
    container_name: portainer
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock
      - /home/donkey/EmuleVision/Settings/Portainer:/data
    ports:
      - "9000:9000"
    restart: unless-stopped

  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    volumes:
      - /home/donkey/EmuleVision/Settings/Homepage:/app/config
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - HOMEPAGE_ALLOWED_HOSTS=*
    ports:
      - "3000:3000"
    restart: unless-stopped

  scrutiny:
    image: ghcr.io/analogj/scrutiny:master-omnibus
    container_name: scrutiny
    cap_add:
      - SYS_RAWIO
    devices:
      - /dev/sda:/dev/sda
    volumes:
      - /run/udev:/run/udev:ro
      - /home/donkey/EmuleVision/Settings/Scrutiny:/opt/scrutiny/config
      - /home/donkey/EmuleVision/Settings/Scrutiny/influxdb:/opt/scrutiny/influxdb
    ports:
      - "8086:8080"
    restart: unless-stopped

  plex:
    image: lscr.io/linuxserver/plex:latest
    container_name: plex
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
      - VERSION=docker
      - PLEX_CLAIM=
    network_mode: host
    volumes:
      - /home/donkey/EmuleVision/Settings/Plex:/config
      - /home/donkey/EmuleVision/media/movies:/data/movies
      - /home/donkey/EmuleVision/media/tv:/data/tvshows
    devices:
      - /dev/dri:/dev/dri

Checklist para a Primeira Inicialização

Após executar docker compose up -d, aqui está a sequência de inicialização:

  1. Aguarde o Gluetun - Verifique os logs: docker logs gluetun

    • Procure por “VPN connection successful”
    • Verifique o IP: docker exec gluetun curl ifconfig.me
  2. Configure o Prowlarr (porta 9696)

    • Adicione indexadores
    • Conecte ao Sonarr/Radarr via chaves de API
    • Teste o FlareSolverr se estiver usando indexadores protegidos
  3. Configure o qBittorrent (porta 8080)

    • Altere a senha padrão
    • Defina o caminho de download: /data/downloads/torrents
    • Adicione categorias: tv, movies
    • Siga os TRaSH Guides
  4. Configure o Sonarr (porta 8989)

    • Adicione o Prowlarr como indexador
    • Adicione o qBittorrent como cliente de download (localhost:8080)
    • Defina a pasta raiz: /data/media/tv
    • Importe perfis de qualidade dos TRaSH Guides
  5. Configure o Radarr (porta 7878)

    • Igual ao Sonarr, mas com pasta raiz: /data/media/movies
  6. Configure o Bazarr (porta 6767)

    • Conecte ao Sonarr/Radarr
    • Adicione provedores de legendas (OpenSubtitles, Subscene)
    • Defina idiomas preferidos
  7. Configure o Jellyfin (porta 8096)

    • Adicione bibliotecas: Filmes (/data/movies), Séries de TV (/data/tvshows)
    • Habilite Aceleração por Hardware (Intel QuickSync)
    • Crie contas de usuário
  8. Configure o Overseerr (porta 5055)

    • Conecte ao Jellyfin
    • Conecte ao Sonarr/Radarr
    • Habilite solicitações de usuários

Dicas de Otimização de Desempenho

Gerenciamento de Armazenamento

Como estamos trabalhando com um SSD de 512GB, o gerenciamento de espaço é crítico:

  1. Habilite exclusão automática no Sonarr/Radarr após X dias
  2. Defina limites de qualidade - Não baixe remuxes de 80GB a menos que realmente precise deles
  3. Monitore o uso do disco via Homepage ou Scrutiny
  4. Limpeza regular - Remova conteúdo assistido que você não vai reassistir

Otimização de Rede

  1. Encaminhamento de portas - Encaminhe a porta 6881 na sua VPN para maximizar as velocidades de download
  2. WiFi 5GHz para a TV Box - Como discutido no post sobre hardware, WiFi AC > Ethernet 100Mbps para streaming 4K
  3. Direct Play em vez de Transcoding - Configure os clientes do Jellyfin para suportar seus formatos de arquivo nativamente

Reforço de Segurança

  1. Altere todas as senhas padrão
  2. Desative o acesso remoto a menos que seja absolutamente necessário
  3. Mantenha as credenciais de VPN do Gluetun no .env - Nunca as codifique diretamente
  4. Atualizações regulares - Execute docker compose pull && docker compose up -d mensalmente

Solução de Problemas Comuns

“qBittorrent não inicia”

  • Verifique os logs do Gluetun: docker logs gluetun
  • Confirme as credenciais de VPN no .env
  • Certifique-se de que o healthcheck está passando: docker inspect gluetun | grep Health

“Sonarr/Radarr não consegue alcançar o qBittorrent”

  • Eles compartilham a rede do Gluetun, use localhost:8080
  • Não use nomes de contêineres ou IPs
  • Verifique as regras de firewall na configuração do Gluetun

“A transcodificação do Jellyfin está lenta”

  • Verifique se a aceleração por hardware está habilitada
  • Confirme se /dev/dri está montado corretamente
  • Instale intel-media-va-driver-non-free no host

“As legendas não estão sendo baixadas”

  • Verifique os logs do Bazarr para problemas com provedores
  • Confirme se as chaves de API estão corretas
  • Alguns provedores limitam a taxa; aguarde e tente novamente
  • Todos os contêineres devem mapear o mesmo volume raiz (/data)
  • Downloads e mídia devem estar no mesmo sistema de arquivos
  • Verifique a propriedade dos arquivos (PUID/PGID)

E Agora?

Agora temos um servidor doméstico totalmente funcional que rivaliza com qualquer serviço de streaming. Mas isso é apenas a fundação. Em posts futuros, abordarei:

  • Automação Avançada: Scripts personalizados para exclusão, notificações e manutenção
  • Acesso Remoto: Expondo seu servidor com segurança via Tailscale ou Cloudflare Tunnels
  • Otimização 4K: Mapeamento de tons HDR, perfis de qualidade específicos e gerenciamento de largura de banda
  • Estratégias de Backup: Protegendo sua configuração e mídia
  • Gerenciamento Multi-Usuário: Bibliotecas separadas, restrições de visualização e cotas de largura de banda
  • Integração com Trakt/IMDb: Sincronização automática de listas de observação
  • Personalização Avançada do Jellyfin: Plugins, temas e configurações específicas do cliente

A beleza deste sistema é que ele é modular. Você pode adicionar ou remover serviços conforme necessário. Não se importa com mangá? Remova o Kaizoku. Quer adicionar gerenciamento de música? Adicione o Lidarr. A arquitetura escala com suas necessidades.

Você transformou um mini PC barato em uma infraestrutura de nível empresarial. Você assumiu o controle do seu consumo de mídia, tirando-o das corporações que cobram mais por menos. E você aprendeu os fundamentos de conteinerização, rede e arquitetura de sistemas no caminho.

Vitória!

O servidor está construído. A stack está completa. Agora vá em frente e adquira (legalmente, é claro) o conteúdo que você realmente quer assistir.

Nos vemos no próximo post.