🐳

Turborepo × Dockerでのモノレポ開発環境構築

に公開

ご覧いただきありがとうございます。Furuyaです。
今回は、TurborepoをDockerコンテナ上で構築し、Next.jsのアプリケーションをモノレポで管理する環境を作る方法についてまとめます。

環境

  • MacBook Pro 13-inch, 2020, Four Thunderbolt 3 ports
  • macOS:macOS Sequoia 15.4
  • Shell: zsh

Docker 設定の初期構築

まずは、Dockerfile と docker-compose.yml ファイルを準備します。Node.js が使用できる最低限の環境で立ち上げます。

docker-compose.yml

docker-compose.yml
services:
  app:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - type: bind
        source: .
        target: /usr/src/app
    stdin_open: true
    tty: true

Dockerfile

Dockerfile
FROM node:22

RUN ["npm", "install", "-g", "pnpm@10.8.0"]

WORKDIR /usr/src/app

開発用コンテナの起動と環境準備

以下のコマンドでシェル付きの状態でコンテナを起動します。終了時に削除されるよう --rm を付けます。

docker-compose run --rm app sh

コンテナ内に入ったら、Turborepo プロジェクトの作成へ進みます。

Turborepo の初期化

インストール方法は公式を参照します。
https://turbo.build/docs/getting-started/installation

公式を参考に以降の手順を進めていきます。
先ほど立ち上げたコンテナ内で、以下のコマンドを実行します。

pnpm dlx create-turbo@latest

実行するとセッテイングに関する質問をされるので順番に選択していきます。
今回は以下のように回答しました。

? Where would you like to create your Turborepo? ./turbo-app
? Which package manager do you want to use? pnpm

プロジェクト作成後の構成は以下のようになります。

turborepo-app/
├── Dockerfile
├── docker-compose.yml
└── turbo-app/

作成されたら exit で一旦コンテナを抜けます。

Docker 設定ファイルの修正

現状のDockerの設定ファイルはNode環境のみの設定だったので、Turborepoで立ち上げたアプリケーションにアクセスできるように修正をします。

docker-compose.yml

docker-compose.yml
services:
  turborepo-apps:
    image: turborepo-apps
    container_name: turborepo-apps
    build:
      context: .
      dockerfile: Dockerfile.local
    volumes:
      - type: bind
        source: .
        target: /usr/src/app
    ports:
      - "3000:3000"
      - "3001:3001"
    command: sleep infinity
    # コンテナ起動時にアプリも立ち上げたい場合は以下を使う
    # command: /bin/sh -c "pnpm install && pnpm turbo dev"

ディレクトリ構成の調整

作成された turbo-app の中身をプロジェクトルートに移動します。

移動前:
turborepo-app/
├── Dockerfile
├── docker-compose.yml
└── turbo-app/

移動後:
turborepo-app/
├── Dockerfile
├── docker-compose.yml
├── .pnpm-store/
├── .turbo/
├── .vscode/
├── apps/
├── node_modules/
├── packages/
├── .gitignore
├── .npmrc
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── README.md
└── turbo.json

アプリケーションの起動確認

ビルドと起動

docker compose build --no-cache
docker compose up -d

Turborepo Dev 起動

デタッチモードでコンテナを立ち上げているので、立ち上げたコンテナにbashで入ります。

docker compose exec turborepo-apps /bin/bash

コンテナに入れたらturboコマンドで機動します。


pnpm turbo dev

その後 localhost:30003001 にアクセスできれば成功です。
ctrl + C で停止し、exitコマンド でコンテナを抜けます。

アプリケーションの追加作成

Turborepo の apps/ フォルダに Next.js のアプリを追加してみましょう。

appsディレクトリに移動し以下のコマンドを実行します。

pnpm create next-app

実行すると対話形式でアプリケーションの作成に必要な情報の入力が求められるので、順次選択していきます。

.../1964d872da2-355                      |   +1 +
.../1964d872da2-355                      | Progress: resolved 1, reused 0, downloaded 1, added 1, done
✔ What is your project named? … sample-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes
Creating a new Next.js app in /usr/src/app/apps/sample-app.

アプリが生成されると以下のようになります。

turborepo-app/
├── Dockerfile
├── docker-compose.yml
├── ...
├── apps/
│   ├── docs
│   ├── sample-app
│   └── web
├──...

アプリ設定とポートの追加

apps/sample-app/package.json の編集

apps/sample-app/package.json
{
  "name": "sample-app",
  "version": "0.1.0",
  "type": "module",
  "private": true,
  "scripts": {
    "dev": "next dev --turbopack --port 3002",
    "build": "next build",
    "start": "next start",
    "lint": "next lint --max-warnings 0",
    "check-types": "tsc --noEmit"
  },
  "dependencies": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "next": "15.3.1"
  },
  "devDependencies": {
    "typescript": "^5",
    "@types/node": "^20",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "@tailwindcss/postcss": "^4",
    "tailwindcss": "^4",
    "eslint": "^9",
    "eslint-config-next": "15.3.1",
    "@eslint/eslintrc": "^3"
  }
}

docker-compose.yml にポート追加

docker-compose.yml
services:
  turborepo-apps:
    image: turborepo-apps
    container_name: turborepo-apps
    build:
      context: .
      dockerfile: Dockerfile.local
    volumes:
      - type: bind
        source: .
        target: /usr/src/app
    ports:
      - "3000:3000"
      - "3001:3001"
      - "3002:3002" #追加
    command: sleep infinity
    # コンテナ起動時にアプリも立ち上げたい場合は以下を使う
    # command: /bin/sh -c "pnpm install && pnpm turbo dev"

最終確認

最後に順番にコマンドを実行していきちゃんと起動できるかを確認して終了です。

コンテナのビルド起動

docker compose up

Turborepoでアプリケーションの起動

docker compose exec turborepo-apps /bin/bash

実行するとDockerfileで指定した/usr/src/appにいる状態でコンテナが起動されます。

pnpm turbo dev

localhost:3002 にアクセスできれば成功です。
ctrl + C で停止し、exit コマンドで終了します。

補足:ホットリロードが効かない問題について

この方法では、Next.js のホットリロードが効かない場合があります。
主な原因は bind mount の設定や WATCHPACK_POLLING=true が無効なためです。
その対策については以下の記事をご覧ください。

https://zenn.dev/k0y0k0y0/articles/article_20250420

以上で「Turborepo × Dockerでのモノレポ開発環境構築」は完了です!

GitHubで編集を提案

Discussion