1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vite + Cloudflare Workers の開発環境を Docker Compose でまとめて起動する

1
Posted at

React + Vite のフロントエンドと、Cloudflare Workers + Hono の API サーバーを別々に起動していたのですが、docker-compose up だけで立ち上げられるようにしました。

やりたかったこと

これまではローカル開発時に、フロントエンドと API を別ターミナルで起動していました。

npm run dev
npm run dev:api

この状態だと、毎回新しいターミナルを2つ開いてそれぞれでコマンドを打たなければいけないので、すごく面倒に感じていました。

そこで Docker Compose を使って、次の2つを同時に起動できるようにしました。

  • Vite dev server
  • Wrangler dev server

前提

このプロジェクトでは、package.json に次のスクリプトがあります。

{
  "scripts": {
    "dev": "vite",
    "dev:api": "wrangler dev worker/index.ts --local --port 8787"
  }
}

フロントエンドは Vite、API は Cloudflare Workers を wrangler dev で起動しています。

また、Vite 側では /api へのリクエストを API サーバーへプロキシしています。

docker-compose.yml を追加する

追加した docker-compose.yml は次のような構成です。

services:
  api:
    image: node:22-bookworm-slim
    working_dir: /app
    environment:
      CI: "true"
    ports:
      - "8787:8787"
    volumes:
      - .:/app
      - api_node_modules:/app/node_modules
      - wrangler_state:/app/.wrangler
    command: >
      sh -c "npm ci &&
      npx wrangler d1 migrations apply kinkyo-note-db --local --persist-to .wrangler/state &&
      npm run dev:api -- --ip 0.0.0.0 --persist-to .wrangler/state"

  frontend:
    image: node:22-bookworm-slim
    working_dir: /app
    environment:
      API_PROXY_TARGET: http://api:8787
      CHOKIDAR_USEPOLLING: "true"
    ports:
      - "5173:5173"
    volumes:
      - .:/app
      - frontend_node_modules:/app/node_modules
    depends_on:
      - api
    command: >
      sh -c "npm ci &&
      npm run dev -- --host 0.0.0.0"

volumes:
  api_node_modules:
  frontend_node_modules:
  wrangler_state:

これで次のコマンドだけで、フロントエンドと API サーバーを同時に起動できます。

docker-compose up

Vite のプロキシ先を環境変数で切り替える

もともと Vite のプロキシ先は localhost:8787 にしていました。

proxy: {
  '/api': 'http://localhost:8787',
},

ただし Docker Compose 内では、frontend コンテナから見た localhostfrontend コンテナ自身です。

API コンテナへアクセスするには、Compose のサービス名である api を使う必要があります。

そのため、vite.config.ts を次のように変更しました。

const apiProxyTarget = process.env.API_PROXY_TARGET ?? 'http://localhost:8787'

export default defineConfig({
  server: {
    proxy: {
      '/api': apiProxyTarget,
    },
  },
})

ローカルで直接 npm run dev する場合は、これまで通り http://localhost:8787 を使います。

Docker Compose で起動する場合だけ、docker-compose.yml 側で次の環境変数を渡します。

environment:
  API_PROXY_TARGET: http://api:8787

0.0.0.0 で待ち受ける

コンテナ内で開発サーバーを起動する場合、localhost だけで待ち受けているとホスト側ブラウザからアクセスできません。

そのため、Vite と Wrangler の両方で 0.0.0.0 を指定しています。

command: >
  sh -c "npm ci &&
  npm run dev -- --host 0.0.0.0"
command: >
  sh -c "npm ci &&
  npm run dev:api -- --ip 0.0.0.0 --persist-to .wrangler/state"

ローカル D1 のマイグレーションも起動時に実行する

API では Cloudflare D1 を使っているため、初回起動時にローカル D1 のテーブルが存在しないと API が正しく動きません。

そこで API サービスの起動コマンド内で、wrangler d1 migrations apply を実行しています。

npx wrangler d1 migrations apply kinkyo-note-db --local --persist-to .wrangler/state

--persist-to .wrangler/state を指定して、wrangler dev と同じローカル永続化ディレクトリを使うようにしています。

Compose では .wrangler を volume にしているため、コンテナを停止してもローカル D1 の状態は保持されます。

volumes:
  - wrangler_state:/app/.wrangler

ローカル D1 の状態をリセットしたい場合は、volume ごと削除します。

docker-compose down -v

node_modules は volume に分ける

ソースコードは bind mount しています。

volumes:
  - .:/app

ただし、このままだとホスト側の node_modules とコンテナ側の node_modules が混ざりやすくなります。

そこで node_modules はサービスごとに named volume に分けました。

volumes:
  - api_node_modules:/app/node_modules
volumes:
  - frontend_node_modules:/app/node_modules

これにより、依存関係はコンテナ内に閉じつつ、ソースコードの変更はホストからそのまま反映できます。

まとめ

Docker Compose を追加したことで、開発開始時のコマンドは次だけになりました。

docker-compose up

フロントエンドと API サーバーを別々に起動する必要がなくなり、ローカル D1 のマイグレーションも起動時に自動で適用されるようになりました。

小さな変更ですが、開発環境の再現性と立ち上げやすさがかなり改善しました。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?