Claude-skills bun-docker
Use for Docker with Bun, Dockerfiles, oven/bun image, containerization, and deployments.
install
source · Clone the upstream repo
git clone https://github.com/secondsky/claude-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/secondsky/claude-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/bun/skills/bun-docker" ~/.claude/skills/secondsky-claude-skills-bun-docker && rm -rf "$T"
manifest:
plugins/bun/skills/bun-docker/SKILL.mdsource content
Bun Docker
Deploy Bun applications in Docker containers using official images.
Official Images
# Latest stable docker pull oven/bun # Specific version docker pull oven/bun:1.0.0 # Variants oven/bun:latest # Full image (~100MB) oven/bun:slim # Minimal image (~80MB) oven/bun:alpine # Alpine-based (~50MB) oven/bun:distroless # Distroless (~60MB) oven/bun:debian # Debian-based (~100MB)
Basic Dockerfile
FROM oven/bun:1 AS base WORKDIR /app # Install dependencies COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile # Copy source COPY . . # Run EXPOSE 3000 CMD ["bun", "run", "src/index.ts"]
Multi-Stage Build (Production)
# Build stage FROM oven/bun:1 AS builder WORKDIR /app COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile COPY . . RUN bun run build # Production stage FROM oven/bun:1-slim AS production WORKDIR /app # Copy only production dependencies COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile --production # Copy built assets COPY --from=builder /app/dist ./dist # Run as non-root USER bun EXPOSE 3000 CMD ["bun", "run", "dist/index.js"]
Alpine Image
FROM oven/bun:1-alpine WORKDIR /app # Alpine uses apk for packages RUN apk add --no-cache git COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile COPY . . CMD ["bun", "run", "src/index.ts"]
Distroless Image
# Build stage FROM oven/bun:1 AS builder WORKDIR /app COPY . . RUN bun install --frozen-lockfile RUN bun build src/index.ts --compile --outfile=app # Runtime stage FROM gcr.io/distroless/base COPY --from=builder /app/app /app ENTRYPOINT ["/app"]
Docker Compose
# docker-compose.yml version: "3.8" services: app: build: . ports: - "3000:3000" environment: - NODE_ENV=production - DATABASE_URL=postgres://db:5432/app depends_on: - db restart: unless-stopped db: image: postgres:16-alpine environment: POSTGRES_DB: app POSTGRES_USER: user POSTGRES_PASSWORD: password volumes: - postgres_data:/var/lib/postgresql/data volumes: postgres_data:
Hot Reload in Development
# docker-compose.dev.yml version: "3.8" services: app: build: context: . dockerfile: Dockerfile.dev ports: - "3000:3000" volumes: - ./src:/app/src - ./package.json:/app/package.json command: bun --hot run src/index.ts
# Dockerfile.dev FROM oven/bun:1 WORKDIR /app COPY package.json bun.lockb ./ RUN bun install # Source mounted as volume CMD ["bun", "--hot", "run", "src/index.ts"]
Compiled Binary
FROM oven/bun:1 AS builder WORKDIR /app COPY . . RUN bun install --frozen-lockfile RUN bun build src/index.ts --compile --outfile=server # Minimal runtime FROM ubuntu:22.04 # Install runtime dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ && rm -rf /var/lib/apt/lists/* COPY --from=builder /app/server /usr/local/bin/server USER nobody EXPOSE 3000 CMD ["server"]
SQLite with Docker
FROM oven/bun:1 WORKDIR /app COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile COPY . . # Create data directory RUN mkdir -p /app/data # Volume for SQLite database VOLUME /app/data ENV DATABASE_PATH=/app/data/app.sqlite CMD ["bun", "run", "src/index.ts"]
Health Checks
FROM oven/bun:1 WORKDIR /app COPY . . RUN bun install --frozen-lockfile EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1 CMD ["bun", "run", "src/index.ts"]
// Health endpoint app.get("/health", (c) => c.json({ status: "ok" }));
Environment Variables
FROM oven/bun:1 WORKDIR /app # Build-time args ARG NODE_ENV=production ARG API_URL # Runtime env ENV NODE_ENV=${NODE_ENV} ENV API_URL=${API_URL} COPY . . RUN bun install --frozen-lockfile CMD ["bun", "run", "src/index.ts"]
# Build with args docker build --build-arg API_URL=https://api.example.com -t myapp . # Run with env docker run -e DATABASE_URL=postgres://... myapp
Caching Optimization
FROM oven/bun:1 AS base WORKDIR /app # Cache dependencies separately FROM base AS deps COPY package.json bun.lockb ./ RUN bun install --frozen-lockfile # Build FROM deps AS builder COPY . . RUN bun run build # Production FROM base AS runner COPY --from=deps /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY package.json ./ USER bun CMD ["bun", "run", "dist/index.js"]
Security Best Practices
FROM oven/bun:1-slim WORKDIR /app # Don't run as root USER bun # Copy with correct ownership COPY --chown=bun:bun package.json bun.lockb ./ RUN bun install --frozen-lockfile --production COPY --chown=bun:bun . . # Read-only filesystem # (use with: docker run --read-only) EXPOSE 3000 CMD ["bun", "run", "src/index.ts"]
.dockerignore
node_modules .git .gitignore *.md Dockerfile* docker-compose* .env* .DS_Store coverage dist .bun
Common Commands
# Build docker build -t myapp . # Run docker run -p 3000:3000 myapp # Run with env file docker run --env-file .env -p 3000:3000 myapp # Interactive shell docker run -it oven/bun sh # Check Bun version docker run oven/bun bun --version
Common Errors
| Error | Cause | Fix |
|---|---|---|
| Missing lockfile | Run locally |
| File ownership | Use |
| Memory limit | Increase container memory |
| Large layers | Use multi-stage builds |
When to Load References
Load
references/optimization.md when:
- Image size reduction
- Layer caching
- Build performance
Load
references/kubernetes.md when:
- K8s deployment
- Horizontal scaling
- Service mesh