Podman Quadlet: Contentores Geridos pelo systemd na PME
O Podman Quadlet permite gerir contentores como unidades nativas do systemd, usando ficheiros declarativos .container, .volume e .network. Para uma PME que precisa de serviços estáveis com reinício automático, dependências entre contentores e integração com o ciclo de vida do sistema, o Quadlet é mais limpo que scripts manuais ou podman generate systemd.
ℹ O Quadlet substitui o podman generate systemd — ficheiros .container são mais simples e declarativos que unidades systemd manuais.
⚠ Os ficheiros Quadlet devem estar em ~/.config/contentores/systemd/ (utilizador) ou /etc/contentores/systemd/ (sistema).
Neste artigo
- 1. Introdução ao Quadlet
- 2. Ficheiros .container
- 3. Ficheiros .volume e .network
- 4. Gestão com systemctl
- 5. Implantação de Serviços
- 6. Quadlet vs docker-compose vs podman generate
- 7. Erros Comuns e Lista de Verificação
1. Introdução ao Quadlet
O Quadlet é o mecanismo nativo do Podman para integrar contentores com o systemd. Em vez de gerar unidades systemd manualmente (o antigo podman generate systemd, agora descontinuado), o administrador escreve ficheiros INI com extensões .container, .volume, .network, .kube ou .pod. O Quadlet converte esses ficheiros em unidades systemd reais durante o daemon-reload.
As vantagens para uma PME são concretas: reinício automático em caso de falha, dependências entre serviços (por exemplo, a base de dados arrancar antes da aplicação), gestão centralizada via systemctl e integração com o diário do sistema para registos. Tudo isto sem instalar o serviço Docker.
O Quadlet está disponível a partir do Podman 4.4 ( Janeiro de 2023) e é a forma recomendada pela documentação oficial para gerir contentores em produção com systemd. Para detalhes completos da sintaxe, consultar a página de manual do podman-systemd.unit.
2. Ficheiros .container
O ficheiro .container é o bloco fundamental do Quadlet. Define a imagem, portas, volumes e opções de execução do contentor. A secção [Contentor] descreve o contentor. A secção [Service] controla o comportamento do systemd (reinício, tempo limite, dependências).
# Criar ficheiro .container
mkdir -p ~/.config/containers/systemd
cat > ~/.config/containers/systemd/web.container << 'EOF'
[Container]
Image=docker.io/nginx:alpine
ContainerName=web
PublishPort=8080:80
Volume=web-data:/usr/share/nginx/html:Z
Exec=nginx -g 'daemon off;'
[Service]
Restart=always
TimeoutStartSec=60
EOF
# Recarregar systemd
systemctl --user daemon-reload
systemctl --user start web
systemctl --user status web
Os campos principais da secção [Contentor] incluem:
| Campo | Descrição |
|---|---|
Image |
Imagem do repositório (ex: docker.io/nginx:alpine) |
ContainerName |
Nome do contentor (usado como nome da unidade systemd) |
PublishPort |
Mapeamento de portas host:contentor |
Volume |
Montagem de volume nomeado ou caminho (com :Z para SELinux) |
Exec |
Comando de entrada (substitui ENTRYPOINT) |
Environment |
Variáveis de ambiente (ex: TZ=Europe/Lisbon) |
3. Ficheiros .volume e .network
Para volumes e redes persistentes, o Quadlet oferece ficheiros dedicados. Um ficheiro .volume cria um volume nomeado gerido pelo Podman. Um ficheiro .network define uma rede personalizada. Ambos são convertidos em unidades systemd que arrancam antes dos contentores que delas dependem.
# Ficheiro .volume
# web-data.volume:
[Volume]
VolumeName=web-data
# Ficheiro .network
# mynet.network:
[Network]
NetworkName=mynet
No ficheiro .container, referenciar o volume e a rede pelo nome do ficheiro (sem extensão). O Quadlet resolve automaticamente a dependência:
# app.container com volume e rede
[Container]
Image=docker.io/nginx:alpine
ContainerName=app
Volume=web-data:/usr/share/nginx/html:Z
Network=mynet.network
PublishPort=8080:80
O systemd garante que o volume web-data.volume e a rede mynet.network arrancam antes do contentor app, sem configuração manual de Requires= ou After=.
4. Gestão com systemctl
Depois de colocar os ficheiros Quadlet no directório correcto e fazer daemon-reload, o contentor é gerido como qualquer unidade systemd. O nome da unidade deriva do nome do ficheiro (sem a extensão .container).
# Recarregar unidades systemd
systemctl --user daemon-reload
# Iniciar o contentor
systemctl --user start web
# Verificar estado
systemctl --user status web
# Parar e desactivar
systemctl --user stop web
systemctl --user disable web
# Activar arranque no arranque
systemctl --user enable web
# Ver registos (journal)
journalctl --user -u web -f
Em modo rootless (utilizador normal), é necessário activar a persistência para que os serviços do utilizador arranquem sem sessão activa:
# Activar lingering para o utilizador
sudo loginctl enable-linger $USER
# Verificar
loginctl show-user $USER | grep Linger
5. Implantação de Serviços
Um cenário típico de PME: um servidor web nginx com uma base de dados PostgreSQL. Com Quadlet, define-se cada serviço num ficheiro separado e declara-se a dependência. O ficheiro db.container arranca primeiro. O web.container depende dele via Requires= e After= na secção [Unit].
# db.container
[Container]
Image=docker.io/postgres:16-alpine
ContainerName=db
Volume=db-data:/var/lib/postgresql/data:Z
Network=mynet.network
Environment=POSTGRES_PASSWORD=segredo
Environment=POSTGRES_DB=appdb
# web.container
[Unit]
Requires=db-container.service
After=db-container.service
[Container]
Image=docker.io/nginx:alpine
ContainerName=web
Volume=web-data:/usr/share/nginx/html:Z
Network=mynet.network
PublishPort=8080:80
[Service]
Restart=always
RestartSec=5
O nome da unidade gerada pelo Quadlet segue o padrão nome-container.service. Por isso, no Requires= usa-se db-container.service e não db.service.
6. Quadlet vs docker-compose vs podman generate
Existem três abordagens comuns para gerir contentores em servidores Linux. Cada uma tem um propósito distinto:
| Método | Vantagens | Desvantagens |
|---|---|---|
| Quadlet | Nativo systemd, políticas de reinício, dependências, sem serviço de fundo | Requer Podman 4.4+, sintaxe INI menos familiar |
| docker-compose | Sintaxe YAML conhecida, ecossistema amplo | Precisa de serviço Docker (ou podman-compose), sem integração systemd nativa |
| podman generate systemd | Gera .service a partir de contentor existente | Descontinuado, ficheiros gerados difíceis de manter |
Para uma PME que já usa systemd como sistema de init (a maioria das distribuições modernas), o Quadlet é a opção mais integrada. O artigo sobre Docker Compose na PME cobre a abordagem alternativa com YAML. Mais sobre contentores e orquestração no Curso Linux Dia 22 e na abordagem com Nomad (artigo 18366).
7. Erros Comuns e Lista de Verificação
Os problemas mais frequentes ao migrar para Quadlet resultam de pequenos detalhes de sintaxe ou localização dos ficheiros:
- Directório errado: ficheiros fora de
~/.config/contentores/systemd/não são detectados. - Esquecer o daemon-reload: sem
systemctl --user daemon-reloado systemd não vê os ficheiros novos. - Persistência desactivada: contentores rootless não arrancam no boot sem
loginctl enable-linger. - Nome de unidade incorrecto: usar
db.serviceem vez dedb-container.serviceem dependências. - SELinux sem :Z: volumes sem a opção
:Zpodem falhar em sistemas com SELinux activo.
Para diagnosticar erros de conversão do Quadlet, o comando /usr/libexec/podman/quadlet --dryrun (ou /usr/lib/podman/quadlet --dryrun em algumas distribuições) mostra as unidades systemd geradas sem as aplicar.
# Pré-validar ficheiros Quadlet
/usr/libexec/podman/quadlet --dryrun --user
# Ver unidades geradas
ls ~/.config/systemd/user/*container*.service
Lista de verificação antes de produção:
- ✓ Ficheiros Quadlet no directório correcto (utilizador ou sistema)
- ✓
daemon-reloadexecutado após criar ou alterar ficheiros - ✓ Persistência activada para rootless (
loginctl enable-linger) - ✓ Dependências declaradas em
[Unit]comRequires=eAfter= - ✓
Restart=alwaysna secção[Service]para reinício automático - ✓ Volumes com opção
:Zem sistemas SELinux - ✓
--dryrunexecutado para validar conversão - ✓ Registos confirmados com
journalctl --user -u nome
O Quadlet é a forma recomendada pela documentação do Podman e pela Arch Wiki para integrar contentores com systemd. Para PMEs que já administram servidores com systemd, reduz a complexidade operacional e elimina a dependência do Docker daemon.