SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

Como configurar contentores Incus numa VPS

Aprenda a configurar contentores de sistema Incus numa VPS, validar virtualizacao, criar storage pools e rede, alem de evitar falhas comuns.

O que é um contentor de sistema Incus

Os contentores de sistema Incus numa VPS fornecem uma máquina completa, com o seu próprio sistema init e as suas próprias contas de utilizador. Não fornecem apenas um processo com um sistema de ficheiros associado. O contentor arranca, executa um init como PID 1 e responde ao seu gestor de serviços. Esse gestor é systemctl em imagens com systemd, como Debian e Ubuntu, e rc-service em Alpine, que utiliza OpenRC. O contentor partilha o kernel do host, por isso não é uma máquina virtual. Tudo o que está acima do kernel comporta-se como uma máquina independente.

Incus é um fork comunitário do LXD, mantido no âmbito do projeto Linux Containers. O comando cliente é incus. Também executa máquinas virtuais reais através do QEMU quando é utilizada a opção --vm. No entanto, o contentor de sistema é a principal razão pela qual a maioria das pessoas instala o Incus, e é esse o modelo abrangido no restante deste guia.

Por que as comparações com Docker induzem em erro

O Docker empacota um processo. O Incus empacota um sistema operativo. A documentação do Incus estabelece diretamente esta distinção: "Os contentores de aplicações (fornecidos, por exemplo, pelo Docker) empacotam um único processo ou aplicação. Os contentores de sistema, por outro lado, simulam um sistema operativo completo, semelhante ao que seria executado num host ou numa máquina virtual."

Esta diferença altera a forma como utiliza o sistema no dia a dia.

  • Uma imagem Docker não tem init, por isso systemctl falha dentro dela. Um contentor Incus executa um sistema init, pelo que os serviços e os temporizadores funcionam como num servidor.
  • Um contentor Docker deve ser destruído e recriado a partir de um Dockerfile. Um contentor Incus deve ser mantido, atualizado e guardado em snapshots.
  • Uma imagem Docker é um artefacto de compilação que publica num registry. Uma instância Incus é estado armazenado num pool de armazenamento, e pode movê-la com incus export.
  • O Docker isola uma carga de trabalho. O Incus isola uma máquina, pelo que um contentor pode conter várias cargas de trabalho e várias contas de utilizador.

Pode executar Docker dentro de um contentor de sistema Incus. Não deve executar Incus dentro de um contentor de aplicação Docker. Se pretende realmente um processo por contentor, com uma etapa de compilação da imagem, leia primeiro a comparação Podman e Docker numa VPS. Se pretende um kernel separado por carga de trabalho, em vez de um kernel partilhado, consulte Firecracker microVMs numa VPS, que segue na direção oposta.

O Incus funciona dentro de um VPS?

Depende do tipo de virtualização e do kernel do VPS. Verifique ambos antes de instalar qualquer componente. Não confie apenas na página de marketing do fornecedor. Execute estes quatro comandos no servidor.

systemd-detect-virt
uname -r
stat -fc %T /sys/fs/cgroup
cat /sys/fs/cgroup/cgroup.controllers

A saída systemd-detect-virt, kvm ou qemu indica que o VPS é uma máquina virtual com kernel próprio. Este é o caso mais simples, porque o Incus funciona como funcionaria num servidor físico. A saída lxc, lxc-libvirt ou openvz indica que o próprio VPS é um contentor que partilha o kernel do fornecedor. Os contentores Incus executados nesse ambiente são contentores aninhados. O aninhamento só funciona se o fornecedor o tiver ativado para o seu contentor. Não é possível ativá-lo a partir do interior, porque essa configuração está no host, ao qual não tem acesso.

stat -fc %T /sys/fs/cgroup deve apresentar cgroup2fs. Qualquer outro resultado indica que o servidor usa uma configuração cgroup (control group) v1 ou híbrida, que o Incus atual não suporta como alvo.

cat /sys/fs/cgroup/cgroup.controllers apresenta os controladores de control groups delegados para o seu VPS. A documentação do Incus indica blkio, cpuset, devices, freezer, memory e pids como necessários. Num VPS aninhado, essa lista costuma ser mais curta do que num VPS KVM, porque o fornecedor escolheu quais controladores delegar. Um controlador ausente desse ficheiro é um controlador que o Incus não pode usar. Por isso, o limite de instâncias que depende dele não fica disponível.

A versão do kernel é mais importante do que era anteriormente. Em outubro de 2026, o projeto upstream mantém duas séries LTS (long term support), 6.0 e 7.0, além das versões atuais com novas funcionalidades, e elas não têm o mesmo requisito mínimo. A documentação da série 6.0 LTS indica: "A versão mínima de kernel suportada é 5.4." A documentação atual indica: "A versão mínima de kernel suportada é 6.12.", e o anúncio da versão 7.0 LTS, publicado em maio de 2026, inclui Linux 6.12 entre os requisitos mínimos. O mesmo anúncio colocou a série 6.0 LTS na fase de atualizações apenas de segurança. O Ubuntu 24.04 disponibiliza os pacotes da série 6.0 LTS no seu próprio repositório e combina-os com um kernel 6.8, uma combinação suportada. Instalar a versão stable ou 7.0 LTS do repositório upstream nesse mesmo kernel 6.8 deixa o sistema abaixo do mínimo documentado. Por isso, leia uname -r antes de escolher um repositório.

Se o objetivo for executar máquinas virtuais completas, a restrição é diferente e mais difícil de satisfazer. Consulte virtualização aninhada num VPS para saber se o seu VPS pode disponibilizar /dev/kvm, e Proxmox num VPS alugado para o caso em que o hardware é seu.

Instalar o Incus no Ubuntu ou Debian

O Debian 13 e o Ubuntu 24.04 e versões posteriores disponibilizam o Incus nos próprios repositórios.

sudo apt update
sudo apt install -y incus

No Debian, incus-base instala o suporte para contentores sem os componentes de máquinas virtuais. No Ubuntu, adicione qemu-system se também quiser instâncias --vm.

Para obter uma versão mais recente do que a disponibilizada pela sua distribuição, os pacotes upstream estão em pkgs.zabbly.com. Esse repositório disponibiliza os canais lts-6.0, lts-7.0 e stable. Os comandos abaixo, retirados do README do próprio repositório do projeto, usam stable. Substitua o nome do canal no nome do ficheiro e na linha URIs: se o kernel exigir uma série LTS.

sudo apt update && sudo apt install -y curl
sudo mkdir -p /etc/apt/keyrings/
sudo curl -fsSL https://pkgs.zabbly.com/key.asc -o /etc/apt/keyrings/zabbly.asc
sudo sh -c 'cat <<EOF > /etc/apt/sources.list.d/zabbly-incus-stable.sources
Enabled: yes
Types: deb
URIs: https://pkgs.zabbly.com/incus/stable
Suites: $(. /etc/os-release && echo ${VERSION_CODENAME})
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/zabbly.asc
EOF'
sudo apt-get update
sudo apt-get install -y incus

Em seguida, dê ao seu utilizador acesso ao socket do daemon.

sudo usermod -aG incus-admin "$USER"
newgrp incus-admin
incus info

incus info imprimir a configuração do servidor confirma que o socket funciona. Um erro de permissões significa que a alteração do grupo ainda não chegou à sua shell. newgrp incus-admin aplica a alteração à shell atual, enquanto um novo login a aplica corretamente. Considere a pertença a incus-admin equivalente a root no anfitrião, porque o acesso a esse socket dá controlo total sobre um daemon executado como root. Algumas distribuições também criam um grupo simples incus para acesso restrito dos utilizadores.

Agora inicialize o daemon.

sudo incus admin init

Responda às perguntas em vez de usar incus admin init --minimal. O caminho mínimo seleciona o driver de armazenamento dir, e a secção seguinte explica por que essa escolha continua a afetar a configuração.

Inicie algo e confirme que funciona.

incus launch images:debian/13 web
incus list
incus exec web -- bash

incus list deve mostrar web como RUNNING, com um endereço IPv4 na sub-rede incusbr0. A ausência de um endereço significa que o DHCP (protocolo de configuração dinâmica de anfitriões) não foi concluído. A secção sobre redes aborda esse problema. Um contentor que não consiga iniciar apresenta o motivo em incus info web --show-log, e as falhas ao nível do daemon aparecem em sudo journalctl -u incus -n 50. Numa VPS em que systemd-detect-virt devolveu lxc ou openvz, este arranque é o teste correto para confirmar se o nesting está disponível para si.

Por que o backend de armazenamento padrão é importante

O backend de armazenamento determina se um snapshot é instantâneo ou uma cópia completa do disco do container. É a única escolha feita durante a instalação que não pode ser alterada depois sem custos significativos.

O Incus suporta dir, btrfs, lvm, zfs, Ceph e vários drivers remotos. Num VPS com um único disco, a escolha real é entre dir e btrfs.

O driver dir mantém cada container como ficheiros e diretórios comuns em /var/lib/incus. A documentação do Incus descreve-o como "muito mais lento do que todos os outros drivers", porque tem de descompactar cada imagem e criar cópias reais, em vez de referenciar blocos partilhados. É o único driver na comparação de funcionalidades do Incus sem criação otimizada de snapshots. Por isso, num pool dir, um snapshot de um container de 4 GiB é uma cópia completa: escreve 4 GiB e demora tanto quanto copiar essa quantidade de dados. Em btrfs, lvm ou zfs, o mesmo snapshot é otimizado e não copia o disco inteiro. As quotas de disco funcionam apenas em ext4 ou XFS com quotas de projeto ativadas ao nível do sistema de ficheiros. Essa opção não está ativada por padrão na maioria das imagens de VPS. Por isso, um limite de disco num pool dir muitas vezes não tem efeito.

btrfs e zfs usam copy-on-write, por isso um snapshot regista apenas os blocos alterados depois da sua criação. O Incus identifica esses dois como os backends recomendados. Os snapshots tornam-se quase instantâneos. As quotas de disco usam o suporte de quotas do próprio sistema de ficheiros.

A maioria dos planos VPS fornece um único disco sem uma partição livre. Por isso, coloque o pool num ficheiro loop. O Incus faz isso automaticamente quando não fornece source=.

sudo apt install -y btrfs-progs
incus storage create fast btrfs size=30GiB
incus profile device set default root pool=fast
incus launch images:debian/13 web2 -s fast

Sem size=, um pool baseado em loop ocupa 20% do espaço livre em disco, com um mínimo de 5 GiB e um máximo de 30 GiB. Defina esse valor de forma explícita. O pool para quando atinge o seu próprio tamanho. Assim, pode ficar cheio enquanto o host ainda tem espaço livre. Essa é a forma habitual de um pool baseado em loop ficar sem espaço. O próprio ficheiro loop é um ficheiro no sistema de ficheiros do host. Por isso, dimensione o pool considerando também as necessidades do host, em vez de lhe atribuir todos os gigabytes livres.

No Debian e no Ubuntu, o ZFS é um módulo DKMS e não um módulo integrado no kernel. Por isso, é recompilado a cada atualização do kernel e essa compilação pode falhar. Num servidor que não é monitorizado diariamente, btrfs exige menos manutenção dos dois.

Os três modos de rede e o que cada um expõe

Quando aceita a resposta recomendada, incus admin init cria uma bridge gerida chamada incusbr0 e associa-a ao perfil default. Assim, cada nova instância que use esse perfil é ligada a essa bridge. Em alternativa, pode apontá-la para uma bridge ou interface existente. A bridge gerida é uma das três formas de ligar um container. As outras duas existem porque a primeira coloca os containers atrás de NAT (network address translation).

Bridge gerida. incusbr0 recebe uma sub-rede privada. O host mantém o primeiro endereço dessa sub-rede e funciona como gateway. O Incus executa DHCP e DNS (domain name system) nessa rede, e o tráfego de saída passa pelo endereço público do host com NAT de origem aplicado. Nada do exterior chega ao container até que defina uma regra para isso. Encaminhe uma porta com um dispositivo proxy.

incus config device add web http proxy listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80 nat=true

nat=true encaminha usando regras netfilter, em vez de passar por uma ligação separada no userspace. Assim, o endereço real do cliente permanece nos logs do container. O Incus suporta esse modo apenas quando o host é o gateway da instância. Esse é exatamente o caso incusbr0.

macvlan. O container recebe o seu próprio endereço MAC (media access control) na rede física do host. Na maioria das plataformas VPS, isso falha porque a porta do switch virtual está associada ao endereço MAC da VM e descarta frames de qualquer outro endereço. Existe uma segunda limitação que causa problemas mesmo quando o modo funciona. A documentação do Incus indica que "os dispositivos macvlan, embora consigam comunicar entre si e com o exterior, não conseguem comunicar com o dispositivo principal. Isto significa que não pode usar macvlan se precisar que as instâncias comuniquem com o próprio host."

Routed. Este é o modo que normalmente funciona num VPS com endereços adicionais. A documentação do Incus descreve o dispositivo como um que "cria um par de dispositivos virtuais para ligar o host à instância e configura rotas estáticas e entradas proxy ARP/NDP para permitir que a instância entre na rede de uma interface principal designada". ARP é o protocolo de resolução de endereços. O container mantém um endereço público. O host responde a ARP por esse endereço, por isso o fornecedor continua a ver apenas o endereço MAC do host.

incus config device add web eth0 nic nictype=routed parent=enp1s0 ipv4.address=203.0.113.20

Obtenha o nome da interface principal a partir de ip route show default no host. Esse nome vem do kernel e da imagem usados pelo seu VPS. Pode ser um nome previsível, como enp1s0 ou ens3, em vez de eth0. Por isso, consulte o nome em vez de o presumir. Dentro do container, o nome é diferente: a documentação do Incus indica que a interface de rede no perfil default "passa a ser eth0 na instância". Definir o nome do dispositivo como eth0 substitui o nome fornecido pelo perfil default. Assim, o container termina na interface routed, em vez de na bridge. Confirme o resultado a partir do interior do container com ip a e ip route.

Por que um contentor alcançou um serviço no host

Um contentor em incusbr0 tem o seu próprio namespace de rede. Isso não constitui uma fronteira de firewall contra o host. As regras de firewall adicionadas por uma bridge Incus gerida existem, nas palavras da documentação, "para garantir a funcionalidade completa", e não para isolar o host. O host está nessa bridge com o endereço de gateway. Por isso, a partir do contentor, o host é um vizinho diretamente acessível, e todos os serviços do host associados a 0.0.0.0 respondem nesse endereço, exceto se uma regra de firewall do host descartar os pacotes.

Verifique por si próprio. No host, liste o que está à escuta.

sudo ss -tlnp

Depois, a partir de um contentor, direcione o pedido para o gateway indicado por ip route.

ip route show default
nc -zv 10.0.0.1 6379

Se uma base de dados, um endpoint de métricas ou um painel de administração no host estiver associado a 0.0.0.0 e nenhuma regra de firewall do host bloquear a bridge, essa verificação será bem-sucedida. O firewall de rede do seu fornecedor nunca viu o pacote, porque o pacote nunca saiu da máquina. Esta é a explicação para a maioria das perguntas do tipo "como é que chegou ali": o contentor está isolado da Internet por NAT e só está isolado do host pelas regras aplicadas pelo firewall do host.

Associe os serviços do host a 127.0.0.1 sempre que possível. Depois, filtre a bridge no host. Num sistema com ufw, a política padrão de negação já bloqueia o tráfego do contentor para o host. Isso interrompe o DNS e o DHCP do Incus. A correção indicada na documentação do Incus é sudo ufw allow in on incusbr0. Esse comando único volta a abrir todas as portas do host para todos os contentores. Em vez disso, permita apenas o que os contentores realmente precisam.

sudo ufw allow in on incusbr0 to any port 53 proto udp
sudo ufw allow in on incusbr0 to any port 53 proto tcp
sudo ufw allow in on incusbr0 to any port 67 proto udp
sudo ufw route allow in on incusbr0
sudo ufw route allow out on incusbr0

As duas regras ufw route permitem que o tráfego das instâncias atravesse o host até à Internet. Sem elas, a política de encaminhamento do ufw descarta os pacotes encaminhados. Assim, os contentores obtêm um endereço, mas não conseguem alcançar nada.

Snapshots e perfis

Um snapshot é uma cópia da instância num ponto específico no tempo, dentro do respetivo pool de armazenamento.

incus snapshot create web pre-upgrade
incus info web
incus snapshot restore web pre-upgrade
incus snapshot delete web pre-upgrade

incus info web lista os snapshots que a instância contém. Agende-os por instância.

incus config set web snapshots.schedule=@daily
incus config set web snapshots.expiry=4w

Um snapshot permanece no mesmo pool, no mesmo disco e no mesmo servidor. Protege contra uma atualização mal sucedida. Não protege contra a falha de um disco nem contra a eliminação da instância. A cópia de segurança é incus export, e o ficheiro tem de sair do servidor.

incus export web /root/web-backup.tar.gz
incus import /root/web-backup.tar.gz

Um perfil é um conjunto nomeado de chaves de configuração e dispositivos aplicado às instâncias. Todas as instâncias recebem o perfil default, salvo indicação em contrário. Esse perfil fornece o disco raiz e a interface de rede. Editar default altera todas as instâncias que o utilizam. Isto é útil, mas também permite desligar a rede de vinte contentores de uma só vez.

incus profile create small
incus profile set small limits.memory=512MiB
incus profile set small limits.cpu=1
incus launch images:debian/13 api -p default -p small

Os perfis são aplicados por ordem. Por isso, uma chave definida no último perfil listado prevalece. Consulte a configuração efetiva de uma instância com incus config show api --expanded.

Executar Docker dentro de um contentor Incus

O Docker dentro de um contentor de sistema Incus precisa que o nesting esteja ativado, porque o Docker cria os seus próprios namespaces e mounts, que um contentor não pode criar por predefinição.

incus config set web security.nesting=true
incus restart web

A documentação do Incus descreve security.nesting como "Whether to allow nesting inside of the instance" e define-o como false para contentores. Dois pontos adicionais estão descritos diretamente nas FAQ do Incus. Um contentor não pode carregar módulos do kernel. Por isso, qualquer módulo necessário ao Docker tem de ser carregado no host e indicado com incus config set web linux.kernel_modules overlay,br_netfilter. Além disso, criar um ficheiro /.dockerenv dentro do contentor faz com que o Docker ignore algumas verificações que falham num ambiente nested.

Em hosts Ubuntu 24.04, as restrições do AppArmor aos user namespaces não privilegiados podem bloquear o pivot_root que runc executa. O Docker dentro do contentor apresenta:

failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error jailing process inside rootfs: pivot_root .: permission denied

e o dmesg do host mostra uma linha que contém apparmor="DENIED" operation="pivotroot" class="mount". A definição que costuma ser alterada é kernel.apparmor_restrict_unprivileged_userns. Desativá-la não é uma correção fiável: o relatório de bug do Incus para esta recusa específica regista que defini-la como 0 não resolveu o problema. Consulte primeiro dmesg para ver a recusa. Assim, confirma se o AppArmor é realmente a causa antes de alterar uma predefinição de segurança.

Se preferir executar os contentores diretamente no VPS e eliminar uma camada, executar Docker num VPS explica essa configuração separadamente.

Modos de falha e as mensagens apresentadas

As instâncias perdem toda a rede depois de instalar o Docker no host. A documentação do Incus identifica a causa: "O Docker define a política global de FORWARD como drop, o que impede o Incus de encaminhar tráfego e faz com que as instâncias percam a conectividade de rede." As instâncias mantêm os seus endereços, mas não conseguem chegar a nenhum destino. Defina ip-forward-no-drop como true em /etc/docker/daemon.json. Depois, torne o encaminhamento persistente e permita a passagem da bridge pela própria chain do Docker.

echo "net.ipv4.conf.all.forwarding=1" | sudo tee /etc/sysctl.d/99-forwarding.conf
sudo systemctl restart systemd-sysctl
sudo iptables -I DOCKER-USER -i incusbr0 -j ACCEPT
sudo iptables -I DOCKER-USER -o incusbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

Essas regras iptables não sobrevivem sozinhas a um reboot. Torne-as persistentes.

Os contentores deixam de arrancar com um erro de cgroup. A FAQ do Incus documenta este caso. Uma mensagem sobre Failed to mount "/sys/fs/cgroup" normalmente significa que um cliente VPN no host montou o controlador de cgroup v1 net_cls sobre o cgroup v2, que o Incus utiliza. sudo umount /sys/fs/cgroup/net_cls remove o problema.

A instância não recebe um endereço IPv4. incus list mostra que está em execução, mas com a coluna de endereço vazia. As respostas DHCP do host estão a ser descartadas, normalmente por uma firewall do host que não conhece a bridge. No ufw, sudo ufw allow in on incusbr0 to any port 67 proto udp resolve o problema. Monitorize a chegada dos pedidos com sudo tcpdump -ni incusbr0 port 67.

A instância recusa arrancar numa VPS aninhada. Consulte primeiro incus info <name> --show-log e depois sudo journalctl -u incus -n 50. Se systemd-detect-virt indicar lxc ou openvz, o problema está do lado do fornecedor, e nenhuma definição dentro da sua VPS o altera.

Os snapshots são lentos e o disco continua a encher. Está a utilizar um pool dir. incus storage list apresenta o driver de cada pool. Para mudar para um pool copy-on-write, crie o novo pool, copie as instâncias para ele com incus copy web web-new -s fast e elimine os originais depois de confirmar que as cópias arrancam.

FAQ

Um contentor Incus é a mesma coisa que um contentor Docker?

Não. O Docker empacota um único processo ou aplicação. Um contentor de sistema Incus simula um sistema operativo completo, com o seu próprio init, utilizadores, serviços e gestor de pacotes. Mantém e aplica atualizações a um contentor Incus como faria com um servidor. Elimina um contentor Docker e recria-o a partir de uma imagem. Pode executar Docker dentro de um contentor Incus definindo security.nesting=true no contentor. O inverso não funciona.

Posso executar Incus numa VPS?

Numa VPS KVM, sim. Se systemd-detect-virt mostrar kvm ou qemu, tem o seu próprio kernel e o Incus comporta-se como num sistema físico. Se mostrar lxc, lxc-libvirt ou openvz, a sua VPS é ela própria um contentor. Por isso, os contentores Incus dentro dela são contentores aninhados e só funcionam se o fornecedor tiver ativado o nesting no seu contentor. Verifique também uname -r. Em outubro de 2026, as versões atuais do Incus e a série 7.0 LTS exigem um kernel 6.12 ou mais recente, enquanto a série 6.0 LTS documenta a versão 5.4.

Que backend de armazenamento devo escolher para o Incus numa VPS?

btrfs num ficheiro loop, a menos que tenha um dispositivo de blocos livre para lhe atribuir. O controlador dir está documentado como muito mais lento do que os restantes, porque copia ficheiros em vez de utilizar copy-on-write. Por isso, cada snapshot escreve novamente todo o contentor. incus admin init --minimal seleciona dir, pelo que vale a pena responder às perguntas interativas durante os dois minutos necessários. Crie o pool com incus storage create fast btrfs size=30GiB.

Porque é que o meu contentor Incus consegue alcançar um serviço em execução no host?

Porque a bridge incusbr0 predefinida coloca o host na mesma sub-rede que o contentor, no endereço do gateway. As regras de firewall que o Incus adiciona a essa bridge existem para permitir o funcionamento da rede, não para bloquear o host. Qualquer serviço do host associado a 0.0.0.0 responde nesse endereço, a menos que uma regra de firewall do host descarte os pacotes. A firewall do fornecedor nunca os vê, porque não saem da máquina. Associe os serviços do host a 127.0.0.1. Num host com ufw, permita apenas DNS e DHCP de entrada em incusbr0, em vez de utilizar a regra abrangente sudo ufw allow in on incusbr0.

Como faço uma cópia de segurança de um contentor Incus?

incus export web /root/web-backup.tar.gz grava a instância e os respetivos snapshots num único ficheiro, e incus import restaura-a no mesmo servidor ou noutro. Os snapshots criados com incus snapshot create não são cópias de segurança. Permanecem no mesmo pool de armazenamento e no mesmo disco, pelo que sobrevivem a uma atualização problemática, mas não à falha do servidor. Agende-os com incus config set web snapshots.schedule=@daily e copie as exportações para fora do servidor.

#incus#lxd#system-containers#virtualization#vps