Podman (Pod Manager) é um motor de containers de código aberto e sem daemon, desenvolvido pela Red Hat, que fornece uma CLI compatível com Docker para construir, executar e gerenciar containers e pods OCI. Diferentemente do Docker, o Podman não requer um daemon em segundo plano com privilégios de root, tornando-o inerentemente mais seguro tanto para estações de trabalho de desenvolvimento quanto para servidores de produção. Se você tem usado Docker e está procurando uma alternativa mais segura, compatível com systemd e que execute containers como seu usuário regular, o Podman é a ferramenta a adotar.
Este guia cobre tudo que você precisa para começar com o Podman no Ubuntu: instalação, execução de containers sem root, gerenciamento de imagens, criação de pods, compatibilidade com Compose, integração com systemd, redes e um caminho completo de migração a partir do Docker.
Pré-requisitos
Antes de começar, certifique-se de ter:
- Um sistema executando Ubuntu 22.04 ou 24.04 (edição desktop ou servidor)
- Acesso ao terminal com privilégios sudo
- Uma conexão estável com a internet
- Familiaridade básica com containers e a linha de comando do Linux
- Pelo menos 2 GB de espaço livre em disco para imagens
Nota: O Podman funciona em qualquer distribuição Linux moderna, mas este guia foca no Ubuntu. Se você está migrando do Docker, nenhuma instalação do Docker é necessária — o Podman o substitui completamente.
O Que É o Podman?
Podman é uma ferramenta de gerenciamento de containers que implementa a mesma interface CLI que o Docker, mas com uma arquitetura fundamentalmente diferente. O nome vem de Pod Manager, refletindo seu suporte nativo para pods estilo Kubernetes — grupos de containers que compartilham namespaces de rede e IPC.
Características principais do Podman:
- Sem daemon: Nenhum serviço em segundo plano é executado como root. Cada comando
podmanlança containers diretamente como processos filhos viaconmon(o monitor de containers). - Sem root por padrão: Os containers são executados sob sua conta de usuário regular usando user namespaces do Linux, sem necessidade de privilégios root.
- Compatível com OCI: O Podman constrói e executa imagens que estão em conformidade com a especificação Open Container Initiative (OCI), garantindo total compatibilidade com imagens e registros Docker.
- Pods nativos: O Podman pode agrupar containers em pods, espelhando a semântica de pods do Kubernetes para desenvolvimento e testes locais.
- Integração com systemd: O Podman gera arquivos de unidade systemd a partir de containers em execução, facilitando o gerenciamento do ciclo de vida dos containers como serviços do sistema.
Podman vs Docker
Entender as diferenças arquiteturais entre Podman e Docker ajuda você a tomar uma decisão informada e planejar sua migração.
| Característica | Podman | Docker |
|---|---|---|
| Arquitetura | Sem daemon (fork/exec) | Cliente-servidor (daemon dockerd) |
| Requisito de root | Sem root por padrão | Requer daemon root (modo sem root opcional) |
| Runtime de containers | crun / runc via conmon | containerd + runc |
| Compatibilidade CLI | Substituto direto (podman = docker) | CLI nativa |
| Suporte a pods | Nativo (estilo Kubernetes) | Não disponível |
| Suporte Compose | podman-compose / podman compose | docker compose (plugin integrado) |
| Integração systemd | Nativa (podman generate systemd) | Requer arquivos de unidade manuais |
| Formato de imagem | OCI / Docker | OCI / Docker |
| Ferramenta de build | Buildah (integrado) | BuildKit |
| Modelo de segurança | Sem daemon root, user namespaces | Daemon root, sem root opcional |
| Socket | Opcional (podman.socket) | Obrigatório (docker.socket) |
A diferença mais significativa é o daemon. O Docker requer que o daemon dockerd esteja em execução o tempo todo como root, criando um único ponto de falha e um vetor potencial de escalonamento de privilégios. O Podman elimina isso completamente — quando você executa podman run, ele diretamente cria um novo processo para o container usando conmon como monitor de containers. Se o próprio Podman falhar, os containers em execução continuam operando.
Instalar o Podman no Ubuntu
O Podman está disponível nos repositórios oficiais do Ubuntu a partir do Ubuntu 22.04. Instale-o junto com suas ferramentas de suporte:
sudo apt update
sudo apt install -y podman
Verifique a instalação:
podman --version
Saída esperada:
podman version 4.9.3
Verifique as informações do sistema para confirmar que o modo sem root está disponível:
podman info --format '{{.Host.Security.Rootless}}'
Isso deve retornar true quando executado como usuário não root.
Para a versão mais recente do Podman (se a versão do repositório do Ubuntu estiver desatualizada), você pode adicionar o repositório oficial do Kubic:
sudo mkdir -p /etc/apt/keyrings
curl -fsSL "https://download.opensuse.org/repositories/devel:kubic:libcontainers:unstable/xUbuntu_$(lsb_release -rs)/Release.key" \
| gpg --dearmor \
| sudo tee /etc/apt/keyrings/devel_kubic_libcontainers_unstable.gpg > /dev/null
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/devel_kubic_libcontainers_unstable.gpg] \
https://download.opensuse.org/repositories/devel:kubic:libcontainers:unstable/xUbuntu_$(lsb_release -rs)/ /" \
| sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list > /dev/null
sudo apt update
sudo apt install -y podman
Configurar Registros de Containers
Por padrão, o Podman requer nomes de imagem totalmente qualificados (ex., docker.io/library/nginx). Para habilitar nomes curtos como nginx, configure os registros de busca não qualificados:
sudo tee /etc/containers/registries.conf.d/00-unqualified-search.conf <<'EOF'
[registries.search]
registries = ['docker.io', 'quay.io', 'ghcr.io']
EOF
Alternativamente, edite /etc/containers/registries.conf e adicione os registros de busca na seção [registries.search].
Executar Seu Primeiro Container
Com o Podman instalado, execute um container de teste como seu usuário regular (não root):
podman run --rm docker.io/library/hello-world
Você deve ver a familiar mensagem “Hello from Docker!”, confirmando que o Podman pode baixar e executar imagens OCI. Note que nenhum sudo é necessário.
Execute um container interativo:
podman run -it --rm docker.io/library/ubuntu:24.04 bash
Dentro do container, verifique o usuário:
whoami
# root (dentro do user namespace do container)
id
# uid=0(root) gid=0(root) groups=0(root)
Embora você apareça como root dentro do container, na realidade está executando como seu usuário regular no host. Este é o poder dos containers sem root com mapeamento de user namespace.
Saia do container com exit ou Ctrl+D.
Containers sem Root
Containers sem root são a característica definidora do Podman. Entender como funcionam ajuda a solucionar problemas de permissão e projetar implantações seguras de containers.
Como Funcionam os Containers sem Root
Quando você executa um container como usuário não root, o Podman usa user namespaces do Linux para criar um ambiente isolado onde:
- O processo do container se vê como
root(UID 0) dentro do container. - No host, o processo é executado como um UID subordinado mapeado do intervalo permitido do seu usuário.
- O mapeamento é definido em
/etc/subuide/etc/subgid.
Verifique os mapeamentos de UID/GID subordinados do seu usuário:
cat /etc/subuid
# jc:100000:65536
cat /etc/subgid
# jc:100000:65536
Isso significa que o usuário jc pode mapear UIDs de 100000 a 165535 dentro dos containers. O UID 0 do container mapeia para o UID do seu usuário no host, e os UIDs 1-65535 dentro do container mapeiam para os UIDs 100000-165535 do host.
Verificar a Operação sem Root
Execute um container e verifique o processo a partir do host:
podman run -d --name test-rootless docker.io/library/nginx:alpine
A partir de outro terminal no host:
ps aux | grep nginx
# jc 12345 ... nginx: master process
O processo nginx é executado como seu usuário (jc), não como root. Se o container fosse comprometido, o atacante teria apenas os privilégios do seu usuário — não acesso root ao host.
Configurar User Namespaces
Se /etc/subuid ou /etc/subgid não contêm entradas para seu usuário, adicione-as:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
Após modificar esses arquivos, reinicie o armazenamento do Podman para aplicar as alterações:
podman system migrate
Trabalhar com Imagens
O Podman usa o mesmo formato de imagem que o Docker e pode baixar de qualquer registro compatível com OCI.
Baixar Imagens
# Baixar do Docker Hub
podman pull docker.io/library/nginx:alpine
# Baixar do Quay.io
podman pull quay.io/podman/hello
# Baixar do GitHub Container Registry
podman pull ghcr.io/actions/actions-runner:latest
Listar Imagens
podman images
Saída:
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx alpine a2bd6d6e82f0 2 weeks ago 43.3 MB
quay.io/podman/hello latest 5dd467fce50b 3 months ago 787 kB
Construir Imagens
O Podman usa Containerfile (ou Dockerfile — ambos são suportados) e o Buildah internamente:
# Containerfile
FROM docker.io/library/python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "app.py"]
Construa a imagem:
podman build -t my-python-app:latest .
Construir com um nome de arquivo específico:
podman build -f Containerfile.prod -t my-python-app:prod .
Enviar Imagens para um Registro
Marque e envie uma imagem para um registro:
podman tag my-python-app:latest quay.io/myuser/my-python-app:latest
podman login quay.io
podman push quay.io/myuser/my-python-app:latest
Remover Imagens
# Remover uma imagem específica
podman rmi docker.io/library/nginx:alpine
# Remover todas as imagens não utilizadas
podman image prune -a
Gerenciamento de Pods
Pods são um conceito emprestado do Kubernetes. Um pod agrupa um ou mais containers que compartilham o mesmo namespace de rede, o que significa que podem se comunicar através do localhost e compartilhar mapeamentos de portas.
Criar um Pod
Crie um pod com mapeamentos de portas definidos no nível do pod:
podman pod create --name my-web-pod -p 8080:80 -p 5432:5432
Adicionar Containers a um Pod
Adicione um container nginx e um container PostgreSQL ao pod:
podman run -d --pod my-web-pod --name web-server docker.io/library/nginx:alpine
podman run -d --pod my-web-pod --name db-server \
-e POSTGRES_PASSWORD=secretpass \
-e POSTGRES_DB=appdb \
docker.io/library/postgres:16-alpine
Ambos os containers agora compartilham o mesmo namespace de rede. O container nginx pode se conectar ao PostgreSQL em localhost:5432, e clientes externos acessam o nginx via host:8080.
Gerenciar Pods
# Listar todos os pods
podman pod ls
# Ver detalhes do pod
podman pod inspect my-web-pod
# Parar todos os containers em um pod
podman pod stop my-web-pod
# Iniciar um pod
podman pod start my-web-pod
# Remover um pod e seus containers
podman pod rm -f my-web-pod
Gerar YAML do Kubernetes a partir de Pods
Uma das características únicas do Podman é gerar manifestos do Kubernetes a partir de pods em execução:
podman generate kube my-web-pod > my-web-pod.yaml
Isso cria um arquivo YAML compatível com Kubernetes que você pode implantar diretamente em um cluster Kubernetes com kubectl apply -f my-web-pod.yaml. Isso torna o Podman uma excelente ferramenta para desenvolvimento local quando seu alvo de produção é o Kubernetes.
Podman Compose
O Podman suporta arquivos Docker Compose para stacks de aplicações multi-container. Existem duas abordagens:
Usando podman-compose
Instale o podman-compose (uma reimplementação comunitária em Python):
sudo apt install -y python3-pip
pip3 install podman-compose
Use-o exatamente como o docker-compose:
podman-compose up -d
podman-compose ps
podman-compose logs -f
podman-compose down
Usando o Comando Integrado podman compose
O Podman 4.7+ inclui um comando integrado podman compose que delega para um provedor de compose externo (docker-compose ou podman-compose):
podman compose up -d
podman compose down
Exemplo de docker-compose.yml
Um arquivo docker-compose.yml padrão funciona sem modificação:
version: "3.8"
services:
web:
image: docker.io/library/nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
depends_on:
- api
api:
image: docker.io/library/node:20-alpine
working_dir: /app
volumes:
- ./api:/app
command: node server.js
environment:
- DB_HOST=db
- DB_PORT=5432
db:
image: docker.io/library/postgres:16-alpine
environment:
POSTGRES_PASSWORD: secretpass
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Execute com Podman Compose:
podman-compose up -d
Gerar Unidades systemd a partir de Containers
O Podman se integra com o systemd para gerenciar containers como serviços do sistema. Isso é especialmente útil para servidores onde você precisa que os containers iniciem na inicialização e reiniciem em caso de falha.
Gerar um Arquivo de Unidade a partir de um Container em Execução
Primeiro, inicie um container:
podman run -d --name my-nginx -p 8080:80 docker.io/library/nginx:alpine
Gere a unidade systemd:
podman generate systemd --new --name my-nginx > ~/.config/systemd/user/container-my-nginx.service
A flag --new garante que o arquivo de unidade crie um container novo cada vez (em vez de reiniciar um existente), o que é a prática recomendada.
Habilitar e Iniciar o Serviço
mkdir -p ~/.config/systemd/user
systemctl --user daemon-reload
systemctl --user enable --now container-my-nginx.service
Habilitar Lingering para Sessões sem Login
Por padrão, os serviços systemd de usuário param quando o usuário faz logout. Habilite o lingering para mantê-los em execução:
sudo loginctl enable-linger $USER
Verificar o Serviço
systemctl --user status container-my-nginx.service
Quadlet (Podman 4.4+)
Para Podman 4.4 e posterior, o Quadlet fornece um formato declarativo mais simples. Crie um arquivo .container em ~/.config/containers/systemd/:
# ~/.config/containers/systemd/my-nginx.container
[Container]
Image=docker.io/library/nginx:alpine
PublishPort=8080:80
Volume=./html:/usr/share/nginx/html:ro
[Service]
Restart=always
[Install]
WantedBy=default.target
Recarregue o systemd e inicie o serviço:
systemctl --user daemon-reload
systemctl --user start my-nginx.service
Migrar do Docker para o Podman
Se você está usando Docker atualmente, o caminho de migração para o Podman é direto.
Instalar o Pacote de Compatibilidade Docker
sudo apt install -y podman-docker
Isso instala um comando docker que é alias para o podman e cria um socket de emulação /var/run/docker.sock. Scripts existentes que chamam docker usarão o Podman em seu lugar.
Migrar Imagens Docker
Exporte imagens do Docker e importe-as no Podman:
# No sistema Docker
docker save my-app:latest -o my-app.tar
# No sistema Podman
podman load -i my-app.tar
Converter Arquivos Docker Compose
A maioria dos arquivos docker-compose.yml funciona sem modificação. Os principais ajustes a observar:
- Qualificar completamente os nomes de imagem: Substitua
nginx:alpinepordocker.io/library/nginx:alpine - Modo de rede: Alguns modos de rede específicos do Docker podem diferir
- Plugins de volume: Plugins de volume do Docker não são suportados; use os drivers de volume nativos do Podman
Atualizar Pipelines CI/CD
Substitua comandos docker por podman nos scripts do seu pipeline, ou instale podman-docker para que o alias docker cuide disso:
# Exemplo de GitHub Actions
steps:
- name: Install Podman
run: sudo apt install -y podman podman-docker
- name: Build image
run: podman build -t my-app:${{ github.sha }} .
- name: Push image
run: |
podman login -u ${{ secrets.REGISTRY_USER }} -p ${{ secrets.REGISTRY_PASS }} ghcr.io
podman push my-app:${{ github.sha }} ghcr.io/${{ github.repository }}:${{ github.sha }}
Redes
O modelo de rede do Podman difere entre os modos com root e sem root.
Redes sem Root
No modo sem root, o Podman usa slirp4netns ou pasta (Podman 5.0+) para fornecer conectividade de rede sem privilégios de root:
- slirp4netns: Cria um dispositivo TAP em um user namespace, fornecendo rede baseada em NAT. O encaminhamento de portas acima de 1024 funciona sem root.
- pasta: Uma alternativa mais nova e rápida que fornece desempenho aprimorado e menor sobrecarga.
Mapear portas no modo sem root:
podman run -d -p 8080:80 docker.io/library/nginx:alpine
Nota: Vincular a portas abaixo de 1024 (ex., 80, 443) requer privilégios de root ou ajustar o início de portas não privilegiadas do sistema com
sudo sysctl net.ipv4.ip_unprivileged_port_start=80.
CNI e Netavark
O Podman suporta dois backends de rede:
- CNI (Container Network Interface): O backend legacy usando plugins CNI.
- Netavark: A pilha de rede moderna baseada em Rust (padrão no Podman 4.0+).
Criar uma rede personalizada:
podman network create my-network
Executar containers na rede personalizada:
podman run -d --network my-network --name container-a docker.io/library/alpine sleep 3600
podman run -d --network my-network --name container-b docker.io/library/alpine sleep 3600
Containers na mesma rede podem se alcançar pelo nome:
podman exec container-a ping -c 3 container-b
Inspecionar Redes
# Listar redes
podman network ls
# Inspecionar uma rede
podman network inspect my-network
# Remover uma rede
podman network rm my-network
Referência de Comandos do Podman
A tabela a seguir lista os comandos do Podman mais utilizados e seus equivalentes no Docker:
| Comando Podman | Equivalente Docker | Descrição |
|---|---|---|
podman run | docker run | Criar e iniciar um container |
podman ps | docker ps | Listar containers em execução |
podman ps -a | docker ps -a | Listar todos os containers |
podman images | docker images | Listar imagens locais |
podman pull | docker pull | Baixar uma imagem de um registro |
podman build | docker build | Construir uma imagem a partir de um Containerfile/Dockerfile |
podman push | docker push | Enviar uma imagem para um registro |
podman exec | docker exec | Executar um comando em um container em execução |
podman logs | docker logs | Visualizar logs do container |
podman stop | docker stop | Parar um container em execução |
podman rm | docker rm | Remover um container |
podman rmi | docker rmi | Remover uma imagem |
podman volume create | docker volume create | Criar um volume nomeado |
podman network create | docker network create | Criar uma rede |
podman pod create | N/A | Criar um pod |
podman pod ls | N/A | Listar pods |
podman generate systemd | N/A | Gerar arquivos de unidade systemd |
podman generate kube | N/A | Gerar YAML do Kubernetes |
podman system prune | docker system prune | Remover dados não utilizados |
podman login | docker login | Fazer login em um registro de containers |
podman inspect | docker inspect | Ver informações detalhadas de container/imagem |
Solução de Problemas
Erro: short-name resolution enforced
Problema: O Podman se recusa a baixar uma imagem usando um nome curto como nginx.
Solução: Use o nome de imagem totalmente qualificado ou configure os registros de busca:
# Usar nome totalmente qualificado
podman pull docker.io/library/nginx:alpine
# Ou configurar registros de busca
sudo tee /etc/containers/registries.conf.d/00-unqualified-search.conf <<'EOF'
[registries.search]
registries = ['docker.io', 'quay.io']
EOF
Erro: cannot find UID/GID mapping
Problema: Containers sem root falham porque os mapeamentos de UID/GID subordinados não estão configurados.
Solução: Adicione mapeamentos para seu usuário:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
podman system migrate
Erro: permission denied on volume mount
Problema: Um container sem root não consegue acessar um diretório montado por bind.
Solução: Adicione o sufixo de rótulo SELinux :Z ou :z, ou garanta que o diretório seja de propriedade do seu usuário:
# Corrigir propriedade
podman unshare chown -R 0:0 /path/to/volume
# Ou usar flag Z para SELinux
podman run -v /path/to/volume:/data:Z my-image
Container Não Consegue Vincular à Porta 80
Problema: Podman sem root não consegue vincular a portas abaixo de 1024.
Solução: Reduza o valor de início de portas não privilegiadas:
sudo sysctl -w net.ipv4.ip_unprivileged_port_start=80
# Tornar persistente
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/99-podman-ports.conf
sudo sysctl --system
Podman Compose Falha com Erro de Rede
Problema: O podman-compose apresenta erros ao criar redes.
Solução: Certifique-se de que o backend de rede do Podman está funcionando e reinicie se necessário:
podman network ls
podman system reset --force
# Recrie seus containers após o reset
Containers Não Iniciam Após Reinicialização
Problema: Containers systemd no nível do usuário não iniciam após uma reinicialização.
Solução: Habilite o lingering para seu usuário:
sudo loginctl enable-linger $USER
Download Lento de Imagens
Problema: O download de imagens é lento no modo sem root.
Solução: Habilite o fuse-overlayfs para melhor desempenho de armazenamento:
sudo apt install -y fuse-overlayfs
Verifique se está sendo utilizado:
podman info --format '{{.Store.GraphDriverName}}'
# Deve exibir: overlay
Resumo
O Podman é um motor de containers maduro, seguro e compatível com Docker que elimina a necessidade de um processo daemon privilegiado. Sua abordagem sem root por padrão, suporte nativo a pods e integração com systemd o tornam uma excelente escolha tanto para ambientes Linux de desenvolvimento quanto de produção. Para qualquer pessoa que execute containers em servidores Linux, o Podman fornece uma clara vantagem de segurança sem sacrificar compatibilidade com o ecossistema Docker.
Neste guia você aprendeu como instalar o Podman no Ubuntu, executar containers sem root, gerenciar imagens e pods, usar o Podman Compose com arquivos docker-compose.yml existentes, gerar unidades systemd para gerenciamento automático do ciclo de vida de containers, configurar redes e migrar do Docker.
Para tópicos relacionados a containers, consulte nossos guias sobre Como Instalar o Docker no Ubuntu e Docker Compose: Guia Prático para Administradores de Sistemas.