Stacks
Un stack agrupa las aplicaciones y servicios de un proyecto. Sus miembros comparten una red privada y un conjunto de variables, y pueden desplegarse juntos en un orden definido.
¿Qué es un stack?
En la API y la CLI, un stack se llama proyecto: /api/v1/projects y sh0 projects gestionan los stacks. Un stack ofrece a sus aplicaciones:
- Una red privada en la que cada aplicación responde a
<nombre-app>y<nombre-app>.internal. El nombre de host no cambia cuando la aplicación se vuelve a desplegar. - Variables compartidas, que leen todas las aplicaciones del stack.
- Un orden de arranque, usado cuando se despliega todo el stack a la vez.
Las aplicaciones de stacks distintos no se ven por su nombre. Los servidores de bases de datos están fuera de los stacks: cualquier aplicación los alcanza en <nombre-servidor>.internal.
Crear un stack
En el panel, abra Stacks, haga clic en Crear Stack, escriba un Nombre del Stack (de 1 a 100 caracteres) y una Descripción opcional. Desde la CLI:
$ sh0 projects create my-shop
Project created: my-shop (5aee8eea-9f77-4d10-ac21-2fe4a565e666)sh0 push --project espera el identificador del stack que se muestra aquí; el nombre no se acepta.Página de un stack
Al abrir un stack se muestran sus servicios agrupados por tipo, y además:
- Agregar app, que abre la página de despliegue para este stack; Configuración del Stack; Exportar instantánea e Importar instantánea.
- El panel Red interna y ajustes compartidos: el nombre de host interno de cada servicio, las Variables compartidas, el Orden de arranque y Desplegar el proyecto, que despliega todas las aplicaciones en ese orden.
Variables del stack
Una variable compartida se inyecta en cada aplicación del stack en su siguiente despliegue. Si una aplicación define la misma clave, gana el valor de la aplicación. Detalles, API y prioridad: Variables de entorno.
Configuración del stack
Configuración del Stack edita el nombre, la descripción, el color y los miembros, e incluye Eliminar Stack.
Usos habituales
- Un stack por producto: el frontend, la API y los workers que deben alcanzarse por su nombre.
- Un stack por entorno: preproducción y producción separadas, cada una con sus variables compartidas.
- Un stack por cliente: gracias a los miembros del stack, las aplicaciones de cada cliente solo son visibles para las personas asignadas.
Gestionar stacks por la API
Las rutas están bajo /api/v1/projects. Las actualizaciones usan PATCH; PUT responde 405. Una solicitud sin /v1 no llega a la API: devuelve la página del panel. Las salidas siguientes se obtuvieron en una instancia de prueba:
# 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