Do Podman ao Docker: como limpei meu ambiente e resolvi conflitos de porta "device or resource busy
Voltar para blog

Do Podman ao Docker: como limpei meu ambiente e resolvi conflitos de porta "device or resource busy

07/06/2026 · 5 min · Infraestrutura

Se você trabalha com infraestrutura, sabe que a promessa do Podman de ser um substituto "drop-in" para o Docker é tentadora. Recentemente, em um dos meus servidores de desenvolvimento onde utilizo o aaPanel, passei por uma situação curiosa: ao instalar o Docker via painel, o sistema removeu o binário do Podman, mas deixou para trás uma "herança" de processos e arquivos que transformaram meu ambiente em um cenário de ghosting técnico.

Neste artigo, compartilho os erros que enfrentei e o passo a passo definitivo para limpar resíduos do Podman e deixar o Docker assumir o controle total.

O aaPanel é otimizado para o Docker Engine. Ao forçar a instalação do Docker, o Podman é desinstalado, mas seus containers rootless e camadas de storage (OverlayFS) podem continuar ativos no kernel.


1. O risco da limpeza sem backup#

Um dos maiores erros ao realizar uma migração de runtime ou executar limpezas de sistema é assumir que todos os containers e volumes no Podman são descartáveis. Antes de rodar comandos destrutivos de remoção de diretórios, você deve realizar o inventário e backup dos dados persistentes:

# 1. Listar todos os containers do Podman ativos e inativos
podman ps -a

# 2. Listar todos os volumes criados no Podman
podman volume ls

# 3. Exportar imagens customizadas importantes que não estão no registry público
podman save -o /root/podman-images-backup.tar $(podman images -q)

# 4. Fazer backup compactado completo do diretório de armazenamento local do usuário (Rootless)
tar czf /root/podman-user-storage-backup-$(date +%Y%m%d).tar.gz ~/.local/share/containers/ 2>/dev/null || true

# 5. Fazer backup compactado do diretório de armazenamento global do sistema (Root)
sudo tar czf /root/podman-system-storage-backup-$(date +%Y%m%d).tar.gz /var/lib/containers/ 2>/dev/null || true

2. Auditoria e parada de recursos ativos#

Se você executar o reset ou a limpeza física com containers ainda em execução, o kernel pode bloquear a remoção de caminhos do OverlayFS.

2.1 parada controlada de containers#

Antes de remover o armazenamento, pare ordenadamente os serviços ativos para que desmontagens de rede e de volumes ocorram de forma limpa:

# 1. Listar containers que ainda estão em execução
podman ps

# 2. Parar todos os containers ativos graciosamente
podman stop -a
# Ou forçando a parada de IDs caso o daemon não responda
# podman stop $(podman ps -aq)

2.2 verificação de volumes e dados relevantes#

Inspecione os pontos de montagem física dos volumes para garantir que dados de bancos de dados ou uploads persistentes não sejam deletados:

# Loop para listar cada volume do Podman, seu mountpoint e as primeiras linhas do conteúdo
for vol in $(podman volume ls -q); do
    echo "=== Volume: $vol ==="
    podman volume inspect $vol | grep Mountpoint
    # Listar o conteúdo físico associado ao volume
    sudo ls -la $(podman volume inspect $vol -f '{{.Mountpoint}}') 2>/dev/null | head -5
done

3. Resolvendo "device or resource busy" (overlayfs)#

O sintoma clássico do descompasso de migração ocorre quando você tenta excluir pastas antigas do Podman e o sistema retorna o erro:

rm: cannot remove '/var/lib/containers/storage/overlay/.../merged': Device or resource busy

3.1 por que o erro acontece?#

O Podman utiliza o driver de armazenamento OverlayFS para empilhar camadas de imagens e contêineres. Se o binário do Podman é removido abruptamente (como ocorre em scripts do aaPanel) enquanto caminhos de montagem ainda estão referenciados no kernel, esses pontos permanecem bloqueados. O utilitário rm -rf falha porque o diretório atua como um ponto de montagem ativo para o Linux.

3.2 o comando de desmontagem com lazy unmount#

A solução não é forçar a exclusão física com flags destrutivas, mas sim desvincular o sistema de arquivos no kernel usando o "lazy unmount":

cat /proc/mounts | grep /var/lib/containers | awk '{print $2}' | xargs -r sudo umount -l

Parâmetro -l (lazy unmount)#

A flag -l instrui o kernel a desvincular o sistema de arquivos da árvore de diretórios imediatamente, liberando todas as referências ao caminho assim que os processos que o utilizavam deixarem de estar ativos.


4. O mistério da porta HTTPS ocupada: rootlessport#

Mesmo após limpar o disco, é comum descobrir que a porta HTTPS (como 9443 ou 8443) continua respondendo na rede, mas o comando docker ps não mostra nenhum container escutando nela.

Ao investigar com a ferramenta de diagnóstico de rede:

sudo lsof -i :9443

O culpado costuma ser o processo rootlessport. Este binário é o componente auxiliar do Podman responsável por encaminhar tráfego de portas privilegiadas para a infraestrutura de rede rootless (sem privilégios de administrador). Ele sobrevive à remoção física do pacote principal.

4.1 encerrando processos de forma segura (escalação de sinais)#

Não utilize diretamente o comando kill -9 (SIGKILL). Matar processos abruptamente pode deixar sockets de rede em estado órfão e corromper recursos compartilhados. Adote um fluxo seguro de encerramento:

# 1. Investigar a árvore genealógica do processo (Process Tree) e consumo
ps -p <PID_DO_ROOTLESSPORT> -o pid,ppid,comm,%cpu,%mem
pstree -p <PID_DO_ROOTLESSPORT>

# 2. Enviar sinal SIGTERM (solicitação amigável de encerramento)
sudo kill -15 <PID_DO_ROOTLESSPORT>

# 3. Aguardar 3 segundos para finalização das conexões pendentes
sleep 3

# 4. Validar se o processo foi finalizado. Se ainda ativo, forçar com SIGKILL
sudo kill -0 <PID_DO_ROOTLESSPORT> 2>/dev/null && sudo kill -9 <PID_DO_ROOTLESSPORT>

5. Auditorias de segurança, SELinux e configurações residuais#

Para garantir a estabilidade do novo ambiente sobre o Docker Engine, você deve auditar as camadas de controle de acesso obrigatório (MAC), configurações locais e redes virtuais órfãs.

5.1 verificação do status do SELinux#

Em sistemas como RedHat, Rocky Linux ou AlmaLinux, o SELinux pode bloquear operações de escrita em diretórios remanescentes do contêiner ou gerar conflitos de permissões no socket do Docker:

# 1. Verificar o modo ativo do SELinux
getenforce

# 2. Consultar logs de negações (denials) recentes relacionados a contêineres ou podman
sudo ausearch -m avc -ts recent | grep -iE "container|podman" 2>/dev/null || echo "Nenhuma negação recente."

# 3. Se necessário, restaurar os contextos de segurança corretos dos arquivos do sistema
sudo restorecon -Rv /var/lib/containers 2>/dev/null || true

5.2 remoção de arquivos de configuração ocultos#

O Podman armazena definições de repositórios e storage em caminhos globais e locais do usuário. Remova-os para evitar conflitos de escopo:

# 1. Listar configurações locais do usuário
ls -la ~/.config/containers/ 2>/dev/null

# 2. Listar configurações globais de sistema
ls -la /etc/containers/ 2>/dev/null

# 3. Remover permanentemente estes arquivos residuais
rm -rf ~/.config/containers/
sudo rm -rf /etc/containers/

5.3 auditoria de rede e firewall (regras CNI e iptables)#

O Podman utiliza a arquitetura CNI (Container Network Interface) ou Netavark para roteamento. Seus filtros de IP podem continuar ativos no Netfilter do kernel:

# 1. Listar regras vigentes de IPTables associadas a contêineres ou podman
sudo iptables -L -n | grep -iE "containers|podman|cni"

# 2. Remover as configurações de redes virtuais CNI do diretório de sistema
sudo rm -rf /etc/cni/net.d/

# 3. Listar interfaces de rede remanescentes no kernel
ip link show | grep -iE "podman|cni|veth"
# Se houver interfaces órfãs ativas (ex: cni-podman0), remova-as:
# sudo ip link delete cni-podman0

6. Validação e saúde do ambiente Docker#

Com a máquina limpa de vestígios do Podman, valide o funcionamento correto do Docker Engine:

# 1. Verificar o status do serviço Docker no systemd
systemctl status docker

# 2. Testar acesso ao socket administrativo e obter informações do daemon
docker info | head -20

# 3. Validar se a rede de bridge padrão do Docker está saudável
docker network inspect bridge | head -20

# 4. Executar um container de testes descartável para validar download e execução de imagem
docker run --rm hello-world

# 5. Confirmar que não há mapeamentos ou portas conflitantes pendentes
docker ps -a
docker network ls

7. Verificação pós-limpeza (sanity checks)#

Execute estes comandos finais para garantir o estado ideal do sistema operacional:

# 1. Confirmar se não há mais pontos de montagem associados ao Podman
# Deve retornar 0
cat /proc/mounts | grep -c containers

# 2. Confirmar se não há processos zumbis do Podman em execução
# Deve retornar 1 (apenas a linha de grep ativa)
ps aux | grep -c podman

# 3. Verificar o espaço em disco liberado após o purge do storage
df -h

Checklist: migração Podman → Docker#

Siga este roteiro operacional para migrar ambientes de forma segura e limpa:

1. Fase de pré-migração#

2. Fase de limpeza do Podman#

3. Fase de rede e firewall#

4. Fase de instalação e homologação Docker#

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários