# Deployment ## Production Build ### Compile to Binary (Recommended) ```bash bun build \ --compile \ --minify-whitespace \ --minify-syntax \ --target bun \ --outfile server \ src/index.ts ``` **Benefits:** - No runtime needed on deployment server - Smaller memory footprint (2-3x reduction) - Faster startup - Single portable executable **Run the binary:** ```bash ./server ``` ### Compile to JavaScript ```bash bun build \ --minify-whitespace \ --minify-syntax \ --outfile ./dist/index.js \ src/index.ts ``` **Run:** ```bash NODE_ENV=production bun ./dist/index.js ``` ## Docker ### Basic Dockerfile ```dockerfile FROM oven/bun:1 AS build WORKDIR /app # Cache dependencies COPY package.json bun.lock ./ RUN bun install COPY ./src ./src ENV NODE_ENV=production RUN bun build \ --compile \ --minify-whitespace \ --minify-syntax \ --outfile server \ src/index.ts FROM gcr.io/distroless/base WORKDIR /app COPY --from=build /app/server server ENV NODE_ENV=production CMD ["./server"] EXPOSE 3000 ``` ### Build and Run ```bash docker build -t my-elysia-app . docker run -p 3000:3000 my-elysia-app ``` ### With Environment Variables ```dockerfile FROM gcr.io/distroless/base WORKDIR /app COPY --from=build /app/server server ENV NODE_ENV=production ENV PORT=3000 ENV DATABASE_URL="" ENV JWT_SECRET="" CMD ["./server"] EXPOSE 3000 ``` ## Cluster Mode (Multiple CPU Cores) ```typescript // src/index.ts import cluster from 'node:cluster' import os from 'node:os' import process from 'node:process' if (cluster.isPrimary) { for (let i = 0; i < os.availableParallelism(); i++) { cluster.fork() } } else { await import('./server') console.log(`Worker ${process.pid} started`) } ``` ```typescript // src/server.ts import { Elysia } from 'elysia' new Elysia() .get('/', () => 'Hello World!') .listen(3000) ``` ## Environment Variables ### .env File ```env NODE_ENV=production PORT=3000 DATABASE_URL=postgresql://user:password@localhost:5432/db JWT_SECRET=your-secret-key CORS_ORIGIN=https://example.com ``` ### Load in App ```typescript import { Elysia } from 'elysia' const app = new Elysia() .get('/env', () => ({ env: process.env.NODE_ENV, port: process.env.PORT })) .listen(parseInt(process.env.PORT || '3000')) ``` ## Platform-Specific Deployments ### Railway ```typescript // Railway assigns random PORT via env variable new Elysia() .get('/', () => 'Hello Railway') .listen(process.env.PORT ?? 3000) ``` ### Vercel ```typescript // src/index.ts import { Elysia } from 'elysia' export default new Elysia() .get('/', () => 'Hello Vercel') export const GET = app.fetch export const POST = app.fetch ``` ```json // vercel.json { "$schema": "https://openapi.vercel.sh/vercel.json", "bunVersion": "1.x" } ``` ### Cloudflare Workers ```typescript import { Elysia } from 'elysia' import { CloudflareAdapter } from 'elysia/adapter/cloudflare-worker' export default new Elysia({ adapter: CloudflareAdapter }) .get('/', () => 'Hello Cloudflare!') .compile() ``` ```toml # wrangler.toml name = "elysia-app" main = "src/index.ts" compatibility_date = "2025-06-01" ``` ### Node.js Adapter ```typescript import { Elysia } from 'elysia' import { node } from '@elysiajs/node' const app = new Elysia({ adapter: node() }) .get('/', () => 'Hello Node.js') .listen(3000) ``` ## Performance Optimization ### Enable AoT Compilation ```typescript new Elysia({ aot: true // Ahead-of-time compilation }) ``` ### Use Native Static Response ```typescript new Elysia({ nativeStaticResponse: true }) .get('/version', 1) // Optimized for Bun.serve.static ``` ### Precompile Routes ```typescript new Elysia({ precompile: true // Compile all routes ahead of time }) ``` ## Health Checks ```typescript new Elysia() .get('/health', () => ({ status: 'ok', timestamp: Date.now() })) .get('/ready', ({ db }) => { // Check database connection const isDbReady = checkDbConnection() if (!isDbReady) { return status(503, { status: 'not ready' }) } return { status: 'ready' } }) ``` ## Graceful Shutdown ```typescript import { Elysia } from 'elysia' const app = new Elysia() .get('/', () => 'Hello') .listen(3000) process.on('SIGTERM', () => { console.log('SIGTERM received, shutting down gracefully') app.stop() process.exit(0) }) process.on('SIGINT', () => { console.log('SIGINT received, shutting down gracefully') app.stop() process.exit(0) }) ``` ## Monitoring ### OpenTelemetry ```typescript import { opentelemetry } from '@elysiajs/opentelemetry' new Elysia() .use(opentelemetry({ serviceName: 'my-service', endpoint: 'http://localhost:4318' })) ``` ### Custom Logging ```typescript .onRequest(({ request }) => { console.log(`[${new Date().toISOString()}] ${request.method} ${request.url}`) }) .onAfterResponse(({ request, set }) => { console.log(`[${new Date().toISOString()}] ${request.method} ${request.url} - ${set.status}`) }) ``` ## SSL/TLS (HTTPS) ```typescript import { Elysia, file } from 'elysia' new Elysia({ serve: { tls: { cert: file('cert.pem'), key: file('key.pem') } } }) .get('/', () => 'Hello HTTPS') .listen(3000) ``` ## Best Practices 1. **Always compile to binary for production** - Reduces memory usage - Smaller deployment size - No runtime needed 2. **Use environment variables** - Never hardcode secrets - Use different configs per environment 3. **Enable health checks** - Essential for load balancers - K8s/Docker orchestration 4. **Implement graceful shutdown** - Handle SIGTERM/SIGINT - Close connections properly 5. **Use cluster mode** - Utilize all CPU cores - Better performance under load 6. **Monitor your app** - Use OpenTelemetry - Log requests/responses - Track errors ## Example Production Setup ```typescript // src/server.ts import { Elysia } from 'elysia' import { cors } from '@elysiajs/cors' import { opentelemetry } from '@elysiajs/opentelemetry' export const app = new Elysia({ aot: true, nativeStaticResponse: true }) .use(cors({ origin: process.env.CORS_ORIGIN || 'http://localhost:3000' })) .use(opentelemetry({ serviceName: 'my-service' })) .get('/health', () => ({ status: 'ok' })) .get('/', () => 'Hello Production') .listen(parseInt(process.env.PORT || '3000')) // Graceful shutdown process.on('SIGTERM', () => { app.stop() process.exit(0) }) ``` ```typescript // src/index.ts (cluster) import cluster from 'node:cluster' import os from 'node:os' if (cluster.isPrimary) { for (let i = 0; i < os.availableParallelism(); i++) { cluster.fork() } } else { await import('./server') } ``` ```dockerfile # Dockerfile FROM oven/bun:1 AS build WORKDIR /app COPY package.json bun.lock ./ RUN bun install COPY ./src ./src ENV NODE_ENV=production RUN bun build --compile --outfile server src/index.ts FROM gcr.io/distroless/base WORKDIR /app COPY --from=build /app/server server ENV NODE_ENV=production CMD ["./server"] EXPOSE 3000 ```