Ir al contenido

Buscar en la documentación

Busca en la documentación de Skiffly

Servicios

Un servicio es una unidad desplegable, construida desde un repositorio de GitHub o descargada como imagen Docker. Esta página cubre builders, comandos de inicio, health checks, recursos, réplicas, tareas cron y App Sleeping.

Orígenes#

OrigenCómo se construyeSe despliega con
Repositorio de GitHub (owner/repo, rama, directorio raíz opcional)Railpack, o el Dockerfile del repositoriocada push a la rama seguida, skiffly up, volver a desplegar
Imagen Docker (ghcr.io/org/app:1.2.3, postgres:17)no se construye, el nodo la descargadespliegue manual, cambio de tag de la imagen

Los repositorios privados necesitan la GitHub App de Skiffly (Configuración → Desarrollador → Conectar GitHub). Los registros privados todavía no están soportados: haz push a un registro público o construye desde un repositorio.

Nuevo servicio en el lienzo del proyecto → Repositorio de GitHub, Imagen Docker o Plantilla. Para un repositorio, elige la rama. Por ahora, el directorio raíz, la ruta del Dockerfile, el puerto y el comando de build se configuran a través de la CLI, la API, update-service de MCP o configuración como código.

Builds#

Railpack (predeterminado) inspecciona el repositorio y produce una imagen para Node, Bun, Python, Go, Rust, PHP, Ruby, Java, Elixir, sitios estáticos y más. Lee los archivos habituales (scripts de package.json, requirements.txt, go.mod, …), así que la mayoría de los proyectos no necesita configuración.

Dockerfile: cuando el repositorio (o el directorio raíz) contiene un Dockerfile, se usa automáticamente. Define otra ruta con dockerfilePath y fuerza un builder con builder: RAILPACK | DOCKERFILE (serviceUpdate, skiffly config, update-service de MCP).

Otras opciones del build: comando de build (reemplaza el paso de build de Railpack) y directorio raíz (monorepos: el build se ejecuta dentro de él). Los patrones de watch los acepta la API, pero todavía no se aplican: cada push a la rama despliega.

Los builds corren en una microVM Kata con BuildKit y caché de capas; la imagen queda en un registro en el nodo. Como máximo corren dos builds a la vez por nodo; un build en cola muestra waiting for a build slot en su log.

Comando de inicio y puerto#

Railpack deduce el comando de inicio (npm start, gunicorn …, el binario compilado). Reemplázalo en Configuración → Despliegue → Comando de inicio del servicio o con startCommand; para una imagen Docker, el comando de inicio reemplaza a CMD.

El servicio debe escuchar en $PORT. Skiffly asigna a PORT el puerto del servicio (port en el servicio, 8080 si no está definido) y enruta hacia él el dominio público y el hostname privado. Los servicios creados desde plantillas ya vienen con el puerto correcto.

Health checks#

Con una ruta de health check (/healthz), el nodo consulta GET <ruta> en el puerto del servicio: un despliegue nuevo recibe tráfico solo cuando la comprobación pasa, y un contenedor que falla la comprobación tres veces seguidas se reinicia. Sin ruta, la sonda es una conexión TCP al puerto. El arranque tiene hasta cinco minutos (una sonda cada 5 s, 60 intentos) antes de que el despliegue se marque como FAILED, así que las migraciones al arrancar no son problema. healthcheckTimeout ajusta el tiempo de espera de cada sonda.

Recursos y réplicas#

Cada réplica recibe un límite de CPU y memoria: 2 vCPU / 2 GiB de forma predeterminada, modificable en Configuración → Recursos dentro de los límites de tu plan. La memoria nunca se sobreasigna; la CPU puede subir hasta el límite. La facturación cuenta el límite reservado mientras la réplica corre.

Las réplicas (numReplicas) ejecutan copias idénticas detrás del mismo dominio; las solicitudes se balancean entre ellas. Los volúmenes no se pueden compartir, así que un servicio con volumen corre con una sola réplica.

skiffly api 'mutation { serviceInstanceUpdate(serviceId: "…", environmentId: "…", input: { numReplicas: 2, cpuMillis: 1000, memoryBytes: 1073741824 }) }'

Política de reinicio#

ON_FAILURE (predeterminada, hasta restartPolicyMaxRetries), ALWAYS o NEVER. Un contenedor que no deja de caerse (tres reinicios seguidos) pone el despliegue en CRASHED; las últimas líneas del log se muestran en el mensaje del despliegue.

Tareas cron#

Define una programación cron (0 3 * * *, UTC) en un servicio y dejará de ser un proceso de larga duración: en cada tick se inicia un contenedor con el comando de inicio y se espera a que termine. Las ejecuciones no se solapan; nextCronRunAt muestra el siguiente tick. Los servicios cron no reciben dominio y no se ponen en reposo.

App Sleeping#

Activa App Sleeping (sleepApplication: true) para servicios HTTP que pasan la mayor parte del tiempo inactivos. Tras unos 10 minutos sin solicitudes a través del dominio público, el servicio se escala a cero y su despliegue muestra SLEEPING; la siguiente solicitud lo despierta (normalmente 2–10 s, quien hace la solicitud espera) y el tráfico se reanuda. Un servicio en reposo no se factura por CPU ni memoria; su volumen sí.

El reposo necesita un dominio público y aplica solo a servicios HTTP sin proxy TCP; los servicios cron y los workers que solo hacen solicitudes salientes no pueden despertarse y se dejan como están. La opción se aplica de inmediato, sin volver a desplegar.

Runtime de aislamiento#

Los servicios corren en gVisor (runtimeClass: gvisor) de forma predeterminada. Algunas imágenes necesitan un kernel completo (bases de datos que usan io_uring, cualquier cosa con multihilo SO_REUSEPORT, FUSE); cambia ese servicio a Kata (runtimeClass: kata), una microVM ligera. Consulta Seguridad.

Eliminar un servicio#

Configuración → Zona de peligro → Eliminar, skiffly service delete o serviceDelete(id). La eliminación quita la carga de trabajo en todos los entornos, los dominios y los volúmenes.