Перейти до основного змісту
Версія: 8.x

Робота з Docker

нотатка

Неможливо створити reflinks або hardlinks між контейнером Docker і головною файловою системою під час збирання. Наступне найкраще, що ви можете зробити, це використовувати монтування кешу BuildKit для спільного використання кешу між збірками. Крім того, ви можете використовувати podman, оскільки він може монтувати томи Btrfs під час збирання.

Мінімізація розміру образу 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 допоможе вам скопіювати лише необхідні файли та пакунки.

Structure of the monorepo
./
├── 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