Bun
Despliega apps de Bun en Skiffly con Railpack — cómo un `bun.lock` cambia el build, `bun run start` frente a `bun src/index.ts`, `Bun.serve` en `PORT`, Elysia y Hono, bases de datos y las diferencias con la ruta de Node.
Railpack no tiene un proveedor separado para Bun: un repositorio con package.json lo maneja el proveedor de Node, y un lockfile de Bun cambia el gestor de paquetes y los comandos de runtime a Bun. Todo lo que dice la página de Node.js sobre puertos, variables, migraciones y health checks aplica aquí; esta página enumera lo que es distinto.
Qué detecta Railpack#
| Mira | Efecto |
|---|---|
bun.lock o bun.lockb (o "packageManager": "bun@1.x") | las dependencias se instalan con bun install --frozen-lockfile; los scripts se ejecutan con bun run |
scripts.start | comando de inicio bun run start |
sin script start: main en package.json, luego index.ts/index.js | bun <archivo> |
scripts.build | bun run build en el paso de build |
.bun-version, packageManager, mise.toml/.tool-versions | la versión de Bun (por defecto: la última estable) |
engines.node, .nvmrc | se instala Node junto a Bun para los módulos nativos que compilan con node-gyp |
Bun ejecuta TypeScript directamente, así que un servicio típico no tiene paso de build: "start": "bun src/index.ts".
Puerto#
Bun.serve({
port: Number(process.env.PORT ?? 3000),
hostname: "0.0.0.0",
fetch: (req) => new Response("ok"),
});Bun.serve usa 0.0.0.0 por defecto y lee PORT solo cuando se lo pasas; Elysia (app.listen(process.env.PORT ?? 3000)) y Hono (export default { port: Number(process.env.PORT ?? 3000), fetch: app.fetch }) siguen la misma regla. Skiffly asigna a PORT el puerto del servicio (8080 cuando no se define).
Bases de datos#
skiffly deploy --template postgres
skiffly variables set 'DATABASE_URL=${{Postgres.DATABASE_URL}}'Bun.sql (cliente de Postgres integrado, lee DATABASE_URL automáticamente), postgres.js, Drizzle con bun-sql o postgres.js, y Prisma funcionan. Los binarios del motor de Prisma necesitan prisma generate en el build ("build": "prisma generate"); el motor de consultas corre en Bun sin flags adicionales. Redis: Bun.redis / ioredis con REDIS_URL=${{Redis.REDIS_URL}}.
Migraciones: no hay fase de release — sh -c "bunx drizzle-kit migrate && bun src/index.ts" como comando de inicio, o skiffly ssh -- bunx drizzle-kit migrate como comando puntual.
Diferencias con la ruta de Node#
- Las dependencias de desarrollo se instalan (Railpack las necesita para los scripts de
build). AgregaRAILPACK_PRUNE_DEPS=truepara eliminarlas de la imagen. bun installrespetatrustedDependenciespara los scripts postinstall; los paquetes con builds nativos (sharp,better-sqlite3) necesitan que Node esté presente, y Railpack lo agrega cuando se declaraengines.node.- Los workspaces (
workspacesenpackage.json) se instalan desde la raíz; para un monorepo, define el comando de inicio comobun run --filter api startobun apps/api/src/index.ts. - Los binarios únicos de
bun build --compileno son necesarios; si de todos modos generas uno en el paso de build, define el comando de inicio como./app.
Health check#
Los workers sin servidor HTTP fallan el sondeo del rollout (consulta Node.js); Bun.serve con una ruta /healthz cuesta una línea. Agrega una ruta /healthz y define la ruta del health check para que los rollouts cambien el tráfico solo cuando el nuevo contenedor responda.
Problemas comunes#
| Síntoma | Solución |
|---|---|
error: lockfile had changes, but lockfile is frozen | ejecuta bun install en local y haz commit de bun.lock |
FAILED a los 5 minutos, el log muestra Listening on localhost:3000 | pasa port: process.env.PORT y hostname: "0.0.0.0" |
Railpack ejecuta npm install en lugar de Bun | no hay lockfile de Bun en el repositorio: haz commit de bun.lock o define packageManager |
Cannot find module "node:…" en runtime | una API de Node no implementada en tu versión de Bun: fija una versión más reciente con .bun-version |
| Un módulo nativo no compila | agrega engines.node para que Node/node-gyp estén disponibles, o elige una alternativa en JS puro |
Ejemplo#
import { defineSkiffly, github, postgres, project, service } from "@skiffly/config";
export default defineSkiffly(() => {
const db = postgres("db");
const api = service("api", {
source: github("acme/bun-api"),
start: "bun src/index.ts",
healthcheck: "/healthz",
port: 3000,
env: { DATABASE_URL: db.env.DATABASE_URL, RAILPACK_PRUNE_DEPS: "true" },
domain: true,
});
return project("bun-api", { resources: [db, api] });
});Landing: /deploy/bun