#Bare Deployment
The default deployment target. alepha build produces a self-contained dist/ folder that runs on any machine with Node.js or Bun installed.
#Build
alepha build
This bundles both server and client code into a single optimized output. The server bundle includes all dependencies -- no npm install is needed in production.
#Run
node dist # Node.js
bun dist # Bun
The server starts on http://localhost:3000 by default. Configure the host and port with environment variables:
SERVER_HOST=0.0.0.0 SERVER_PORT=8080 node dist
#Output Structure
dist/
index.js # Server entry point
public/ # Client assets (if React frontend exists)
Database migrations stay in your project's migrations/ directory — run them with alepha db migrations apply against the target database (the docker target copies them into the image for you).
If no React frontend is present, only index.js is generated.
#Runtime Flag
Optimize the build for a specific runtime:
alepha build --runtime=bun
The --runtime=bun flag uses Bun-specific export conditions during bundling.
#Configuration
Set the target in alepha.config.ts to avoid passing flags:
1import { defineConfig } from "alepha/cli/config";2 3export default defineConfig({4 build: {5 target: "bare",6 runtime: "node",7 },8});
bare is the default target. You do not need to set it explicitly unless you want to override a different default.
#Deployment
Copy the dist/ folder to any server and run it. No build tools, no package managers, no configuration files required on the target machine.
Works on:
- VPS (DigitalOcean, Hetzner, Linode)
- Bare metal servers
- Any container runtime
- systemd, PM2, or any process manager
#Multi-replica $job cron jobs
When you run more than one replica (e.g. 10 Docker instances behind a load balancer), $job({ cron, ... }) acquires a per-job distributed lock by default so the handler runs once per tick across the fleet, not once per replica. The default MemoryLockProvider is per-process — to get cross-replica coordination, register a real lock provider:
1import { AlephaLockRedis } from "alepha/lock/redis";2 3const app = Alepha.create()4 .with(AlephaLockRedis) // Redis-backed lock store5 .with(AlephaApiJobs);
Set lock: false on a $job if you genuinely want every replica to fire the handler.
#Retry granularity
$job retries are sweep-driven on every platform: no exponential backoff. A failing handler is rescheduled with scheduledAt = now and the next sweep tick (default */15 * * * *, configurable via jobConfig.sweepCron) picks it up. Lower sweepCron if you need tighter retry latency.