Blog do Guilherme

ZFS em casa: dicas para servidores domésticos com o TrueNAS Community Edition

A filosofia Unix sempre pregou: "faça uma coisa e faça-a bem". Embora nos últimos anos o TrueNAS tenha expandido seu escopo com suporte a apps Docker e recursos de virtualização, seu principal propósito continua sendo o armazenamento de dados. É justamente esse foco que faz do TrueNAS uma referência em desempenho, confiabilidade e segurança para quem busca uma plataforma robusta baseada em ZFS.

Também uso o TrueNAS profissionalmente, mas aqui vou tentar documentar a minha experiência com o TrueNAS Community Edition em um ambiente doméstico/homelab. Para referência, a versão que estou usando é a 26.0.0-BETA.2.

Sumário

Hardware

O meu NAS não tem nenhum hardware sofisticado, mas é mais do que suficiente para o que se propõe: armazenar/servir meus arquivos com segurança e fornecer alguns apps Docker. Não é necessário gastar tubos de dinheiro em racks e hardware específicos de servidores para se ter um servidor doméstico confiável.

Recentemente, fiz um upgrade no meu PC e aproveitei as peças que sobraram. Só precisei comprar um novo gabinete e alguns discos a mais. Mas as especificações do NAS são basicamente essas:

Componente Modelo/Especificação
Gabinete Montech Air 903 Base
Placa-mãe MSI MPG Z390 Gaming Pro Carbon
Processador Intel Core i5-9600K
Memória RAM 32 GB DDR4 (2 x 16 GB)
Fonte Corsair RM750i

O gabinete possui um visual sóbrio e bem acabado, painel lateral em vidro temperado, ótimo custo-benefício, é espaçoso... e com um "extra" difícil de se encontrar hoje em dia: nada de RGB. Ao todo, cabem 5 SSDs e 2 HDDs nele.

A placa-mãe suporta simultaneamente até 7 discos, sendo 1 NVMe e 6 SATA 3. Ideal para o layout que vou apresentar nas próximas seções.

A memória não é ECC. Existe bastante discussão na comunidade sobre esse assunto. Mas a conclusão a que cheguei, com base em quem entende do assunto, é que isso não é algo essencial em um NAS doméstico. O ECC oferece uma proteção adicional e tem seu valor, principalmente em ambientes críticos, mas o conjunto de recursos nativos do ZFS (checksums, scrubs, mecanismos pra detectar corrupção de dados etc.) já oferece uma importante camada de segurança para os dados.

Até mesmo um dos cofundadores do ZFS já comentou sobre esse tema, reforçando que a relação entre ZFS e memória ECC muitas vezes é tratada de forma muito simplificada.

E não uso placa de vídeo dedicada no servidor. Primeiro, não pretendo rodar nenhum LLM. Segundo, para eventual transcodificação de mídia via Jellyfin, o processador i5-9600K já dá conta do recado.

Para quem não sabe, a transcodificação acontece quando o cliente/dispositivo que reproduz o conteúdo não é compatível com o arquivo original ou quando é necessário reduzir o consumo de dados, fazendo com que o servidor converta o vídeo em tempo real. Nesses casos, o i5-9600K já atende muito bem graças ao Quick Sync Video (QSV), que acelera a conversão por hardware usando a GPU integrada do processador, dispensando uma placa de vídeo dedicada. Essa escolha mantém o NAS mais simples e eficiente. Em último caso, vale a pena ler a página de hardware recomendado pelo Jellyfin.

Discos

Disco Modelo Quantidade Capacidade de cada disco
SSD (NVMe M.2) WD Green SN350 1 250 GB
SSD (SATA 3) Kingston A400 4 480 GB
HDD (SATA 3) Seagate IronWolf 2 8 TB

O SSD NVMe serve exclusivamente para a instalação do TrueNAS. É nele que fica o boot-pool. Não é preciso redundância, já que ele armazena somente o sistema e os arquivos necessários para inicialização e funcionamento do próprio TrueNAS. Em caso de falha, a reinstalação do sistema e a restauração da configuração são procedimentos relativamente simples, enquanto os dados importantes permanecem protegidos nos pools ZFS dedicados ao armazenamento.

Caso o boot-pool estrague, basta substituir o SSD NVMe e reinstalar o TrueNAS nele, importando o arquivo de configuração que, no meu caso, não chega a 1 MB. Tudo será restaurado, bastando reimportar os pools criados anteriormente, sem perda de dados.

Os SSDs SATA 3 são usados para documentos/mídias pessoais, apps Docker (e alguns de seus bancos de dados), rotinas de sincronização via Syncthing e armazenamento de gravações de câmeras de segurança gerenciadas via Kerberos.

Por último, nos HDDs são armazenados backups, mídias do Jellyfin e torrents... de, claro, ISOs de distribuições Linux. 😇️

Pools

Para simplificar o layout e a gestão dos discos, optei por apenas dois pools: flash (SSDs) e tank (HDDs). No pool flash, considerando redundância e 4 SSDs de 480 GB, havia algumas opções:

Layout ZFS
(equivalente em RAID)
Organização Capacidade útil Tolerância a falhas
Stripe of mirrors
(RAID 10)
(SSD1↔SSD2) + (SSD3↔SSD4) 50%
(960 GB)
Até 2 (desde que não sejam do mesmo par)
RAIDZ1
(RAID 5)
SSD1 + SSD2 + SSD3 + paridade 75%
(1,44 TB)
1 SSD
RAIDZ2
(RAID 6)
SSD1 + SSD2 + paridade dupla 50%
(960 GB)
2 SSDs

Stripe of mirrors (RAID 10) acaba sendo a melhor opção por apresentar:

Para o pool tank, com 2 HDDs, não havia opção a não ser um mirror (RAID 1).

Resumindo tudo:

Pool Discos Tamanho total Capacidade útil Tolerância a falhas
flash 4 x 480 GB 1,92 TB 960 GB Até 2 SSDs (desde que não sejam do mesmo par)
tank 2 x 8 TB 16 TB 8 TB 1 HDD

Datasets e permissões

Por padrão, os datasets criados utilizam permissões POSIX, tradicionais dos sistemas Unix. Eu, no entanto, prefiro adotar quase sempre as ACLs NFSv4. Elas oferecem um gerenciamento muito mais simples e flexível para o compartilhamento de arquivos, além de serem mais indicadas para ambientes mistos (Linux, macOS e Windows). Recomendo fortemente a leitura da documentação oficial do TrueNAS sobre o tema.

E existem 4 presets para datasets no TrueNAS: generic, multiprotocol, SMB e apps. Via de regra, uso generic para todos os datasets (maior compatibilidade para NFS e SMB), com exceção dos datasets de apps, em que uso o preset apps.

Só que há exceções dentro das exceções. O Immich, por exemplo, pede que o dataset do seu banco de dados seja configurado com o preset generic para que ele mesmo gerencie as permissões posteriormente. É sempre importante ler as documentações dos apps e do TrueNAS, e analisar caso a caso.

Começando pelos datasets do pool flash:

flash/
├── apps/
│   ├── filebrowser
│   ├── glance
│   ├── immich/
│   │   ├── data
│   │   └── pgData
│   ├── jellyfin/
│   │   ├── cache
│   │   └── config
│   ├── kerberos
│   ├── nginx/
│   │   ├── certs
│   │   └── data
│   ├── qbittorrent
│   ├── qui
│   ├── scrutiny/
│   │   ├── config
│   │   └── influxdb
│   ├── syncthing
│   ├── speedtest-tracker
│   ├── tailscale
│   └── uptime-kuma
├── personal/
└── syncthing/

Observe que prefiro criar datasets separados para cada app Docker, o que garante maior granularidade de configurações, permissões, record sizes etc.

O dataset syncthing possui pastas individuais sincronizadas com os celulares da família. Isso garante que as fotos tiradas por eles não sejam perdidas, mesmo que algum aparelho estrague. Não uso Google Photos ou Google One para backup de fotos.

E os datasets do pool tank:

tank/
├── backups
├── data
└── sharing

Nesse pool, o dataset data é o mais importante. Eu costumo organizá-lo em 2 pastas principais: downloads e library. Inspirado pelo TRaSH Guides, seguindo esse padrão:

data/
├── downloads/
│   ├── complete/
│   │   ├── trackerx/
│   │   ├── trackery/
│   │   └── trackerz/
│   └── incomplete/
└── library/
    ├── movies/
    ├── music/
    └── series/

Mas por que, nesse caso, não usar datasets ao invés de pastas? O motivo é simples: hardlinks. Fazer hardlinks não é possível em datasets distintos, mesmo que estejam no mesmo pool. As mídias baixadas continuam sendo semeadas por um bom tempo no qBittorrent, com sua estrutura padrão e nomes originais dos trackers, dentro da pasta downloads/complete/trackerx. E o hardlink é feito para as pastas library/movies, library/music e library/series, usando o FileBot. A licença vitalícia do programa é cara, mas vale cada centavo. O FileBot facilita demais a padronização dos nomes das mídias, essencial para quem tem TOC de organização.

Em suma, um filme baixado em downloads/complete/trackerx é hardlinkado instantaneamente para a pasta library/movies, só que com o nome do arquivo "higienizado". Dois arquivos com nomes diferentes, mas ocupando o espaço de um só arquivo.

Apps Docker

Vou citar aqui somente os apps que considero essenciais para a minha rotina:

Proxy reverso e certificados SSL

Imagem Está cansado de sempre se deparar com a tela acima ao tentar acessar serviços self-hosted? Proxy reverso e certificados SSL são a solução. Siga o passo-a-passo deste vídeo para saber como configurar o Nginx Proxy Manager e ter certificados SSL gratuitos (via Let's Encrypt).

Para evitar conflitos, recomendo trocar a porta padrão para acesso (HTTPS) ao TrueNAS de 443 para 444. Desta forma, o Nginx Proxy Manager fica com a porta padrão do protocolo HTTPS (443), tornando a solução mais elegante. Após as configurações, daqui em diante, os seus serviços poderão ser acessados, por exemplo, via https://immich.seudominio.com e https://jellyfin.seudominio.com ao invés de https://ip-do-truenas:30041 ou https://ip-do-truenas:8096. Sem precisar lembrar de IPs e portas, além de nunca mais ficar vendo aqueles avisos dos navegadores. O Nginx Proxy Manager também fica responsável pela renovação automática dos certificados SSL.

O vídeo indicado ensina como configurar o proxy reverso utilizando um subdomínio do DuckDNS, um serviço gratuito de DNS dinâmico. Mas também é possível utilizar domínios próprios. Uma opção barata são os domínios .xyz, que custam a partir de US$ 1 por ano.

Para não precisar expor seus serviços fora da sua rede interna, é possível configurar reescritas de DNS no seu próprio roteador, via AdGuard Home ou Pi-hole. Com isso, seudominio.com passará a resolver para um IP interno que só a sua rede enxergará, sem precisar configurar A records públicos para o domínio. Com o Tailscale, também dá para especificar um servidor DNS específico para domínios específicos, o que permite continuar resolvendo o seu domínio mesmo não estando em casa.

Segurança dos dados

Por aqui, sigo a regra de backup 3-2-1. Os datasets do pool flash diariamente são:

Os datasets também são copiados via Duplicati, com criptografia, para um HD externo, que não fica em casa. Tento fazer essa cópia ao menos uma vez a cada três meses.

Automaticamente, são feitos scrubs mensais nos pools e snapshots diários dos datasets. Uso o scrutiny para monitoramento SMART periódico dos discos.

E não se esqueça de testar a restauração dos seus backups de vez em quando. Não adianta nada ter 3 backups se, quando você precisar, nenhum deles funcionar.

Outras dicas

#homelab #linux #self-hosted #software