简体   繁体   English

Docker `npm install` 与 TypeScript 中的 GitHub 私有 repo 依赖项

[英]Docker `npm install` with GitHub private repo dependency in TypeScript

We have a Node TypeScript project that we are trying to Dockerize.我们有一个 Node TypeScript 项目,我们正在尝试对其进行 Dockerize。 The project has a dependency on another GitHub private repo that is referenced via "git@github.com:{private-repo-name}" syntax in package.json.该项目依赖于另一个 GitHub 私有存储库,该存储库通过 package.json 中的“git@github.com:{private-repo-name}”语法引用。 The dependency project is also a TS project.依赖项目也是一个TS项目。 The main project installs and builds fine when running npm install (or npm ci etc) in the clone location and shell of any local dev PC OS (eg macOS, Ubuntu LTS, etc).在任何本地开发 PC 操作系统(例如 macOS、Ubuntu LTS 等)的克隆位置和 shell 中运行npm install (或npm ci等)时,主项目安装和构建良好。 However when trying to Dockerize the main project we are seeing npm build script errors that apparently make no sense.然而,当尝试 Dockerize 主项目时,我们看到npm build脚本错误显然没有意义。 The dependency project has a "prepare" script, which gets run after the npm install that is called for the dependency project, after its repo has been checked-out.依赖项目有一个“准备”脚本,它在为依赖项目调用的npm install之后npm install ,在它的 repo 被检出后。 The "prepare" script is npm run build and the "build" script is tsc -p . && npm run validate “准备”脚本是npm run build ,“构建”脚本是tsc -p . && npm run validate tsc -p . && npm run validate . tsc -p . && npm run validate

So things look like this:所以事情看起来像这样:

Main project's package.json:主项目的 package.json:

{
    "name": "main-project",
    "private": true,
    "scripts": {
        ...
    },
    "dependencies": {
        ...
        "typescript": "^4.3.4",
        "private-repo": "git@github.com:my-private-repo.git#a-branch",
    },
    "devDependencies": {
        "@types/example": "^1.0.0",
        ...
    }
}

Dependency project package.json:依赖项目package.json:

{
    "name": "dependency-project",
    "main": "dist/index.js",
    "types": "dist/index.d.ts",
    "scripts": {
        "build": "tsc -p . && npm run validate",
        "prepare": "npm run build",
        "validate": "node dist/validate.js"
    },
    "private": true,
    "dependencies": {
        ...
    },
    "devDependencies": {
        "@types/example": "1.0.0",
        ...
    }
}

The overall goal is the build the Docker image in layers, but we're stumbling at the first step of just getting the first layer ( npm install of the main project) to complete without errors.总体目标是分层构建 Docker 映像,但我们在第一步(主项目的npm install )无错误地完成时遇到了困难。

The main project's Dockerfile looks like this:主项目的 Dockerfile 如下所示:

FROM node:16-alpine
ARG SSH_KEY
RUN apk add git openssh-client
COPY package.json package-lock.json ./
RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN ssh-agent sh -c 'echo $SSH_KEY | base64 -d | ssh-add - ; npm ci'

This methodology of handing the private key into the layer build works fine (although it is the only one of various methods, including Docker Buildkit, that we were able to get working).这种将私钥传递到层构建中的方法工作正常(尽管它是我们能够开始工作的各种方法中的唯一一种,包括 Docker Buildkit)。 The repo gets checked-out and the install apparently succeeds, then the "prepare" script (and hence npm build and tsc -p ) runs.回购被检出并且安装显然成功,然后“准备”脚本(因此npm buildtsc -p )运行。

When we run docker build --build-arg SSH_KEY=$key .当我们运行docker build --build-arg SSH_KEY=$key . everything runs fine until the following errors:一切正常,直到出现以下错误:

#9 27.31 npm ERR! > my-private-repo@0.0.3 prepare
#9 27.31 npm ERR! > npm run build
#9 27.31 npm ERR!
#9 27.31 npm ERR!
#9 27.31 npm ERR! > my-private-repo@0.0.3 build
#9 27.31 npm ERR! > tsc -p . && npm run validate
#9 27.31 npm ERR!
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'cacheable-request'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'cacheable-request'
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'chai'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'chai'
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'cors'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'cors'
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'faker'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'faker'
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'lodash'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'lodash'
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'mocha'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'mocha'
#9 27.31 npm ERR! error TS2688: Cannot find type definition file for 'responselike'.
#9 27.31 npm ERR!   The file is in the program because:
#9 27.31 npm ERR!     Entry point for implicit type library 'responselike'

The confusing thing is that none of packages that those "error TS2688" messages refer to are dependencies of the dependency (private repo) project (they are in the package-lock.json of the main project. We have no idea how to interpret that.令人困惑的是,那些“错误 TS2688”消息所指的包都不是依赖项(私有仓库)项目的依赖项(它们在项目的 package-lock.json 中。我们不知道如何解释) .

The main troubleshooting steps we have tried include:我们尝试的主要故障排除步骤包括:

It seems like there must be something in the user context of the shell invoked in the relevant Docker layer that is causing TS to use the wrong package.json (ie the wrong dependencies), because what we are doing in the Dockerfile is very simple, and it works everywhere except in the Docker layer.似乎在相关的Docker层中调用的shell的用户上下文中一定有什么东西导致TS使用了错误的package.json(即错误的依赖项),因为我们在Dockerfile中所做的非常简单,它适用于除 Docker 层之外的任何地方。

[Update/answer to my own question] I wasn't able to fully explain this behaviour, since it made no sense. [更新/回答我自己的问题] 我无法完全解释这种行为,因为它没有任何意义。 Instead I tried using an ubuntu:20.04 instead of the node:16-alpine image.相反,我尝试使用 ubuntu:20.04 而不是 node:16-alpine 图像。 I had to add node and a bunch of dependencies, but having done that I was able to npm ci just fine, without that typescript complaint, or any other complaint.我不得不添加 node 和一堆依赖项,但完成后我能够很好地npm ci ,没有那个打字稿投诉,或任何其他投诉。

Here's the Dockerfile in case that helps anyone (noting this is just the base/build layer):这是 Dockerfile 以防万一可以帮助任何人(注意这只是基础/构建层):

FROM ubuntu:20.04

RUN apt-get update \
  # had to install tzdata this first to get the noninteractive to work
  && DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends tzdata \
  && apt-get install -y curl gnupg build-essential libcurl4-openssl-dev openssh-client git\
  && curl -fsSL https://deb.nodesource.com/setup_16.x | bash - \
  #&& apt-get remove -y --purge cmdtest \
  && apt-get update \
  && apt-get install -y nodejs \
  && rm -rf /var/lib/apt/lists/* \
  && rm -rf /var/lib/apt/lists.d/* \
  && apt-get autoremove \
  && apt-get clean \
  && apt-get autoclean

RUN adduser --disabled-password --gecos "" --uid 1000 node

RUN chown -R node:node /home/node

USER node

# had to set mode to 0700 otherwise couldn't open .ssh director to write known_hosts file
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN mkdir -p ~/app/node_modules && chown -R node:node /home/node/app

WORKDIR ~/app

COPY package.json package-lock.json ./

# had to allow uid=1000 access for this to work
RUN --mount=type=ssh,uid=1000 npm ci

COPY --chown=node:node . .

RUN npm run build

Hope that helps someone else, since it took my about a week of "spare" time to get to this point!希望对其他人有所帮助,因为我花了大约一周的“空闲”时间才达到这一点!

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

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