🥟
コンテナでbunをパッケージマネージャーとして使うんだったらこう書く
何がしたいか?
今回はJSランタイムとしてbunを使うのではなく高速なnpm互換パッケージマネージャーとして利用することを焦点においた話になります。そのためbunをランタイムや様々な用途で組み込もうとしている用途での記事ではないのでご注意ください。
実現したいことを箇条書きにすると以下です
- CI/CDの中でbunを高速なnpm互換のパッケージマネージャーとして組み込みたい
- CI/CDで十分なパフォーマンスを出すためにロックファイルは
bun.lockbを使いたい
↓
開発環境のコンテナでもbunをパッケージマネージャーとして利用して環境を統一したい
”そもそもbunとは”のための説明
Develop, test, run, and bundle JavaScript & TypeScript projects—all with Bun. Bun is an all-in-one JavaScript runtime & toolkit designed for speed, complete with a bundler, test runner, and Node.js-compatible package manager.
答え
# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM oven/bun:1.1.42-alpine AS bun
FROM node:22.12.0-alpine3.21
WORKDIR /usr/src/bun-sample/
RUN apk --no-cache add wget git unzip vim curl python3 make g++
COPY --from=bun /usr/local/bin/bun /usr/local/bin/bun # bun installしてます
COPY ./bun-sample/package.json ./bun-sample/bun.lockb ./
RUN bun i
ENV NODE_ENV=development
何をしてるか
要点だけ説明
- ホスト環境がARM64で
oven/bunをベースイメージとする際にはプラットフォーム指定しないとうまく動かなかった- よく分からない箇所で処理がコケて結構時間を食ってしまった、後日調査予定
-
# bun installしてますのところでマルチステージビルドを使ってbunをバイナリだけを持ってくる- phpだとdockerでcomposerを使うときに使ったり、Goだとライブラリのバイナリだけ持ってきたい時に使えたりする手段
-
npm i -g bunはCPUアーキテクチャによる違いで工夫が必要で面倒だったので、マルチステージビルドでサクッと導入
bunのおまけ
今回はbun.lockbを使ったがバイナリなのでdependabotやrenovateなどでうまく検知ができないという問題がある。が、それに対応するためにbunの1.1.39からbun.lockというテキストベースのロックファイルを作成するオプションが追加されている。若干パフォーマンスが落ちる可能性はあるが、dependabotなどのサポートを継続して利用したい場合は--save-text-lockfileをつけてみると良いかも
まとめ
- bunは速い
- GitHub Actionsのubuntu-latestランナーでパッケージのインストール時間で検証した
-
npmより2倍速い -
pnpmより若干速い
-
- GitHub Actionsのubuntu-latestランナーでパッケージのインストール時間で検証した
- マルチステージビルドは便利
- 今回のような恩恵を受けられるポイントがあったり、デプロイなどで最終成果物のサイズを小さくする目的など他にも色んな目的に対して使えそう
Discussion