Get the FREE Ultimate OpenClaw Setup Guide →

bun-deploy

Scanned
npx machina-cli add skill DaleSeo/bun-skills/bun-deploy --openclaw
Files (1)
SKILL.md
7.6 KB

Bun Docker Deployment

Create optimized Docker images for Bun applications. Bun's small runtime and binary compilation reduce image sizes by 88MB+ compared to Node.js.

Quick Reference

For detailed patterns, see:

Core Workflow

1. Check Prerequisites

# Verify Docker is installed
docker --version

# Verify Bun is installed locally
bun --version

# Check if project is ready for deployment
ls -la package.json bun.lockb

2. Determine Deployment Strategy

Ask the user about their needs:

  • Application Type: Web server, API, worker, or CLI
  • Image Size Priority: Minimal size (40MB binary) vs. debugging tools (90MB Alpine)
  • Platform: Single platform or multi-platform (AMD64 + ARM64)
  • Orchestration: Docker Compose, Kubernetes, or standalone containers

3. Create Production Dockerfile

Choose the appropriate template based on needs:

Standard Multi-Stage (Recommended)

# syntax=docker/dockerfile:1

FROM oven/bun:1-alpine AS deps
WORKDIR /app
COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile --production

FROM oven/bun:1-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN bun run build

FROM oven/bun:1-alpine AS runtime
WORKDIR /app

RUN addgroup --system --gid 1001 bunuser && \
    adduser --system --uid 1001 bunuser

COPY --from=deps --chown=bunuser:bunuser /app/node_modules ./node_modules
COPY --from=builder --chown=bunuser:bunuser /app/dist ./dist
COPY --from=builder --chown=bunuser:bunuser /app/package.json ./

USER bunuser
EXPOSE 3000

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD bun run healthcheck.ts || exit 1

CMD ["bun", "run", "dist/index.js"]

Minimal Binary (40MB)

For smallest possible images:

FROM oven/bun:1-alpine AS builder
WORKDIR /app

COPY package.json bun.lockb ./
RUN bun install --frozen-lockfile

COPY . .
RUN bun build ./src/index.ts --compile --outfile server

FROM gcr.io/distroless/base-debian12
COPY --from=builder /app/server /server
EXPOSE 3000
ENTRYPOINT ["/server"]

For other scenarios (monorepo, database apps, CLI tools, etc.), see dockerfile-templates.md.

4. Create .dockerignore

node_modules
bun.lockb
dist
*.log
.git
.env
.env.local
tests/
*.test.ts
coverage/
.vscode/
.DS_Store
Dockerfile
docker-compose.yml

5. Create Health Check Script

Create healthcheck.ts:

#!/usr/bin/env bun

const port = process.env.PORT || 3000;
const healthEndpoint = process.env.HEALTH_ENDPOINT || '/health';

try {
  const response = await fetch(`http://localhost:${port}${healthEndpoint}`, {
    method: 'GET',
    timeout: 2000,
  });

  if (response.ok) {
    process.exit(0);
  } else {
    console.error(`Health check failed: ${response.status}`);
    process.exit(1);
  }
} catch (error) {
  console.error('Health check error:', error);
  process.exit(1);
}

Add health endpoint to your server:

app.get('/health', (req, res) => {
  res.json({
    status: 'ok',
    timestamp: Date.now(),
    uptime: process.uptime(),
  });
});

6. Build and Test Image

# Build image
docker build -t myapp:latest .

# Check image size
docker images myapp:latest

# Run container
docker run -p 3000:3000 myapp:latest

# Test health endpoint
curl http://localhost:3000/health

7. Setup for Environment

For Local Development with Docker Compose:

Create docker-compose.yml:

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
    depends_on:
      - db
      - redis

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    ports:
      - "5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

Run with: docker-compose up

For Kubernetes Deployment:

See kubernetes.md for complete manifests including:

  • Deployment configuration
  • Service and Ingress
  • Secrets and ConfigMaps
  • Horizontal Pod Autoscaling
  • Resource limits optimized for Bun

For CI/CD:

See ci-cd.md for:

  • GitHub Actions workflow
  • GitLab CI configuration
  • Build and push scripts
  • Automated deployments

For Multi-Platform (ARM64 + AMD64):

See multi-platform.md for:

  • Multi-platform Dockerfile
  • Buildx configuration
  • Testing on different architectures

8. Update package.json

Add Docker scripts:

{
  "scripts": {
    "docker:build": "docker build -t myapp:latest .",
    "docker:run": "docker run -p 3000:3000 myapp:latest",
    "docker:dev": "docker-compose up",
    "docker:clean": "docker system prune -af"
  }
}

Image Size Comparison

Bun produces significantly smaller images:

ConfigurationSizeUse Case
Bun Binary (distroless)~40 MBProduction (minimal)
Bun Alpine~90 MBProduction (standard)
Node.js Alpine~180 MBBaseline comparison

88MB+ savings with Bun!

Security Best Practices

  1. Use non-root user (included in Dockerfiles above)
  2. Scan for vulnerabilities: docker scan myapp:latest
  3. Use official base images: oven/bun is official
  4. Keep images updated: Rebuild regularly with latest Bun
  5. Never hardcode secrets: Use environment variables or secret managers

Optimization Tips

Layer caching:

# Copy dependencies first (changes less often)
COPY package.json bun.lockb ./
RUN bun install

# Copy source code last (changes more often)
COPY . .
RUN bun run build

Reduce layer count:

# Combine RUN commands
RUN bun install && \
    bun run build && \
    rm -rf tests/

Minimize final image:

# Only copy what's needed in runtime
COPY --from=builder /app/dist ./dist
# Don't copy: src/, tests/, .git/, node_modules (if using binary)

Completion Checklist

  • ✅ Dockerfile created (multi-stage or binary)
  • ✅ .dockerignore configured
  • ✅ Health check implemented
  • ✅ Non-root user configured
  • ✅ Image built and tested locally
  • ✅ Image size verified (<100MB for Alpine, <50MB for binary)
  • ✅ Environment configuration ready (docker-compose or K8s)
  • ✅ CI/CD pipeline configured (if needed)

Next Steps

After basic deployment:

  1. Monitoring: Add Prometheus metrics endpoint
  2. Logging: Configure structured logging
  3. Secrets: Set up proper secret management
  4. Scaling: Configure horizontal pod autoscaling (K8s)
  5. CI/CD: Automate builds and deployments
  6. Multi-region: Deploy to multiple regions for redundancy

For detailed implementations, see the reference files linked above.

Source

git clone https://github.com/DaleSeo/bun-skills/blob/main/skills/bun-deploy/SKILL.mdView on GitHub

Overview

Generates production-ready Docker images for Bun apps with a focus on minimal size and solid defaults. Bun’s small runtime and binary compilation can shrink images by 88MB+ versus Node.js, speeding deployments and reducing resource usage.

How This Skill Works

Follow a concise core workflow: verify Docker and Bun are installed and the project is ready, decide deployment strategy (application type, size, platform, orchestration), and generate a production Dockerfile using the appropriate template (Standard Multi-Stage or Minimal Binary). Add a .dockerignore, health check script, and then build and test the image before deployment.

When to Use It

  • Deploy Bun applications to containers with the smallest feasible image size
  • Set up CI/CD pipelines for Bun-based projects
  • Deploy Bun apps to Kubernetes, Docker Compose, or standalone containers
  • Build multi-arch images (AMD64 and ARM64) for cross-platform deployment
  • Handle monorepos or CLI tools built with Bun that require optimized packaging

Quick Start

  1. Step 1: Verify Docker and Bun are installed and the project is ready (package.json, bun.lockb).
  2. Step 2: Choose deployment strategy and corresponding template based on app type and size.
  3. Step 3: Create the production Dockerfile, add a .dockerignore, implement a health check, then build and test the image.

Best Practices

  • Start with the Standard Multi-Stage template for a balance of size and debuggability
  • When possible, use the Minimal Binary template to achieve ~40MB images
  • Lock dependencies with bun.lockb and use bun install --frozen-lockfile --production
  • Keep the build context lean with a comprehensive .dockerignore
  • Run as a non-root user (bunuser) and define a robust HEALTHCHECK

Example Use Cases

  • Web API service compiled with Bun and deployed to Kubernetes using a multi-stage Dockerfile
  • Monorepo containing multiple Bun apps leveraging shared dockerfile-templates
  • Tiny Bun-based CLI tool packaged in a minimal container using the Minimal Binary approach
  • CI/CD workflow that builds and pushes Bun images for multi-arch support
  • Production server image using Distroless or minimal runtime for security and efficiency

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers