Docker との連携
注記
ビルド時にDockerコンテナとホストファイルシステム間でreflinksまたはハードリンクを作成することはできません。次に最適な方法は、BuildKitキャッシュマウントを使用してビルド間のキャッシュを共有することです。または、ビルド時にBtrfsボリュームをマウントできるPodmanを使用することもできます。
Dockerイメージのサイズとビルド時間の最小化
- 小さなイメージ(例:
node:XX-slim
)を使用します。 - 可能な限り、そして意味のある場合は、マルチステージビルドを活用します。
- BuildKitキャッシュマウントを活用します。
例1:Dockerコンテナ内でバンドルをビルドする
devDependencies
はバンドルのビルドのみに必要であるため、pnpm install --prod
はpnpm install
とpnpm run build
とは別のステージになり、最終ステージでは前のステージから必要なファイルのみをコピーできるため、最終イメージのサイズを最小限に抑えることができます。
.dockerignore
node_modules
.git
.gitignore
*.md
dist
Dockerfile
FROM node:20-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
COPY . /app
WORKDIR /app
FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
FROM base AS build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build
FROM base
COPY --from=prod-deps /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist
EXPOSE 8000
CMD [ "pnpm", "start" ]
例2:モノレポで複数のDockerイメージをビルドする
3つのパッケージ(app1、app2、common)を含むモノレポがあると仮定します。app1とapp2はcommonに依存しますが、互いに依存しません。
各パッケージに必要な依存関係のみを保存するには、pnpm deploy
を使用すると、必要なファイルとパッケージのみをコピーするのに役立ちます。
モノレポの構造
./
├── Dockerfile
├── .dockerignore
├── .gitignore
├── packages/
│ ├── app1/
│ │ ├── dist/
│ │ ├── package.json
│ │ ├── src/
│ │ └── tsconfig.json
│ ├── app2/
│ │ ├── dist/
│ │ ├── package.json
│ │ ├── src/
│ │ └── tsconfig.json
│ └── common/
│ ├── dist/
│ ├── package.json
│ ├── src/
│ └── tsconfig.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
└── tsconfig.json
pnpm-workspace.yaml
packages:
- 'packages/*'
.dockerignore
node_modules
.git
.gitignore
*.md
dist
Dockerfile
FROM node:20-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
FROM base AS build
COPY . /usr/src/app
WORKDIR /usr/src/app
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run -r build
RUN pnpm deploy --filter=app1 --prod /prod/app1
RUN pnpm deploy --filter=app2 --prod /prod/app2
FROM base AS app1
COPY --from=build /prod/app1 /prod/app1
WORKDIR /prod/app1
EXPOSE 8000
CMD [ "pnpm", "start" ]
FROM base AS app2
COPY --from=build /prod/app2 /prod/app2
WORKDIR /prod/app2
EXPOSE 8001
CMD [ "pnpm", "start" ]
app1とapp2のイメージをビルドするには、次のコマンドを実行します。
docker build . --target app1 --tag app1:latest
docker build . --target app2 --tag app2:latest