logo

pnpm workspace で Hono x Nextjs x Docker 環境構築の備忘録

2025-03-20
15 days ago

開発環境

  • pnpm 8.15.3

前提

pnpm workspaceを初めて触る筆者のメモ書きのような記事です。

最適化など考えず、とりあえず動くsandobox環境のようなものを構築したいというモチベーションで作成しています。

構成はフロントエンド(web)にNextjs、バックエンド(api)にHonoとなります。

ついでにPostgreSQL(db)も入れています。

本題

STEP: 1

workspace関連ファイルの配置

  • プロジェクトルートにpnpm-workspace.yamlを作成

./pnpm-workspace.yaml

packages:
  - "apps/*"
  • プロジェクトルートにpackage.jsonを作成

./package.json

{
  "name": "pnpm-monorepo-sample-v3",
  "private": true,
  "scripts": {
    "test": "echo \\"Error: no test specified\\" && exit 1",
    "api": "pnpm -F \\"api\\"",
    "web": "pnpm -F \\"web\\""
  },
  "engines": {
    "pnpm": "8.15.3",
    "npm": "please_use_pnpm_instead",
    "yarn": "please_use_pnpm_instead"
  },
  "packageManager": "pnpm@8.15.3",
}
  • モノレポ構成のディレクトリを作成
mkdir -p apps/web apps/api

dockerファイルの配置

./.dockerignore

  • プロジェクトルートに.dockerignoreを作成
node_modules
**/node_modules
  • プロジェクトルートにcompose.yamlを作成

./compose.yaml

x-common: &common
  env_file:
    # - .env
    - .env.local

services:
  web:
    <<: *common
    container_name: web
    build:
      dockerfile: web.Dockerfile
    ports:
      - "3000:3000"
    depends_on:
      - api
    volumes:
      - .:/app
  api:
    <<: *common
    container_name: api
    build:
      dockerfile: api.Dockerfile
    ports:
      - "3001:3001"
    depends_on:
      - db
    volumes:
      - .:/app

  db:
    <<: *common
    container_name: db
    image: postgres:16
    restart: always
    ports:
      - "5432:5432"
    volumes:
      - ./db/app/postgres/init.d:/docker-entrypoint-initdb.d
      - ./db/app/postgres/pgdata:/var/lib/postgresql/data
  • apiwebのDockerfileを作成

./api.Dockerfile

FROM node:22.14.0-alpine AS base

FROM base AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
COPY . .

FROM base AS installer
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
# COPY package.json pnpm-lock.yaml ./
RUN corepack enable && corepack prepare pnpm@8.15.3 --activate
RUN pnpm --version
# RUN pnpm install --frozen-lockfile
# CMD pnpm api dev
[!WARNING] 初回ビルド時は一部コメントアウトして実行

./web.Dockerfile

FROM node:22.14.0-alpine AS base

FROM base AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
COPY . .

FROM base AS installer
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /app
# COPY package.json pnpm-lock.yaml ./
RUN corepack enable && corepack prepare pnpm@8.15.3 --activate
RUN pnpm --version
# RUN pnpm install --frozen-lockfile
# CMD pnpm web dev
[!WARNING] 初回ビルド時は一部コメントアウトして実行
docker compose build

STEP: 2

apiの設定

docker compose run --rm api pnpm create hono .
  • ポート3000はweb側で利用するので、3001に変更する

./apps/api/src/index.ts

import { serve } from '@hono/node-server';
import { Hono } from 'hono';

const app = new Hono();

app.get('/', (c) => {
  return c.text('Hello Hono!');
});

serve(
  {
    fetch: app.fetch,
    port: 3001,
  },
  (info) => {
    console.log(`Server is running on <http://localhost>:${info.port}`);
  }
);

STEP: 3

webの設定

docker compose run --rm web pnpm create-next-app@latest

STEP: 4

共通の設定

  • eslint, @types/nodeを一度プロジェクト全体から削除
docker compose up
docker exec -it web sh
pnpm remove eslint @types/node -r
  • ルートにeslint, @types/node, prettierを追加
pnpm add eslint -D --workspace-root
pnpm add @types/node -D --workspace-root
pnpm add prettier -D --workspace-root

さいごに

docker compose upで起動できるはず!

そもそもpnpm自体初めて触ったので、色々戸惑いました・・

参照