Pular para o conteúdo principal
Versão: Next

Trabalhando com Docker

nota

É impossível criar reflinks ou hardlinks entre um contêiner Docker e o sistema de arquivos host durante o tempo de compilação. A próxima melhor coisa que você pode fazer é usar a montagem de cache do BuildKit para compartilhar o cache entre compilações. Alternativamente, você pode usar podman porque ele pode montar volumes Btrfs durante o tempo de compilação.

Minimizando o tamanho da imagem Docker e o tempo de compilação

  • Use uma imagem pequena, por exemplo node:XX-slim.
  • Aproveite os vários estágios, se possível e fizer sentido.
  • Aproveite as montagens de cache do BuildKit.

Exemplo 1: Construa um pacote em um contêiner Docker

Como devDependencies é necessário apenas para construir o pacote configurável, pnpm install --prod será um estágio separado de pnpm install e pnpm run build, permitindo que o estágio final copie apenas os arquivos necessários das etapas anteriores, minimizando o tamanho da imagem final.

.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" ]

Exemplo 2: Construa várias imagens Docker em um monorepo

Supondo que você tenha um monorepo com 3 pacotes: app1, app2 e common; app1 e app2 dependem do common, mas não um do outro.

You want to save only necessary dependencies for each package, pnpm deploy should help you with copying only necessary files and packages.

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" ]

Execute os seguintes comandos para criar imagens para app1 e app2:

docker build . --target app1 --tag app1:latest
docker build . --target app2 --tag app2:latest