SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor · Atualizado 2026-08-24

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

Compare jails do FreeBSD e contêineres Docker: userland completo contra imagens em camadas, com diferenças práticas em software, estado, rede e limites.

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

As jails do FreeBSD e os contêineres Docker resolvem o mesmo problema de duas formas diferentes. Ambos executam userlands isolados sobre um único kernel partilhado, portanto 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. Uma jail executa um userland completo do FreeBSD: 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 do FreeBSD. Não é possível alugar um servidor FreeBSD nesta plataforma, e nada do que segue é um guia de instalação para uma máquina que possa ser adquirida aqui. Esta é uma comparação entre dois modelos de isolamento, escrita para que possa determinar qual deles corresponde às necessidades reais de uma carga de trabalho e interpretar a configuração de uma equipa que usa FreeBSD sem ter de fazer suposições.

O que é realmente um jail

Os jails surgiram no FreeBSD 4.0, em março de 2000, por isso são anteriores aos cgroups e aproximadamente uma década anteriores ao Docker. O mecanismo consiste numa chamada ao kernel. jail(8) recebe uma árvore de diretórios e inicia os processos dentro dela com um ID de jail associado. Depois, o kernel recusa um conjunto fixo de operações a qualquer processo que tenha esse ID. Um processo dentro de um 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 um tipo separado de namespace para aprender nem uma ativação específica para cada funcionalidade. As restrições são aplicadas como uma unidade e ajustadas por parâmetros na 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

Isto obtém o conjunto de distribuição base correspondente à sua release e executa os passos normais de 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. Depois, 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 respetivo hostname e o endereço IP. Se o jail não aparecer, execute sudo jail -c web diretamente. Este 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 deve ler duas vezes é exec.start = "/bin/sh /etc/rc". Iniciar um jail executa o script de arranque normal do FreeBSD dentro dele. Por isso, 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, identificada pelo conteúdo, que outra pessoa compilou e testou, e docker compose up -d inicia-a com os respetivos volumes e rede ligados. 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 dentro dele, 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 curto. BastilleBSD é o gestor de jail habitual 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 cada jail criada posteriormente reutiliza-a. 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 ecossistema. Um template é reproduzido em cada jail. Nada chega pré-compilado.

O resumo correto é curto. O Docker fornece compilações de outras pessoas. As jails fornecem as suas próprias instalações. Se o software que pretende utilizar for disponibilizado como imagem de contentor e não existir de outra forma, a decisão fica tomada antes de qualquer outro critério ser considerado.

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

O Docker separa o estado de forma intencional. O sistema de ficheiros do contentor é descartável, os seus dados ficam num volume nomeado ou num bind mount, e uma atualização consiste em 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 funcionalidade quando segue a regra e um incidente de perda de dados quando se esquece dela. Por isso, a escolha entre bind mounts e volumes nomeados é tão importante numa stack do Compose.

Um jail não separa o estado, e o ZFS é o motivo pelo qual isso funciona. O jail inteiro é 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 à estrutura usada no manual. O snapshot demora cerca de um segundo e ocupa quase nenhum espaço até o conteúdo do jail mudar. Se a atualização danificar o 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 dessa funcionalidade.

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

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

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

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

Rede: portas publicadas versus uma decisão de endereçamento

O Docker decide a configuração de rede por si e pede 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 publicada de um contentor passa diretamente pelo ufw.

Uma jail obriga-o a escolher o modelo antecipadamente, 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 a sua própria pilha de rede, pelo que não pode executar a sua própria firewall. Também não pode efetivamente associar-se a todos os endereços: um socket numa jail que peça 0.0.0.0 é reescrito pelo kernel para o endereço da própria jail. Duas jails não podem escutar ambas na porta 80 do mesmo endereço. Por isso, atribui um endereço a cada uma ou coloca um reverse proxy à frente.

VNET. Adicione vnet; à jail e ela obterá uma pilha de rede completa: interfaces próprias, tabela de encaminhamento 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. Esta é a correspondência mais próxima do que o Docker fornece e é o modo utilizado pelos tipos de jail -V e -B do Bastille.

O encaminhamento de uma porta do host para uma jail é uma regra de redirecionamento pf. O Bastille fornece uma camada de configuração para isso:

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 respetivo endereço ou uma regra de redirecionamento o permita. Isto proporciona um arranque mais lento e uma 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 é configurado: --memory=1g --cpus=1.5 na linha de comandos ou as chaves correspondentes num ficheiro Compose. Se já mantém a sua stack num 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:

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 o uso atual do jail em unidades legíveis, para que possa ver quão próximo está do limite antes de ocorrer uma falha. 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 reboot seguinte. O serviço rctl do FreeBSD recarrega-as a partir de /etc/rctl.conf. Por isso, escreva a regra nesse ficheiro e ative o serviço:

sudo sysrc rctl_enable=YES

É neste aspeto que o Docker é claramente mais conveniente. Um limite num ficheiro Compose é revisto junto do 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 separação real entre máquinas: um sistema operativo diferente, um kernel diferente ou um tenant cujo kernel prefere não partilhar. O custo inclui 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 que determina se precisa de um VPS que suporte virtualização aninhada por baixo.

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

Tudo o que foi apresentado acima diz respeito ao modelo. Para a maioria das equipas, o fator decisivo é a dimensão do ecossistema existente em torno de cada modelo.

O Docker disponibiliza o Docker Hub e o GHCR, docker compose, o 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. Os jails disponibilizam a árvore de ports do FreeBSD, que é extensa e mantida com cuidado, além de um conjunto muito menor de bundles de aplicações prontos a executar. Quando um projeto publica uma imagem de contentor e nada mais, no FreeBSD é necessário ler a documentação e montar os componentes manualmente.

Os jails justificam-se no outro lado dessa escolha. São adequados quando já utiliza ZFS e valoriza snapshots e rollback de um serviço inteiro, quando os seus serviços são nativos do FreeBSD, quando pretende 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. É a este último ponto que as pessoas se referem quando dizem que o FreeBSD é coerente. Esse tema é desenvolvido em a comparação mais ampla entre Linux e FreeBSD como plataformas de servidor e em o que o FreeBSD 15 mudou 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 próximos para que a configuração tenha mais importância. Mude porque pretende rollback de serviços inteiros suportado por ZFS ou porque já utiliza FreeBSD.

FAQ

Posso executar imagens Docker no FreeBSD?

Não imagens Linux, pelo menos não de forma suportada. O FreeBSD tem suporte para contentores OCI: sudo pkg install -y podman-suite instala o Podman, que executa os 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 usar 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, a port do Podman para FreeBSD continua descrita como experimental. Se a sua implementação for composta por uma stack de imagens Linux, execute-a em Linux. Na família RHEL, isso significa instalar o Docker no Rocky Linux ou AlmaLinux, onde o Podman surge novamente como o pacote que já fornece o comando docker antes de instalar qualquer outra coisa.

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

Ambos partilham o kernel do host. Por isso, um bug no kernel representa um risco para ambos. Nenhum dos dois é o limite de isolamento adequado para código genuinamente não confiável. A diferença está no ponto de partida. Uma jail começa por recusar um conjunto amplo de operações, 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 tem mais influência do que o modelo: uma jail com allow.mount e allow.raw_sockets ativados não é mais segura do que um contentor configurado cuidadosamente.

Como faço backup de uma jail?

Crie um snapshot do dataset e envie-o. sudo zfs snapshot zroot/jails/containers/web@backup e, em seguida, zfs send esse snapshot para outro pool ou para um ficheiro que possa copiar para fora do servidor. Como uma jail mantém todo o seu userland num único dataset, o snapshot inclui os pacotes instalados e os dados num ponto consistente, além de todos os ficheiros de configuração editados 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. Depois de os conhecer, pode administrar qualquer host FreeBSD sem ter de aprender primeiro as ferramentas específicas desse host. O Bastille é uma camada de conveniência sobre esse sistema: inicializa releases, cria jails thin, aplica templates e escreve regras de redirecionamento pf por si. Aprenda primeiro os comandos base. Depois, adicione o Bastille quando o número de jails tornar a introdução manual dos comandos demasiado trabalhosa.