Documentación / Conceptos fundamentales / Variables de entorno

Variables de entorno

Las variables de entorno configuran sus aplicaciones sin poner secretos en el código. Se definen por aplicación o se comparten en todo un stack, se guardan cifradas y se inyectan en el contenedor en el siguiente despliegue.

Añadir variables

Una clave usa letras mayúsculas, dígitos y guiones bajos, y empieza por una letra o un guion bajo (DATABASE_URL, _INTERNAL). Una clave en minúsculas se rechaza con 422.

Desde el panel

  1. Abra la aplicación (Stacks, luego el stack y luego la aplicación) y su pestaña Entorno.
  2. En el modo Clave-Valor, escriba la clave y el valor. Marque Build si el valor solo se necesita al construir la imagen.
  3. Haga clic en Agregar variable. Los valores se muestran ocultos; Revelar los muestra y requiere al menos el rol Developer en la aplicación.

Desde la CLI

sh0 env <app> set recibe un par CLAVE=VALOR y --build para una variable de build; list nunca muestra los valores.

Terminal
$ sh0 env my-api set LOG_LEVEL=info
[ok] Set LOG_LEVEL for 'my-api'
$ sh0 env my-api set GREETING_BUILD=hello --build
[ok] Set GREETING_BUILD for 'my-api'
$ sh0 env my-api list
  KEY             VALUE    BUILD  CREATED
  --------------  -------  -----  -------
  LOG_LEVEL       *******  no     0s ago
  GREETING_BUILD  *******  yes    0s ago

Desde la API

Las rutas son /api/v1/apps/:id/env-vars (GET, POST) y /api/v1/apps/:id/env-vars/:env_id (PATCH, DELETE). Las respuestas siempre ocultan el valor; añada ?reveal=true al GET para leerlo.

Terminal
$ curl -s -X POST https://panel.example.com/api/v1/apps/e17d4314-ff61-485a-a509-58b3974c1eee/env-vars \
    -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
    -d '{"key":"DATABASE_URL","value":"postgres://app:[email protected]:5432/appdb"}'
{"data":{"app_id":"e17d4314-ff61-485a-a509-58b3974c1eee","created_at":"2026-10-02T02:49:26.463374291+00:00","id":"68ddf6a1-d9e0-49e4-9893-c320eaa58b62","is_build":false,"key":"DATABASE_URL","value":"*****"}}

$ curl -s -X PATCH https://panel.example.com/api/v1/apps/e17d4314-ff61-485a-a509-58b3974c1eee/env-vars/68ddf6a1-d9e0-49e4-9893-c320eaa58b62 \
    -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
    -d '{"value":"postgres://app:[email protected]:5432/appdb"}'
{"data":{"app_id":"e17d4314-ff61-485a-a509-58b3974c1eee","created_at":"2026-10-02 02:49:26","id":"68ddf6a1-d9e0-49e4-9893-c320eaa58b62","is_build":false,"key":"DATABASE_URL","value":"*****"}}
Warning
Añadir una clave que ya existe no la actualiza: la API responde 201 y la aplicación queda con dos entradas con la misma clave. Para cambiar un valor, edite la variable existente (PATCH, o Editar en el panel).

Cuándo se aplican los cambios

Guardar una variable no reinicia nada. El contenedor en ejecución conserva su entorno anterior hasta el siguiente despliegue, desde el panel o con sh0 deploy <app>.

Las variables de build se pasan a docker build como --build-arg; el Dockerfile debe declararlas con ARG. No están en el contenedor en ejecución. Para una aplicación desplegada por envío de archivo (sh0 push), un nuevo despliegue reutiliza la última imagen: las variables de ejecución cambian, pero un nuevo valor de build solo se aplica en el siguiente sh0 push.

Observado en una aplicación de prueba tras un nuevo despliegue (la variable de build GREETING_BUILD llegó a la imagen, no al entorno):

Terminal
$ docker exec <container> env | grep -E '^(LOG_LEVEL|REGION|GREETING_BUILD)='
REGION=eu-central
LOG_LEVEL=info
$ docker exec <container> cat /build-arg.txt
hello

Edición masiva (.env)

La pestaña Entorno acepta líneas CLAVE=VALOR, una por línea; los comentarios (#) y las líneas vacías se ignoran. Las dos vías se comportan de forma distinta:

  • Pegar .env y luego Analizar y agregar añade cada línea como nueva variable y deja las demás intactas (una clave existente se duplica, ver arriba).
  • El Editor .env y luego Guardar todo reemplaza todas las variables de la aplicación por el contenido del editor. El equivalente en la API es PUT /api/v1/apps/:id/env-vars/bulk con un arreglo entries: toda clave ausente del arreglo se elimina.

Variables de stack

Una variable definida en un stack la leen todas las aplicaciones de ese stack. Abra el stack y use Variables compartidas en el panel Red interna y ajustes compartidos, o la API /api/v1/projects/:id/env-vars (un stack es un proyecto en la API). Enviar una clave existente la actualiza. Los valores de stack nunca se devuelven, ni siquiera a un administrador.

Terminal
$ curl -s -X POST https://panel.example.com/api/v1/projects/5aee8eea-9f77-4d10-ac21-2fe4a565e666/env-vars \
    -H "Authorization: Bearer $SH0_TOKEN" -H "Content-Type: application/json" \
    -d '{"key":"REGION","value":"eu-central"}'
{"data":{"created_at":"2026-10-02 02:49:26","id":"e89e5915-e5dd-4878-b1b6-b6df150df54d","is_build":false,"key":"REGION","project_id":"5aee8eea-9f77-4d10-ac21-2fe4a565e666","updated_at":"2026-10-02 02:49:26"}}

Cuando la misma clave existe en ambos niveles, gana la aplicación, y el registro del despliegue enumera las variables de stack sobrescritas. En el ejemplo siguiente, el stack define LOG_LEVEL=debug y REGION=eu-central, y la aplicación LOG_LEVEL=info:

Cifrado en reposo

Cada valor se cifra con AES-256-GCM antes de escribirse en la base de datos de sh0. La clave es la clave maestra de la instancia, guardada en master.key y protegida por master.passphrase (PBKDF2), ambos en el directorio de datos de sh0 (/var/lib/sh0 en una instalación Linux estándar).

Warning
Sin master.key y master.passphrase, los valores guardados (y las copias cifradas) no se pueden descifrar. Guarde una copia de ambos archivos fuera del servidor.

Conectar con otros servicios

sh0 no expande referencias: un valor como $OTHER_VAR llega al contenedor tal cual. Escriba el valor completo con los nombres de host internos: una aplicación alcanza otra del mismo stack en <nombre-app> o <nombre-app>.internal, y cualquier servidor de bases de datos en <nombre-servidor>.internal.

Lo que sh0 no inyecta

  • Ninguna variable de sistema. sh0 no añade variables SH0_* (nombre de aplicación, dominio, commit) a sus contenedores. Única excepción: una aplicación Laravel o Lumen sin APP_KEY recibe una, generada en el primer despliegue y guardada como variable de la aplicación.
  • Variables en las tareas programadas. Una tarea vinculada a una aplicación recibe las variables de ejecución de la aplicación y del proyecto, en un contenedor desechable creado desde la imagen de la aplicación: consulte Tareas programadas.