🍹

Bun on docker で Monorepo 内の Next.js v14 を render にデプロイする

2023/11/03に公開

Bunの進撃が止まらねえ!

https://bun.sh/

パッケージマネージャーとしても、テストランナーとしても、非常にすぐれた使い心地とスピードを誇ってくれるBun、残念なことにスタートアップや個人開発の救世主 render ではまだ利用できません(2023/11/03現在)

https://render.com/

当社含め、乗り換え進めてきたい!って方も結構いらっしゃると思うので、docker使ってざっくり書いてみました。

構成

$ tree -L 3 --gitignore
.
├── README.md
├── apps
│   └── app
│       ├── README.md
│       ├── app
│       ├── next.config.js
│       ├── package.json
│       ├── public
│       └── tsconfig.json
├── bun.lockb
├── docker
│   └── Dockerfile.app
├── package.json
├── packages
│   └── lib
│       ├── README.md
│       ├── index.ts
│       ├── package.json
│       └── tsconfig.json
├── render.yaml
└── tsconfig.json

やった手順

$mkdir bun-docker-monorepo-next

$npx create-next-app@latest apps/app

  • package-lock.json / node_modules を削除

$bun init

  • index.ts package.main を削除
  • package.workspaces を更新
    "workspaces": [
      "apps/*",
      "packages/*"
    ],
    

$bun install

  • これで apps/app 内のモジュールバージョンが bun.lockb に記録される
  • VSCode の Bun の拡張があると中身見やすい

packages/lib の作成

package.json
{
  "name": "@packages/lib",
  "module": "index.ts",
  "type": "module",
  "devDependencies": {
    "bun-types": "latest"
  },
  "peerDependencies": {
    "typescript": "^5.0.0"
  }
}

appから読み込むテスト用

index.ts
export const nodeEnv = process.env.NODE_ENV;

apps/app の更新

  • Next@14 の任意のファイルに以下を追加(自分はpage.tsxにしてみました)
  • 補完が効くのも確かめる
apps/app/page.tsx
import { nodeEnv } from '@packages/lib'


export default function Home() {
  return (
    <main className={styles.main}>
      <div className={styles.description}>
        <p>Env: {nodeEnv}</p>
// ...
  • package.json の更新
// ...
"dependencies": {
  "@packages/lib": "workspace:*",
// ...

IaC (render.yaml) と Dockerfile の作成

https://render.com/docs/blueprint-spec

render.yaml
services:
  - name: test.monorepo-docker-to-render
    type: web
    runtime: docker
    repo: {{自分のgit repo}}
    branch: main
    autoDeploy: true
    dockerfilePath: docker/Dockerfile.app
docker/Dockerfile.app
FROM oven/bun

# render の ディレクトリ
WORKDIR /usr/src/app

COPY package*.json bun.lockb ./
# apps / packages などがないと bun workspace でコケる
COPY . .
RUN bun install
COPY . .

# テストなので、一旦設定。render に設定し、 .env をコピるなどすればOK
ENV NODE_ENV production

# monorepo の app をホスティングするための切り替え
WORKDIR /usr/src/app/apps/app
RUN bun run build
CMD [ "bun", "run", "start" ]

無事デプロイ完了!

じゃん

まともにローカルテストもしないままでしたが、ここまで10分程度!これは良い!

当社では最近 render のビルドスペックをあげた(16CPU/64GB)のもありますが、 GitHub への push から deployまで約3分でした。

個人でもBunを使い始めており、非常に体験が良いので、チーム全体ではよ載せ替えたいなと、休日を使ったテストでした!

いやーすごい。
DevOpsが充実していくと、企画や開発に集中できるようになるので嬉しいですね。
当社はNextもがっつり使っているので、 Next14 の turbopack も楽しみです。

ついでにVividirの紹介

https://vividir.io/

現在、私 @repomn がCPOを務めるVividirは、事業を数字から構造化するシミュレーションSaaSです。多くのビジネスの未来を描き、支援するサービスとして、鋭意チーム強化中です。

開発者泣かせのゴリゴリに重たいアルゴリズムをバチバチに最適化しながら、ブランドデザインにもこだわって、少数チームで邁進しています。
2週間ごとの全社スクラムが習慣化しており、本記事のような構成がメインで、爆速(週2~3デプロイ)開発中です。毎度7割達成くらいなので、協力してあげるよ・色々見直してやるよ、って方がいたら是非お気軽にお問い合わせ、DM、コメント等ください。

Discussion