bun-docker について
bun-dockerは、公式Bunイメージを使ってBunアプリをDockerコンテナにデプロイするためのスキルです。本番・開発向けのビルド構成、実行バイナリの作成、イメージキャッシュ、コンテナのセキュリティに関する内容を扱います。
主な機能
- 01公式Bun Dockerイメージの利用
- 02マルチステージおよびAlpineビルド
- 03開発時のホットリロード設定
- 04実行可能バイナリのコンパイル
- 05キャッシュ、ヘルスチェック、安全性の指針
活用シーン
- 01Bunアプリ用Dockerfileの作成
- 02本番用コンテナイメージのビルド
- 03Docker Composeでのホットリロード設定
- 04コンテナのビルドや実行エラーの調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill bun-dockerインストール後、Claude Code で/bun-dockerを入力して読み込まれたか確認します。
詳細
Bun Docker
公式イメージを使用して、Docker コンテナで Bun アプリケーションをデプロイします。
公式イメージ
# Latest stable
docker pull oven/bun
# Specific version
docker pull oven/bun:1
# 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)
基本的な 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"]
マルチステージビルド(本番環境)
# 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 イメージ
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 イメージ
# 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:
開発環境でのホットリロード
# 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"]
コンパイル済みバイナリ
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"]
Docker での SQLite
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"]
ヘルスチェック
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" }));
環境変数
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
キャッシュの最適化
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"]
安全なインストール
Docker ビルドでパッケージをインストールする際は、サプライチェーンセキュリティのベストプラクティスに従ってください。
- インストール後のスクリプトをブロックする — Bun ではデフォルトで無効になっています。
trustedDependenciesを使って、特定のパッケージを許可できます - 依存関係のバージョンを固定する — 再現可能なビルドのため、
package.jsonでは正確なバージョンを指定してください - インストール前に監査する — パッケージがイメージに含まれる前に、
socket package score npm <pkg>を実行して確認してください
dependency-upgrade スキルを読み込み、Socket CLI の統合、クールダウンの設定、ロックファイルの検証、CI での適用など、セキュリティ設定全般を確認してください。
セキュリティのベストプラクティス
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
よく使うコマンド
# 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
よくあるエラー
| エラー | 原因 | 修正方法 |
|---|---|---|
bun.lockb not found | ロックファイルがありません | ローカルで bun install を実行します |
EACCES permission | ファイルの所有権 | --chown=bun:bun を使用します |
OOM killed | メモリ制限 | コンテナのメモリを増やします |
No space left | レイヤーが大きすぎます | マルチステージビルドを使用します |
リファレンスを読み込むタイミング
次の場合は references/optimization.md を読み込みます。
- イメージサイズの削減
- レイヤーのキャッシュ
- ビルドのパフォーマンス
次の場合は references/kubernetes.md を読み込みます。
- K8s へのデプロイ
- 水平スケーリング
- サービスメッシュ
コメント
Markdown 対応