SSD Nodes Learn 🎉 VPS desde $5.50/mês
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-13

Jails do FreeBSD vs contêineres Docker: diferenças

Compare jails do FreeBSD e contêineres Docker: userland completo contra imagens em camadas, além de diferenças em software, estado, rede e limites.

Jails do FreeBSD vs contêineres Docker, em um parágrafo

Os jails do FreeBSD e os contêineres Docker resolvem o mesmo problema de duas formas diferentes. Ambos executam userlands isolados num kernel partilhado, por isso nenhum deles é uma máquina virtual. A diferença está no que é executado dentro deles. Um contêiner Docker executa um processo a partir de uma imagem em camadas obtida de um registry. Um jail executa um userland FreeBSD completo: o seu próprio /etc, os seus próprios scripts de arranque rc, a sua própria base de dados pkg e tantos processos quantos forem necessários. Quase todas as outras diferenças desta página resultam dessa única característica.

A SSD Nodes não oferece imagens FreeBSD. Não é possível alugar um servidor FreeBSD nesta plataforma, e nada do que vem a seguir é um guia de instalação para uma máquina que possa comprar aqui. Esta é uma comparação entre dois modelos de isolamento, escrita para que possa identificar qual deles uma carga de trabalho realmente requer e ler a configuração de uma equipa FreeBSD sem ter de fazer suposições.

O que é realmente um jail

Os jails chegaram ao FreeBSD 4.0 em março de 2000, o que os torna mais antigos do que os cgroups e aproximadamente uma década mais antigos do que o Docker. O mecanismo consiste numa chamada ao kernel. jail(8) recebe uma árvore de diretórios e inicia processos dentro dela com um ID de jail associado. O kernel recusa então um conjunto fixo de operações a qualquer processo que tenha esse ID. Um processo num jail não consegue ver processos fora do seu jail, montar ou desmontar sistemas de ficheiros, carregar módulos do kernel nem associar-se a endereços de rede que não tenham sido atribuídos ao jail. Não existe outro tipo de namespace para aprender nem ativação opcional por funcionalidade. As restrições são aplicadas como uma unidade e ajustadas pelos parâmetros da configuração do jail.

No host, jls lista os jails em execução e jexec web sh abre uma shell dentro do jail chamado web.

Para criar um jail, coloque um userland do FreeBSD num diretório. O sistema base faz isso por si:

sudo bsdinstall jail /usr/local/jails/containers/web

Esse comando obtém o conjunto de distribuição base correspondente à sua release e executa os passos normais pós-instalação. Assim, define uma palavra-passe de root e escolhe um fuso horário exatamente como faria num servidor novo. O resultado é uma instalação do FreeBSD armazenada numa pasta. Em seguida, descreva-a em /etc/jail.conf:

web {
  host.hostname = "web.example.internal";
  path = "/usr/local/jails/containers/web";
  ip4.addr = "10.0.0.10";
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  mount.devfs;
}

Inicie-a e verifique o estado:

sudo service jail start web
jls

jls deve agora listar web com um JID, o hostname e o respetivo endereço IP. Se o jail não aparecer, execute sudo jail -c web diretamente. Esse comando aplica a mesma configuração em primeiro plano e mostra o parâmetro que não conseguiu aceitar, em vez de deixar a falha apenas na saída do serviço.

A linha que vale a pena ler duas vezes é exec.start = "/bin/sh /etc/rc". Iniciar um jail executa o script de boot normal do FreeBSD dentro dele. Assim, o jail inicia todos os serviços ativados no seu próprio /etc/rc.conf. Um contentor Docker não tem um passo equivalente, porque executa o processo entrypoint da imagem e para quando esse processo termina.

Como obter software: imagens e registos versus um userland que preenche

Esta é a diferença que se sente logo no primeiro dia.

Com Docker, indica o software e recebe-o. docker pull nginx obtém uma imagem em camadas, endereçada por conteúdo, que outra pessoa criou e testou, e docker compose up -d inicia-a com os volumes e a rede associados. O registo é o produto. Grande parte do valor de um fluxo de trabalho Docker está no facto de milhares de projetos publicarem imagens funcionais. É isso que torna executar Docker numa VPS uma tarefa curta, e não um projeto.

O FreeBSD não fornece um registo público predefinido de imagens de jail. Cria um userland vazio e instala o software nele, da mesma forma que configuraria um servidor básico. Isto exige mais comandos. Também é mais transparente, porque o que é executado na jail é aquilo que pkg instalou, a partir do mesmo conjunto de pacotes usado pelo host.

As ferramentas tornam o processo mais curto. BastilleBSD é o gestor de jail mais comum e é um pacote:

sudo pkg install bastille
sudo sysrc bastille_enable=YES
sudo bastille setup
sudo bastille bootstrap 15.1-RELEASE

bastille setup configura a rede, o armazenamento e a firewall por si. bastille bootstrap descarrega uma release uma vez, e todas as jails criadas depois reutilizam-na. FreeBSD 15.1 é a release atual para produção, disponibilizada em June 2026; substitua-a pela release que utiliza.

Criar uma jail requer então um comando, e preenchê-la requer mais um:

sudo bastille create web 15.1-RELEASE 10.17.89.10/24
sudo bastille pkg web install nginx
sudo bastille service web nginx start
sudo bastille console web

bastille console web fornece uma shell de login dentro da jail, e bastille list mostra o que existe no host. Para repetir uma compilação, os templates do Bastille guardam os passos num ficheiro e aplicam-nos a uma jail. É o equivalente mais próximo de um Dockerfile neste contexto. Um template é reaplicado em cada jail. Nada é fornecido previamente compilado.

O resumo correto é simples. O Docker fornece compilações de outras pessoas. As jails fornecem as suas próprias instalações. Se o software da sua lista existir como imagem de contentor e não de outra forma, a questão fica decidida antes de qualquer outro critério.

Estado e atualizações: a parte que o ZFS altera

O Docker separa o estado de propósito. O sistema de ficheiros do contentor é descartável, os seus dados ficam num volume nomeado ou numa montagem bind, e uma atualização é docker compose pull seguida de docker compose up -d. O contentor é substituído e tudo o que não tiver colocado num volume é perdido. Isto é uma vantagem quando segue a regra e um incidente de perda de dados quando se esquece dela. Por isso, a escolha entre montagens bind e volumes nomeados é tão importante numa stack do Compose.

Uma jail não separa o estado, e o ZFS é o motivo pelo qual isso funciona. A jail inteira é um dataset:

sudo zfs snapshot zroot/jails/containers/web@pre-upgrade
sudo pkg -j web upgrade
sudo zfs rollback zroot/jails/containers/web@pre-upgrade

Confirme o nome real do dataset com zfs list antes de executar isto. O caminho acima corresponde à disposição usada no handbook. O snapshot demora cerca de um segundo e ocupa quase nenhum espaço até o conteúdo da jail mudar. Se a atualização interromper o funcionamento do serviço, o rollback repõe todo o userland no estado anterior, incluindo a base de dados de pacotes e os ficheiros de configuração que editou manualmente às 2 da manhã. O Docker não tem um equivalente integrado, porque o seu modelo pressupõe que nunca precisou de um.

zfs clone é a outra parte. Um clone de um snapshot é uma nova jail com escrita que partilha com a jail-pai os blocos que não foram alterados. Assim, uma cópia de staging de uma jail de 3 GB ocupa quase nenhum espaço em disco até começar a alterá-la. É assim que um administrador de FreeBSD cria uma jail "igual à produção" para ensaiar uma atualização.

A atualização do sistema base é separada da atualização dos pacotes. Numa jail que contém a sua própria cópia do userland:

sudo freebsd-update -b /usr/local/jails/containers/web fetch install

As jails thin evitam repetir esse trabalho. Montam uma base partilhada, apenas para leitura, através de nullfs e atribuem a cada jail a sua própria camada pequena com escrita. Assim, aplica o patch à base uma vez e todas as jails veem o resultado. O Bastille cria jails thin por predefinição.

Rede: portas publicadas vs. decisão de endereçamento

O Docker decide a rede por si e pede-lhe que publique as exceções. Os contentores ficam numa bridge, comunicam entre si pelo nome do serviço numa rede definida pelo utilizador, e -p 8080:80 expõe um deles ao host. O Docker escreve as suas próprias regras de filtragem de pacotes para fazer isso, que é também o motivo pelo qual uma porta de contentor publicada passa diretamente pelo ufw.

Uma jail obriga-o a escolher o modelo à partida, e existem dois.

IP partilhado. ip4.addr = "10.0.0.10" adiciona esse endereço a uma interface existente do host e restringe a jail a esse endereço. A jail não tem uma stack de rede própria, pelo que não pode executar a sua própria firewall. Também não pode realmente fazer bind a todos os endereços: um socket numa jail que peça 0.0.0.0 é reescrito pelo kernel para o endereço próprio da jail. Duas jails não podem escutar na porta 80 do mesmo endereço, pelo que atribui um endereço a cada uma ou coloca um reverse proxy à frente.

VNET. Adicione vnet; à jail e ela obtém uma stack de rede completa: interfaces próprias, tabela de routing própria e regras de firewall próprias. Ligue-a ao host com um epair, um cabo virtual com uma extremidade de cada lado, e coloque a extremidade do host numa bridge. Este é o equivalente mais próximo do que o Docker fornece e é o modo usado pelos tipos de jail -V e -B do Bastille.

O encaminhamento de uma porta do host para uma jail é uma regra de redirect pf. O Bastille encapsula-a:

sudo bastille rdr web tcp 80 80

Não existe EXPOSE nem publicação automática. Nada chega a uma jail a menos que o seu endereço ou uma regra de redirect o permita. O arranque é mais lento e a firewall é muito mais silenciosa.

Limites de recursos: cgroups vs rctl

O Docker limita um contentor com cgroups, e os limites ficam definidos no local onde o contentor é declarado: --memory=1g --cpus=1.5 na linha de comandos ou nas chaves correspondentes num ficheiro Compose. Se já mantiver a sua stack em um ficheiro Docker Compose num VPS, o limite fica junto do serviço a que se aplica e acompanha-o no git.

O FreeBSD usa rctl, que é um subsistema que tem de ativar. A contabilização de recursos está desativada por predefinição porque acrescenta um pequeno custo a cada alocação. Adicione o tunable a /boot/loader.conf e reinicie o sistema:

kern.racct.enable=1

Depois, defina uma regra e monitorize-a:

sudo rctl -a jail:web:vmemoryuse:deny=1g
rctl -hu jail:web

rctl -hu jail:web apresenta a utilização atual do jail em unidades legíveis, para que possa ver quão perto está do limite antes de algo falhar. A ação deny faz com que a alocação acima do limite falhe dentro do jail. Assim, vê o erro de alocação da própria aplicação, em vez de uma mensagem de kill no host.

As regras adicionadas com rctl -a desaparecem no próximo reboot. O serviço rctl do FreeBSD volta a carregá-las a partir de /etc/rctl.conf. Por isso, escreva a regra nesse ficheiro e ative o serviço:

sudo sysrc rctl_enable=YES

Este é o aspeto em que o Docker é claramente mais conveniente. Um limite num ficheiro Compose é revisto juntamente com o serviço que restringe. Uma regra rctl é uma linha num ficheiro separado que identifica um jail definido noutro local.

Quando a resposta é uma máquina virtual: bhyve

Um jail partilha o kernel do host, por isso algumas funcionalidades ficam permanentemente fora do seu alcance. Não pode executar uma versão diferente do kernel, carregar um módulo do kernel nem executar binários Linux da mesma forma que um contentor Linux. O FreeBSD tem uma camada de compatibilidade com Linux, o linuxulator, mas ela implementa apenas um subconjunto das chamadas de sistema Linux e não é uma solução geral para imagens Linux arbitrárias.

O bhyve é o hypervisor do FreeBSD e é a ferramenta adequada quando precisa de uma fronteira real entre máquinas: um sistema operativo diferente, um kernel diferente ou um tenant cujo kernel não quer partilhar. O custo é ter memória reservada em vez de partilhada e um segundo kernel para atualizar. Esta é a mesma decisão que toma no Linux entre contentores e máquinas virtuais completas. É também o fator que determina se precisa de um VPS que suporte virtualização aninhada por baixo.

O ecossistema, que é a razão real pela qual a maioria das equipas usa Docker

Tudo o que foi apresentado até aqui diz respeito ao modelo. Para a maioria das equipas, a escolha é determinada pela dimensão do ecossistema em torno de cada opção.

Docker inclui Docker Hub e GHCR, docker compose, Kubernetes quando uma única máquina deixa de ser suficiente, runners de CI com suporte para contentores já integrado e um quickstart de um comando no README de quase todos os projetos. As jails incluem a árvore de ports do FreeBSD, que é extensa e mantida com cuidado, além de um conjunto muito menor de pacotes de aplicações prontos para executar. Quando um projeto publica uma imagem de contentor e nada mais, a alternativa no FreeBSD é ler a documentação e montar as partes manualmente.

As jails justificam-se no outro lado dessa escolha. Use-as quando já executa ZFS e valoriza snapshots e rollback de um serviço completo, quando os seus serviços são nativos do FreeBSD, quando quer um userland completo por tenant em vez de um único processo ou quando quer que o kernel, o packet filter, o sistema de ficheiros e a documentação sejam mantidos em conjunto como um único sistema. É isto que as pessoas querem dizer quando descrevem o FreeBSD como coerente. Esse ponto é desenvolvido em a comparação mais ampla entre Linux e FreeBSD como plataformas de servidor e em as alterações do FreeBSD 15 para utilização em servidores.

Uma conclusão final. Se a sua equipa já conhece Docker, o custo da migração é real e os benefícios têm de ser específicos. Não mude pela qualidade do isolamento. Os dois modelos são suficientemente semelhantes para que a sua configuração tenha mais impacto. Mude porque quer rollback de serviços completos suportado por ZFS ou porque já utiliza FreeBSD.

FAQ

Posso executar imagens Docker no FreeBSD?

Não imagens Linux, e não como uma opção suportada. O FreeBSD tem suporte para contentores OCI: sudo pkg install -y podman-suite instala o Podman, que executa contentores através de ocijail, um runtime que cria jails reais por baixo. É necessário montar fdescfs em /dev/fd para o monitor de contentores e pf para o NAT de contentores (tradução de endereços de rede). As imagens OCI nativas do FreeBSD funcionam melhor. As imagens Linux também exigem a camada de compatibilidade Linux e, em agosto de 2026, o port do Podman para FreeBSD ainda é descrito como experimental. Se a sua implementação for composta por uma stack de imagens Linux, execute-a em Linux.

As jails do FreeBSD são mais seguras do que os contentores Docker?

Ambos partilham o kernel do host, por isso um erro no kernel representa um risco para ambos, e nenhum dos dois é a fronteira que escolheria para código genuinamente não confiável. A diferença está no ponto de partida. Uma jail começa com um conjunto amplo de operações recusadas, que são reativadas uma a uma por parâmetro. Um contentor Docker começa como root dentro de um conjunto de namespaces, com algumas capabilities removidas, e o reforço adicional é opcional. Na prática, a configuração é mais determinante do que o modelo: uma jail com allow.mount e allow.raw_sockets ativados não é mais segura do que um contentor configurado com cuidado.

Como faço backup de uma jail?

Crie um snapshot do dataset e envie-o. sudo zfs snapshot zroot/jails/containers/web@backup e depois zfs send esse snapshot para outro pool ou para um ficheiro que copie para fora do servidor. Como uma jail mantém todo o seu userland num único dataset, o snapshot captura os pacotes instalados e os dados num único ponto consistente, juntamente com todos os ficheiros de configuração que editou manualmente. Isto é o oposto do procedimento habitual com Docker, em que faz backup dos volumes nomeados e do ficheiro Compose e recria o restante a partir da imagem.

Preciso do BastilleBSD ou o sistema base é suficiente?

O sistema base é suficiente e é o melhor ponto de partida. jail.conf, jls, jexec e service jail start abrangem todo o modelo e, depois de os conhecer, pode ler qualquer host FreeBSD sem aprender primeiro as ferramentas desse host. O Bastille é uma camada de conveniência sobre o sistema base: inicializa releases, cria jails thin, aplica templates e escreve por si regras de redirecionamento pf. Aprenda primeiro os comandos base e adicione o Bastille quando o número de jails tornar a introdução manual dos comandos demasiado trabalhosa.