简体   繁体   English

使用 docker 构建纱线工作区

[英]Yarn workspaces build with docker

Consider following file structure of yarn workspaces:考虑以下纱线工作区的文件结构:

.
├── docker-compose.yaml
├── package.json
├── packages
│   └── pkg-1
│       ├── dist
│       ├── package.json
│       ├── src
│       └── tsconfig.json
├── services
│   ├── api-1
│   │   ├── dist
│   │   ├── Dockerfile
│   │   ├── package.json
│   │   ├── src
│   │   ├── tsconfig.json
│   │   └── yarn.lock
│   └── client-1
│       ├── package.json
│       ├── src
│       └── yarn.lock
├── tsconfig.json
└── yarn.lock

I have written Dockerfile to create image for api-1:我已经编写了 Dockerfile 来为 api-1 创建图像:

ARG APP_DIR=/usr/app

# Build stage
FROM node:16.2-alpine AS build

ARG APP_DIR

WORKDIR ${APP_DIR}
COPY package.json ./
COPY yarn.lock ./
COPY tsconfig.json ./

WORKDIR ${APP_DIR}/packages/pkg-1
COPY packages/pkg-1/package.json ./
RUN yarn --pure-lockfile --non-interactive
COPY packages/pkg-1/tsconfig.json ./
COPY packages/pkg-1/src/ ./src
RUN yarn build

WORKDIR ${APP_DIR}/services/api-1
COPY services/api-1/package.json ./
COPY services/api-1/yarn.lock ./
RUN yarn --pure-lockfile --non-interactive
COPY services/api-1/tsconfig.json ./
COPY services/api-1/src/ ./src
RUN yarn build

# Production stage
FROM node:16.2-alpine AS prod

ARG APP_DIR

WORKDIR ${APP_DIR}
COPY --from=build ${APP_DIR}/package.json ./
COPY --from=build ${APP_DIR}/yarn.lock ./

WORKDIR ${APP_DIR}/packages/pkg-1
COPY --from=build ${APP_DIR}/packages/pkg-1/package.json ./
RUN yarn --pure-lockfile --non-interactive --production
COPY --from=build ${APP_DIR}/packages/pkg-1/dist ./dist

WORKDIR ${APP_DIR}/services/api-1
COPY --from=build ${APP_DIR}/services/api-1/package.json ./
COPY --from=build ${APP_DIR}/services/api-1/yarn.lock ./
RUN yarn --pure-lockfile --non-interactive --production
COPY --from=build ${APP_DIR}/services/api-1/dist ./dist

CMD ["node", "dist"]

Build is running from root docker-compose.yaml to have proper context:构建从根 docker-compose.yaml 运行以获得正确的上下文:

services:
  api-1:
    image: project/api-1
    container_name: api-1
    build:
      context: ./
      dockerfile: ./services/api-1/Dockerfile
      target: prod
    ports:
      - 3000:3000

It is working but this way there will be a lot of repetition while application grow.它正在工作,但是这样在应用程序增长时会有很多重复。 Problem is the way how packages are building.问题是包的构建方式。

Package can be for example normalized components collection used among client services or collection of normalized errors used among api services. Package 可以是例如在客户端服务之间使用的规范化组件集合或在 api 服务之间使用的规范化错误集合。

Whenever I will build some service I need to first build its depending packages which is unnecessarily repetitive task.每当我要构建一些服务时,我都需要首先构建它的依赖包,这是不必要的重复任务。 Not mention that building steps of respective package are defined over and over again in Dockerfile of every single service that uses the package.更不用说在使用 package 的每个服务的 Dockerfile 中一遍又一遍地定义各个 package 的构建步骤。

So my question is.所以我的问题是。 Is there a way how to create for example image of package that will be used for building a service to avoid defining build steps of package in service Dockerfile?有没有办法创建例如 package 的图像,该图像将用于构建服务以避免在服务 Dockerfile 中定义 package 的构建步骤?

Seems like you are looking for something that gives you the option to have a "parent" package.json, so you only have to invoke "build" on one and with that build the whole dependency tree.似乎您正在寻找可以让您选择拥有“父”package.json 的东西,因此您只需在其中调用“构建”并构建整个依赖关系树。

eg:例如:

- package.json // root package
  | - a
    | - package.json // module a package
  | - b
    | - package.json // module b package

You might want to look into the following:您可能需要查看以下内容:

Both support structures like the one mentioned, lerna has just a lot more features.这两种支持结构都像上面提到的那样,lerna 具有更多的功能。 To get a quick grasp on the differences, look here: Is Lerna needed anymore with NPM 7.0.0's workspaces?要快速了解差异,请查看此处: NPM 7.0.0 的工作区是否需要 Lerna?

A while ago I have posted an answer detailing how I structured a monorepo with multiple services and packages .不久前,我发布了一个答案,详细说明了我如何构建具有多个服务和包的 monorepo

The "trick" is to copy all the packages that your service depends on, as well as the project root package.json. “诀窍”是复制您的服务所依赖的所有包,以及项目根 package.json。 Then running yarn --pure-lockfile --non-interactive --production once will install the dependencies for the all the sub-packages since they are part of the workspace.然后运行一次yarn --pure-lockfile --non-interactive --production将为所有子包安装依赖项,因为它们是工作空间的一部分。

The example linked isn't using typescript, but I believe this could be easily achieved with a postinstall script in every package.json that would run yarn build .链接的示例没有使用 typescript,但我相信这可以通过每个package.json运行yarn buildpostinstall脚本轻松实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM