Stacks
Um stack agrupa as aplicações e serviços de um projeto. Seus membros compartilham uma rede privada e um conjunto de variáveis, e podem ser implantados juntos em uma ordem definida.
O que é um stack?
Na API e na CLI, um stack se chama projeto: /api/v1/projects e sh0 projects gerenciam os stacks. Um stack oferece às suas aplicações:
- Uma rede privada na qual cada aplicação responde a
<nome-app>e<nome-app>.internal. O nome de host não muda quando a aplicação é reimplantada. - Variáveis compartilhadas, lidas por todas as aplicações do stack.
- Uma ordem de arranque, usada quando o stack inteiro é implantado de uma vez.
Aplicações de stacks diferentes não se enxergam pelo nome. Os servidores de banco de dados ficam fora dos stacks: qualquer aplicação os alcança em <nome-servidor>.internal.
Criar um stack
No painel, abra Stacks, clique em Criar Stack, informe um Nome do Stack (de 1 a 100 caracteres) e uma Descrição opcional. Pela CLI:
$ sh0 projects create my-shop
Project created: my-shop (5aee8eea-9f77-4d10-ac21-2fe4a565e666)sh0 push --project espera o ID do stack exibido aqui; o nome não é aceito.Página de um stack
Ao abrir um stack, seus serviços aparecem agrupados por tipo, além de:
- Adicionar app, que abre a página de implantação para este stack; Configurações do Stack; Exportar snapshot e Importar snapshot.
- O painel Rede interna e definições partilhadas: o nome de host interno de cada serviço, as Variáveis partilhadas, a Ordem de arranque e Implantar o projeto, que implanta todas as aplicações nessa ordem.
Variáveis do stack
Uma variável compartilhada é injetada em cada aplicação do stack na próxima implantação. Se uma aplicação define a mesma chave, o valor da aplicação vence. Detalhes, API e prioridade: Variáveis de ambiente.
Configurações do stack
Configurações do Stack edita o nome, a descrição, a cor e os membros, e contém Excluir Stack.
Usos comuns
- Um stack por produto: o frontend, a API e os workers que precisam se alcançar pelo nome.
- Um stack por ambiente: homologação e produção separadas, cada uma com suas variáveis compartilhadas.
- Um stack por cliente: com os membros do stack, as aplicações de cada cliente ficam visíveis apenas para as pessoas designadas.
Gerenciar stacks pela API
As rotas ficam em /api/v1/projects. Atualizações usam PATCH; PUT responde 405. Uma requisição sem /v1 não chega à API: ela devolve a página do painel. As saídas abaixo foram obtidas em uma instância de teste:
# Create a stack
$ curl -s -X POST https://panel.example.com/api/v1/projects \
-H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
-d '{"name":"my-staging","description":"Staging environment"}'
{"data":{"color":null,"created_at":"2026-10-02 02:53:41","description":"Staging environment","id":"b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e","member_count":1,"name":"my-staging","owner_id":"50159570-e8ad-46a8-8065-e6c9096edde6"}}
# List stacks (paginated: page, per_page)
$ curl -s https://panel.example.com/api/v1/projects -H "Authorization: Bearer $SH0_TOKEN"
{"data":[{"color":null,"created_at":"2026-10-02 02:53:41","description":"Staging environment","id":"b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e","member_count":1,"name":"my-staging","owner_id":"50159570-e8ad-46a8-8065-e6c9096edde6"}, ...],"page":1,"pages":1,"per_page":20,"total":3}
# Get one stack
$ curl -s https://panel.example.com/api/v1/projects/b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e -H "Authorization: Bearer $SH0_TOKEN"
{"data":{"color":null,"created_at":"2026-10-02 02:53:41","description":"Staging environment","id":"b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e","member_count":1,"name":"my-staging","owner_id":"50159570-e8ad-46a8-8065-e6c9096edde6"}}
# Update a stack
$ curl -s -X PATCH https://panel.example.com/api/v1/projects/b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e \
-H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
-d '{"description":"Staging, rebuilt nightly"}'
{"data":{"color":null,"created_at":"2026-10-02 02:53:41","description":"Staging, rebuilt nightly","id":"b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e","member_count":1,"name":"my-staging","owner_id":"50159570-e8ad-46a8-8065-e6c9096edde6"}}
# Delete a stack that still holds an app: refused (HTTP 400)
$ curl -s -X DELETE https://panel.example.com/api/v1/projects/5aee8eea-9f77-4d10-ac21-2fe4a565e666 -H "Authorization: Bearer $SH0_TOKEN"
{"error":{"code":"BAD_REQUEST","key":"project_not_empty","message":"Cannot delete stack: it still has 1 app (my-api). Delete these services first.","params":{"remaining":[{"count":1,"family":"apps","names":"my-api"}]}}}
# Delete an empty stack (HTTP 204, no body)
$ curl -s -X DELETE https://panel.example.com/api/v1/projects/b9b14ce5-7aa4-4c0d-85fe-b6c4b3977e8e -H "Authorization: Bearer $SH0_TOKEN" -o /dev/null -w "%{http_code}\n"
204