Automação, JSON e solução de problemas
Sem perguntas interativas#
Um argumento obrigatório que falta é um erro imediato, com uma dica de uso, nunca uma pergunta, e o comando sai com código diferente de zero. Nada trava um script ou um agente esperando entrada.
Alguns comandos fazem perguntas, mas só quando há uma pessoa em um terminal:
- O
zeltro createsó pergunta em um terminal. Com--one-off,--json-outputou uma stdin que não é terminal, ele volta para o erro imediato. - O
zeltro configurepergunta o diretório de projetos (e o seu nome e e-mail do git, se o git não tiver nenhum), a menos que você passe--non-interactive(--yes,-y) ou--json-output. Passe--projects-dirpara definir o diretório sem pergunta. - O
zeltro ai-setsem flags abre um menu em um terminal. Com qualquer flag, ou sem terminal, não abre. - O
zeltro uninstallpergunta se deve apagar as imagens Docker, a menos que você passe--delete-imagesou--json-output.
Use zeltro up-all / zeltro down-all para agir em todos os projetos em vez de fazer um loop.
Rodando comandos em um projeto#
Use zeltro exec <cmd> a partir do diretório do projeto. Ele roda sem TTY, roda como o seu próprio usuário para que os arquivos montados continuem graváveis, e devolve o código de saída do comando. O zeltro exec-root faz o mesmo como root. Os dois aceitam argumentos separados ou uma única string entre aspas:
zeltro exec python3 manage.py migrate
zeltro exec "php artisan migrate --force"
zeltro bash, zeltro tinker e zeltro exec-tty / exec-tty-root são para uso interativo e alocam um TTY quando existe um. Também não use um docker exec -u developer … direto: o usuário developer do contêiner não é o dono dos arquivos do seu projeto.
Substituições de IA por sessão#
zeltro ai, resume, create, clone, create-installer e update-installer usam o agente definido pelo zeltro ai-set. Para usar outro em uma única execução, defina estas variáveis no ambiente. Elas nunca são escritas na configuração.
| Variável | Substitui |
|---|---|
ZELTRO_AI_AGENT |
O agente: codex, claude, agy, aider, qwen, opencode, hermes ou gemini (obsoleto) |
ZELTRO_AI_MODEL |
O modelo |
ZELTRO_AI_API_BASE |
O endpoint da API |
ZELTRO_AI_API_KEY |
A chave de API |
ZELTRO_AI_API_KEY_FILE |
A chave de API, lida da primeira linha do arquivo. Tem prioridade sobre ZELTRO_AI_API_KEY. |
ZELTRO_AI_LANGUAGE |
O idioma em que o agente responde, por exemplo Spanish. A saída do próprio Zeltro continua em inglês. |
Não definida significa "usar o valor do ai-set"; definida mas vazia apaga o valor nesta execução. Um nome de agente desconhecido, um arquivo de chave ilegível ou um agente de substituição que não está instalado sai com código diferente de zero antes de qualquer coisa rodar. zeltro ai-set --install-only --agent <name> instala um agente sem torná-lo o padrão.
Mensagens entre sessões de agentes#
Quando o app Zeltro roda sessões de agentes em vários projetos, elas podem trocar mensagens:
zeltro peers # live sessions, as project@host
zeltro send blog api -- "schema changed" # to one or more sessions
zeltro send --all -- "rebasing main" # to every other session
echo "long message" | zeltro send blog -- - # read the message from stdin
Rode o send de dentro do diretório do seu projeto; é assim que o destinatário sabe quem enviou. Todos os destinos precisam estar ativos, senão nada é enviado. As mensagens têm limite de 16 KB. Quem entrega é o app, então ele precisa estar rodando.
Saída JSON#
--json-output gera uma saída limpa, legível por máquina, para interfaces gráficas e scripts.
zeltro status --json-output
zeltro new laravel myapp --json-output
O new imprime um objeto, com o resultado da etapa de setup aninhado dentro dele:
{
"action": "new_project",
"project_name": "myapp",
"framework": "laravel",
"database": "mysql",
"setup_result": { "action": "setup_project", "status": "success", "...": "..." },
"status": "success"
}
Quando o setup precisou ligar um servidor de banco de dados, o setup_result também traz services_enabled (por exemplo ["postgres"]) e admin_uis_suggested.
O status imprime shared_services, indexado pelo nome do contêiner, e projects:
{
"shared_services": {
"zeltro-mariadb": { "name": "zeltro-mariadb", "status": "running", "port": "3306", "resolved_ip": "10.x.x.2", "ping_status": "ok" }
},
"projects": [
{
"name": "my-api",
"project_ip": "10.x.x.219",
"external_port": "219",
"docker_running": true,
"http_status": "ok",
"local_url": "http://10.x.x.219",
"lan_url": "http://192.168.1.20:219",
"metadata": {}
}
]
}
O status de um serviço é running ou stopped. Sem --all, projects lista só os projetos em execução.
Outros formatos, todos com action e status:
| Comando | Saída |
|---|---|
enable-service (sem nome) |
action: "list_services", always_on e services[] com slug, group, description, address, state (running, disabled ou enabled_not_running) |
enable-service <name> / disable-service <name> |
action: "enable_service" / "disable_service", service, enabled (a nova lista separada por espaços) |
ai-set (só --json-output) |
action: "ai_set", agent, model, api_base, has_api_key, unattended, installed_agents. Somente leitura. |
peers |
action: "peers", this_host, me, app_running, updated_at, age_seconds, sessions[] |
send |
action: "send", id, from, to, file, app_running |
down |
action: "shutdown", target, project_name |
remove |
action: "remove_project", project_name, database_deleted |
Os erros imprimem "status": "error" com um campo message ou error e saem com código diferente de zero, então confira o código de saída além do JSON.
Exemplos de script:
# is the shared MariaDB up?
if zeltro status --json-output | jq -e '.shared_services["zeltro-mariadb"].status == "running"' >/dev/null; then
echo "Database is ready"
fi
# list stopped projects
zeltro status --all --json-output | jq -r '.projects[] | select(.docker_running == false) | .name'
Quais comandos suportam#
Suportam: status, new, clone, setup, remove, up, down, down-all, start-services, stop-services, enable-service, disable-service, enable, disable, set-metadata, configure, create (inclusive --classify-only), ai-set, peers, send.
Em parte: install --json-output imprime o JSON das etapas setup e up, mas nenhum objeto de resumo próprio. uninstall --json-output só pula a pergunta sobre as imagens; não imprime JSON.
Não suportam — tudo o que roda dentro de um contêiner ou se conecta direto a um serviço: composer, art, wp, php, npm, npx, node, python, pip, shell, django, exec, supervisor, redis, memcache.
Se você é um agente de IA, nunca use --json-output. Ele suprime toda a saída legível por pessoas, inclusive a distinção entre sucesso e falha, então você não consegue saber se um comando realmente funcionou. Ele existe para programas externos que interpretam a saída do Zeltro, não para agentes que operam o CLI.
Depuração#
zeltro new laravel test-project --debug
tail -f /tmp/zeltro-cli-debug.log
O --debug funciona em new, clone, setup, up, down, status, remove, configure, start-services, stop-services e uninstall. Cada chamada sobrescreve o log e registra o fluxo pelos scripts que ela chama. Defina DEBUG_LOG_PATH para gravá-lo em outro lugar.
Solução de problemas#
| Sintoma | O que verificar |
|---|---|
| Os serviços não iniciam | O Docker está rodando; você está no grupo docker (saia da sessão e entre de novo depois da instalação) |
| Erros de permissão | O mesmo — fazer parte do grupo docker exige um novo login |
| Não consigo acessar um projeto no navegador | Use o endereço que o zeltro status <project> mostra (http://<project>/ não é resolvido no host); depois docker logs <project-name> |
| Conexão com o banco de dados recusada | zeltro status — o serviço compartilhado está rodando? Se aparecer stopped, zeltro enable-service mysql (ou postgres, mongo) |
| O projeto dá 502 depois de reiniciar | Uma dependência não está na imagem base. Veja Arquitetura → Imagens base |
| Fedora: permissão negada nos arquivos do projeto | SELinux — rode zeltro configure de novo para refazer o rótulo. Veja Instalação |
| Arch: o Docker não inicia depois da instalação | A atualização do sistema substituiu o kernel em execução — reinicie |
Verificações úteis:
zeltro status # shared services and running projects
zeltro status --all # include stopped projects
zeltro status <project> # one project, even if stopped
docker logs <project-name>
zeltro exec "getent hosts zeltro-mariadb" # name resolution from inside the container
Ferramentas gráficas#
Os instaladores trazem o ImageMagick (convert, magick) e o rsvg-convert no host, então projetos que precisam de gráficos não têm dependências extras.
Prefira gerar SVG — os navegadores o renderizam perfeitamente e é texto que um agente pode escrever diretamente. Converta só quando um bitmap for realmente necessário:
rsvg-convert sprite.svg -o sprite.png # best SVG → PNG fidelity
convert -size 1200x800 gradient:'#1e3a8a-#04081d' bg.png # procedural backgrounds
Essas são ferramentas do host — rode-as diretamente, não pelo zeltro exec.
Achou um erro nesta tradução? Avise a gente no GitHub.