一个关于 Nodejs Dockerfile 的小优化

建议点击 查看原文 查看最新内容。

原文链接: https://typonotes.com/posts/2024/02/20/a-simple-optimizion-for-nodejs-dockerfile/

原版 Dockerfile 如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
FROM ${BASE_IMAGE} as env

RUN mkdir -p /app && chown -R node:node /app
WORKDIR /app
COPY package*.json ./
COPY .npmrc ./
USER node

## 问题在这里, npm install 失败之后, 无法看到具体错误
RUN npm install

在执行完成 npm install 之后没有更多的 错误判断

  1. 如果没有出错, 一切都正常。 往下走就行了。
  2. 但是执行出错 npm 会将错误放在一个 错误文件中, 需要用户自行查询。
#10 13.06 npm ERR!     /home/node/.npm/_logs/2024-02-16T08_23_58_047Z-debug.log

可以从图片中看到, 这里的输出都是执行日志, 都是 WARN。 根本不是根因。

很显然 在 CI 中是没办法登录到打包机上手动查看错误的文件的额。

优化方案

因此需要对这行命令做一个简单的优化。 在 npm install 失败的时候, 使用 tail 查看最后 100 行错误日志。

这是完整的 shell 脚本。

1
2
3
4
5
6
7
# run npm install; if it fails, print the logs and exit
npm install
RET=$?
if [[ $RET -ne 0 ]]; then
    tail -n 100 $HOME/.npm/_logs/*.log
    exit $RET
fi

内容很简单,

  1. 保存 npm isntall 的 退出值
  2. 如果 不等于0 则表示有错。
    1. 使用 tail 命令查看所有日志文件的最后 100 行
    2. 并使用 退出值 退出。

由于在打包机上每次执行前虚拟环境将被清空, 所以只有一个文件的错误日志。

更新 Dockerfile

在更新后 Dockerfile 中, 为了方便还是将 shell 脚本最小化成 一行 了。

1
2
3
4
5
FROM ${BASE_IMAGE} as env
# ...

# run npm install; if it fails, print the logs and exit
RUN npm install; RET=$?; if [[ $RET -ne 0  ]]; then tail -n 100 $HOME/.npm/_logs/*.log; exit $RET; fi;

再次执行之后, 可以看到。 日志中的正式错误是私有包鉴权失败导致的。

#10 12.78 20372 verbose statusCode 401
...

#10 12.78 20380 error Unable to authenticate, need: Basic realm="Artifactory Realm"