解析Node.js镜像原理,轻松构建高效CI/CD流程

解析Node.js镜像原理,轻松构建高效CI/CD流程 原文来源于:程序员成长指北;作者:wks 如有侵权,联系删除 1. 前言
如果公司项目使用容器化部署,那么或多或

原文:程序员成长指南作者:wks

如有侵权,请联系我们删除。

1. 前言

如果你公司的项目采用容器化部署,那么你对nodejs镜像或多或少有些熟悉。这是因为基于nodejs的前端或BFF项目在构建或部署过程中依赖于nodejs镜像。

有同学可能会问,关于nodejs镜像需要了解什么?访问docker官方镜像网站,搜索对应的node版本,找到对应的版本号,查看是否可用。假设你想像这样找到16.20.0:如图所示

然后将对应的镜像版本写入Dockerfile中,如下所示。

JavaScript

复制代码

来自节点:16.20.0

聪明的同学可能会注意到,相同的版本有不同的标签,比如16.20.0和14.19.1,如下图所示。

为什么我的节点镜像版本有这么多标签,我该如何选择?

除了版本号之外,为什么标签14 和16 之间存在差异?

2. 解析nodejs镜像

如果你对Linux不熟悉,可以先了解一下什么是debian、什么是Alpine,然后再了解nodejs镜像。如果你熟悉这部分,可以直接跳到官方的nodejs镜像配置。

2.1 Debian是什么

Linux 发行版有很多,但根据其性质分为由商业公司维护的商业版本和由开源社区维护的免费发行版。商业版本以Redhat为代表,开源社区版本以Debian为代表。每个版本都有不同的特点,在不同的应用领域发挥不同的作用。

目前流行的发行版有:

总的来说,Debian 是一个比Ubuntu 更稳定的服务器操作系统。 Debian的整体系统基本没问题,除非应用层面存在逻辑缺陷。 Debian 的系统级基础核心非常小,这使得它不仅稳定而且消耗的硬盘空间和内存也很少。

有关更多信息,请查看CentOS、Ubuntu 和Debian Linux 之间的异同。

Debian 发行版本Debian 至少维护了三个发行版本。分为稳定版、测试版、不稳定版。

稳定版本(Stable Version) : 稳定版本包含Debian官方发布的最新软件包。这是Debian的正式发布版本,也是第一个推荐给用户的版本。 Debian当前稳定版本号为12,开发代号为Bookworm。初始版本为12.0,于2023年6月10日发布,其更新版本12.1于2023年7月22日发布。

测试: 测试版本包含尚未包含在稳定版本中但在候选队列中的软件包。使用此版本的最大优点是它包含较新版本的软件。当前测试版代号为trixie。

不稳定版本(unstable) : 不稳定版本存储Debian当前的开发工作。该版本通常仅供开发人员和喜欢生活刺激的人使用,不稳定版本的版本代号始终称为sid。

Debian 发布生命周期和目录Debian 通常会根据一定的规则定期发布新的稳定版本。对于每个稳定版本,用户将获得三年的全面支持和额外两年的长期支持。当前的发布时间表如下所示。

可以看到最新的稳定版本是12。

2.2 Alpine又是什么

Alpine 是一个轻量级、面向安全的Linux 发行版。与常规Linux 发行版不同,Alpine 使用musl libc 和Busybox 来减少系统大小和运行时资源消耗,但其功能比Busybox 丰富得多,因此开源社区的支持不断增长。在保持轻薄外形的同时,Alpine还提供了自己的包管理工具apk,可以让你通过apk命令直接查询和安装各种软件。

2.3 Debian与Alpine的差异

空间大小差异默认情况下,alpine 为5M 左右,debian 为200M 左右。

默认软件包有所不同。 Alpine 使用Busybox,而Debian 使用bash+coreutils。

阿尔派优化了国际零部件。

另一点是alpine使用“最小依赖”。这与archlinux类似。例如,openssh 软件包没有自带pam 插件,因此不支持ldap。我已向alpinelinux 正式提出了有关此问题的问题。与php不同的是,php可以封装在php-pdo和php-dom中,并且可以动态加载共享库。 openssh不行,“不带就不写”。

glibc的区别,alpine使用musl,centos等使用glibc。 libc 差异对于开发非常重要。

有关更多信息,请参阅Alpine Linux 和CentOS 之间有什么区别?

2.4 nodejs官方镜像构成

接下来我们看一下nodejs的镜像配置

node:版本:基于最新版本的Debian,依赖最基本的镜像、工具包buildpack-deps,提供了最常用的Debian软件包如curl、bash、git等。

node:alpine:基于流行的Alpine Linux项目,不包含常用软件包,必须通过apk安装。此外,受影响的是musl libc 而不是glibc。依赖于glibc 的软件包,例如grpc。

node:buster:基于Debian10版本的镜像(依赖工具包buildpack-deps)

node:bullseye:基于Debian11版本镜像,依赖工具包buildpack-deps。

node:bookworm:基于Debian12版本镜像,依赖工具包buildpack-deps。

node:slim:基于当前版本的Debian,仅包含允许镜像运行的最基本的软件包,例如bash 和git,但不包含像curl 这样的东西。

当然,未来还会有基于新的Debian版本的镜像。

您可以直接在镜像详情页面搜索,查看镜像是否包含特定工具包,如下图所示。

镜子的整体结构如下图所示。

以16.20.0(arm64)为例,不同标签的镜像差异如下:

镜像标签节点版本、软件包、系统漏洞数量、镜像大小包含yarnnode16.20.0751230856MBnode:bullseye16.20.0751121890MBnode:bullseye-slim16.20.034726184MBnode:bookworm16.20.0750921 .04GBnode :bookworm -slim16.20.033415206MBnode:alpine16.20.02304116MB

从上表可以得出

Alpine 和Slim 的尺寸最小,Bullseye、Bookworm、node:version 的图像尺寸比Alpine 和Slim 大几倍。

Alpine和Slim的漏洞数量最少,而Bullseye、bookworm和node:版本的漏洞数量是Alpine和Slim的几倍。

因此,您可以在versions.json文件中查看node:version对应的版本。以16.20.0版本为例,node:16.20.0实际上是node:16.20.0-buster。

此外,您还可以看到镜像配置,如下图所示。

此时您应该能够回答前两个问题

为什么我的节点镜像版本有这么多标签,我该如何选择?

原因是您可以根据镜像大小和功能选择基于不同Linux 版本的: Nodejs 构建的镜像。

除了版本号之外,为什么标签14 和16 之间存在差异?

原因是Debian不断发布新版本,而nodejs只发布基于维护中的最新Nodejs版本的新Debian版本的镜像。

3. 怎么选择nodejs镜像

通过以上,您已经了解了各个标签的含义以及对应标签图片的构成,因此您可以根据自己的使用场景进行选择。

3.1 web项目

构建Web 项目时建议使用Alpine 镜像。原因是,当您构建Web 项目时,通常仅依赖于构建工具(例如Webpack),而不依赖于底层工具库,而底层工具库通常不需要输入。具体例子包括:

泊坞窗文件

复制代码

来自builder_web 的Node:16.20.0-alpine AS

工作目录/应用程序

添加./package.json /app/package.json

添加./pnpm-lock.yaml /app/pnpm-lock.yaml

# 安装依赖项

运行pnpm install –frozen-lockfile

添加./app

# 构建代码

运行pnpm 构建

来自nginx:1.21.0

# CDN同步脚本默认从/app/dist目录读取文件

复制–from=builder_web /app/dist /app/dist

复制–from=builder_web /app/config/nginx.conf /etc/nginx/conf.d/default.conf

3.2 BFF项目

要构建基于Nodejs 的BFF 项目,我们建议在构建阶段使用Alpine 镜像,在执行和部署阶段使用slim 镜像。原因是镜像中包含了一些基础的第三方工具包,方便二次安装。进入容器。

泊坞窗文件

复制代码

# Alpine 可以在构建阶段使用

来自Node:16.20.0-alpine 作为bff_build

# 作品列表

WORKDIR/工作区/应用程序

#复制依赖文件

复制./package.json /workspace/app/package.json

复制./yarn.lock /workspace/app/yarn.lock

# 安装依赖项

运行纱线–frozen-lockfile –check-files

#复制源代码

复制./工作区/应用程序

构建

RUN Yarn 执行构建

#在部署阶段使用基础镜像和精简镜像

来自Node:16.20.0-slim

# 作品列表

WORKDIR/工作区/应用程序

#复制依赖项

复制–from=bff_build /workspace/app/package.json /workspace/app/package.json

复制–from=bff_build /workspace/app/node_modules /workspace/app/node_modules

#复制内容

复制–from=bff_build /workspace/app /workspace/app

开始

CMD 纱线运行运行

3.3 npm包场景

要发布npm 包,我们建议使用gitlab-ci,因为它独立于工具包。但是,如果您使用lerna等多包管理工具,则可能会依赖git。在线安装现有的Alpine 或Slim 映像。

亚穆尔

复制代码

阶段:

– 发布

before_script:

– 回显$CI_COMMIT_TAG

发布:

阶段: 已发布

image: node:16.20.0-slim

脚本:

– echo -e $NPM_AUTH_CONTENT ~/.npmrc # 插入私有仓库令牌

– 纱线安装–frozen-lockfile

– |

如果[[ $CI_COMMIT_TAG==*\’beta\’* ]];

echo \’发布测试版标签\’

纱线发布–tag beta –non-interactive –no-commit-hooks

除此之外

echo \’发布官方标签\’

线程释放–non-interactive –no-commit-hooks

仅:

参考:

-标签

当然,还有其他场景,但是根据每个标签的特点,您可以选择适合您项目的标签。

4. 自定义nodejs镜像

除了直接使用官方的NodeJS镜像之外,我们还封装了适合我们公司项目的NodeJS镜像,并且我们可以在镜像中添加定制的逻辑,以解决我们公司所有项目共有的问题,比如配置,目的是方便。的统一处理设置公司的npm 代理源、常用npm 包的第三方依赖变量、安装pnpm、处理安装和构建过程中由于buildkit 缓存错误导致的构建失败等等。封装有两种想法。

Idea 1: 从头开始包装

Idea 2: 基于官方镜像的二次包

4.1 从零封装自己的nodejs镜像

让我们以高山的图像为例。

泊坞窗文件

复制代码

# 选择Alpine 版本的镜像

来自阿尔卑斯:3.18

# 定义节点版本

ENV 节点版本16.20.0

# 设置APK源为阿里巴巴源

RUN sed -i \’s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g\’ /etc/apk/repositories apk 更新

# 配置源并托管一些在中国很难下载的二进制依赖文件。

复制./.npmrc /root/.npmrc

# 使用apk安装依赖

运行addgroup -g 1000 个节点\\

adduser -u 1000 -G 节点-s /bin/sh -D 节点\\

apk 添加–no-cache \\

libstdc++\\

apk 添加–no-cache –virtual .build-deps \\

卷曲\\

ARCH=alpineArch=\’$(apk –print-arch)\’ \\

\\ 案例\’${alpineArch##*-}\’

x86_64)\\

ARCH=\’x64\’ \\

校验和=\’d2df78a192bd78b958e19a77821916a38def5e9e46c0c9a0989fdf5eb6c14a7e\’\\

;

*) ;

艾萨克\\

如果[ -n \’${CHECKSUM}\’ ];

设置-欧盟;

curl -fsSLO –compressed \’https://unofficial-builds.nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\’;

echo \’$CHECKSUM 节点-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\’ | sha256sum -c – \\

tar -xJf \’node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\’ -C /usr/local –strip-components=1 –no-same-owner \\

ln -s /usr/local/bin/node /usr/local/bin/nodejs;

除此之外\\

echo \’从源代码构建\’ \\

# 备份构建

apk 添加–no-cache –virtual .build-deps-full \\

binutils-gold\\

克++\\

海湾合作委员会\\

gnupg\\

libgcc\\

Linux 头文件\\

制作\\

Python3\\

# 使用现有的gpg 目录。请参阅https://github.com/nodejs/docker-node/pull/1895#issuecomment-1550389150。

导入GNUPGHOME=\’$(mktemp -d)\’ \\

# gpg 密钥列于https://github.com/nodejs/node#release-keys

对于关键\\

4ED778F539E3634C779C87C6D7062848A1AB005C\\

141F07595B7B3FFE74309A937405533BE57C7D57 \\

74F12602B6F1C4E913FAA37AD3A89613643B6201 \\

DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 \\

61FC681DFB92A079F1685E77973F295594EC4689\\

8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \\

C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \\

890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 \\

C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \\

108F52B48DB57BB0CC439B2997B01419BD92F80A\\

; 做\\

gpg –batch –keyserver hkps://keys.openpgp.org –recv-keys \’$key\’ ||

gpg –batch –keyserver keyserver.ubuntu.com –recv-keys \’$key\’ ;

结尾\\

curl -fsSLO –compressed \’https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz\’ \\

卷曲-fsSLO –压缩\’https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc\’\\

gpg –batch –decrypt –output SHASUMS256.txt SHASUMS256.txt.asc \\

gpgconf –删除全部\\

rm -rf \’$GNUPGHOME\’ \\

grep \’节点v$NODE_VERSION.tar.xz\\$\’ SHASUMS256.txt -c – \\

tar -xf \’node-v$NODE_VERSION.tar.xz\’ \\

cd \’节点-v$NODE_VERSION\’ \\

。 /配置,设置\\

make -j$(getconf _NPROCESSORS_ONLN) V=\\

执行安装\\

apk del .build-deps-full \\

光盘.\\

rm -Rf \’节点v$NODE_VERSION\’ \\

rm \’node-v$NODE_VERSION.tar.xz\’ SHASUMS256.txt.asc SHASUMS256.txt;

菲\\

rm -f \’节点-v$NODE_VERSION-linux-$ARCH-musl.tar.xz\’ \\

apk del .build-deps \\

#冒烟测试

节点–版本\\

npm –版本

ENV YARN_VERSION 1.22.19

运行apk add –no-cache –virtual .build-deps-yarncurl gnupg tar \\

# 使用现有的gpg 目录。请参阅https://github.com/nodejs/docker-node/pull/1895#issuecomment-1550389150。

导入GNUPGHOME=\’$(mktemp -d)\’ \\

对于关键\\

6A010C5166006599AA17F08146C2130DFD2497F5\\

; 做\\

gpg –batch –keyserver hkps://keys.openpgp.org –recv-keys \’$key\’ ||

gpg –batch –keyserver keyserver.ubuntu.com –recv-keys \’$key\’ ;

结尾\\

curl -fsSLO –compressed \’https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz\’ \\

curl -fsSLO –compressed \’https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc\’ \\

gpg –batch –verify 纱线-v$YARN_VERSION.tar.gz.asc 纱线-v$YARN_VERSION.tar.gz \\

& gpgconf –kill all \\
&& rm -rf \”$GNUPGHOME\” \\
&& mkdir -p /opt \\
&& tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \\
&& ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \\
&& ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \\
&& rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \\
&& apk del .build-deps-yarn \\
# smoke test
&& yarn –version
# 安装pnpm依赖
RUN npm install -g pnpm
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT [\”docker-entrypoint.sh\”]
CMD [ \”node\” ]
其实就是参照官方镜像的构建方式,在里面进行适当的修改

当然还可以基于其它某个linux发行版来进行封装,如下所示

yaml
复制代码
FROM centos:7
RUN curl -L https://dl.yarnpkg.com/rpm/yarn.repo -o /etc/yum.repos.d/yarn.repo
RUN curl –silent –location https://rpm.nodesource.com/setup_14.x | bash –
RUN yum install -y nodejs yarn
WORKDIR /code
EXPOSE 80
CMD npm start

4.2 基于官方镜像二次封装

以slim镜像为例

dockerfile
复制代码
FROM node:16.20.0-slim
RUN sed -i s/deb.debian.org/archive.debian.org/g /etc/apt/sources.list && \\
sed -i \’s|security.debian.org|archive.debian.org|g\’ /etc/apt/sources.list && \\
sed -i \’/stretch-updates/d\’ /etc/apt/sources.list && \\
apt-get clean && \\
apt-get update && \\
apt-get install -y tzdata tree git && \\
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
ARG CUSTOM_NODE_VERSION
COPY ./.npmrc /root/.npmrc
RUN npm install -g pnpm@6.32.3 \\
&& pnpm config set store-dir /root/.pnpm-store \\
&& npm config set custom_node_version $CUSTOM_NODE_VERSION

这样的话,封装起来清爽一些

至于自己封装的nodejs镜像可以发到自己的私仓,比如Nexus搭建的私仓,或者阿里云、腾讯云上买的私仓等

当然在封装的时候如果我们要安装一些额外的工具包,因为国内网络的问题,所以我们一般会将debian的源设置成国内源

5. 总结

nodejs官方镜像主要由三部分组成 linux版本 + 工具包合集 + nodejs运行时,三部分可以组合成不同的tag,每种组合都有其应用的场景,我们可以根据大小、安全、功能来进行选择

一般项目推荐使用:alpine or slim镜像,不推荐使用完整镜像特殊项目推荐根据alpine or slim镜像进行二次封装,解决公司的通用问题,提高研发效率

像我们公司就选择封装自己的nodejs镜像,会在镜像内做如下事情

设置公司自己的npm代理源
设置npm包的第三方依赖环境变量,比如node-sass、puppeteer等
安装pnpm
解决CI场景因为buildkit缓存问题导致的install 失败或者build失败
bff启动之前的前置检查等

当然如果对镜像大小追求极致的,可以在去删减镜像内的工具包,或者通过copy的方式只拷贝工具的执行文件等方式去缩减镜像大小

最后通过选择合适的镜像,可以帮助我们构建高效的CI/CD流程
#以上关于解析Node.js镜像原理,轻松构建高效CI/CD流程的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92757.html

Like (0)
CSDN的头像CSDN
Previous 2024年6月28日
Next 2024年6月28日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注