从源码构建基于Alpine的NodeJS镜像
发布日期:2021-06-30 20:13:24 浏览次数:2 分类:技术文章

本文共 7381 字,大约阅读时间需要 24 分钟。

在前一篇文章中介绍了直接使用Alpine的npmjs与npm的package的方式来构建NodeJS镜像,但是这种方法的局限性目前在于Alpine的包所支持的版本有限,如果所需版本不能通过apk add来添加,使用源码进行编译来生成所需的NodeJS包则成为解决方法之一。这篇文章将通过在具体的版本来介绍如何在Alpine中进行源码的编译来生成NodeJS的二进制包。

源码编译方式说明

和基于m4的源码编译方式类似,还是configure && make && make install三板斧即可完成。事前保证编译器等准备条件,安装成功基本应该不会碰到问题。在本文中直接使用Alpine镜像启动一个容器来说明源码安装的整个过程

步骤1: 启动Alpine容器

liumiaocn:~ liumiao$ docker run -it --rm alpine:3.10.2 sh/ #

步骤2: 事前准备

需要安装的包包括:python gcc g++ make linux-headers

  • 安装python
~ # apk add pythonfetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gzfetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz(1/10) Installing libbz2 (1.0.6-r7)(2/10) Installing expat (2.2.8-r0)(3/10) Installing libffi (3.2.1-r6)(4/10) Installing gdbm (1.13-r1)(5/10) Installing ncurses-terminfo-base (6.1_p20190518-r0)(6/10) Installing ncurses-terminfo (6.1_p20190518-r0)(7/10) Installing ncurses-libs (6.1_p20190518-r0)(8/10) Installing readline (8.0.0-r0)(9/10) Installing sqlite-libs (3.28.0-r1)(10/10) Installing python2 (2.7.16-r1)Executing busybox-1.30.1-r2.triggerOK: 139 MiB in 34 packages~ #

注:如果python不安装的话,可能会提示

./configure: exec: line 4: python: not found

查看解压后的代码,从congigure可以看到如下代码,所以python也是需要的

/tmp/node-v8.6.0 # grep python configure # Locate python2 interpreter and re-execute the script.  Note that thewhich python2.7 >/dev/null && exec python2.7 "$0" "$@"which python2 >/dev/null && exec python2 "$0" "$@"exec python "$0" "$@"  python2 = which('python2') or which('python2.6') or which('python2.7')  if python2:    sys.stderr.write('  ' + python2 + ' ' + ' '.join(sys.argv))/tmp/node-v8.6.0 #
  • 安装gcc编译器和g++编译器
~ # apk add --no-cache gccfetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gzfetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz(1/10) Installing binutils (2.32-r0)(2/10) Installing gmp (6.1.2-r1)(3/10) Installing isl (0.18-r0)(4/10) Installing libgomp (8.3.0-r0)(5/10) Installing libatomic (8.3.0-r0)(6/10) Installing libgcc (8.3.0-r0)(7/10) Installing mpfr3 (3.1.5-r1)(8/10) Installing mpc1 (1.1.0-r0)(9/10) Installing libstdc++ (8.3.0-r0)(10/10) Installing gcc (8.3.0-r0)Executing busybox-1.30.1-r2.triggerOK: 92 MiB in 24 packages~ #
  • 安装make
~ # apk add --no-cache makefetch http://dl-cdn.alpinelinux.org/alpine/v3.10/main/x86_64/APKINDEX.tar.gzfetch http://dl-cdn.alpinelinux.org/alpine/v3.10/community/x86_64/APKINDEX.tar.gz(1/1) Installing make (4.2.1-r2)Executing busybox-1.30.1-r2.triggerOK: 205 MiB in 38 packages~ #
  • 安装linux-headers
~ # apk add linux-headers(1/1) Installing linux-headers (4.19.36-r0)OK: 212 MiB in 39 packages~ #

如果不安装,在make的过程中,可能会提示如下类似的linux/xxx.h找不到的错误信息。还不是是因为Alpine删的太干净了,不然咋么才能这么小呢。

../deps/v8/src/base/cpu.cc:11:10: fatal error: linux/auxvec.h: No such file or directory #include 
// AT_HWCAP

步骤2: 下载nodejs源码

下载地址:wget https://nodejs.org/dist/版本号/node-v版本号.tar.gz

以8.6.0为例,源码下载方式为:

wget https://nodejs.org/dist/8.6.0/node-v8.6.0.tar.gz

可以使用任何方式获取源码,然后上传至Alpine容器之中。

/tmp # lsnode-v8.6.0.tar.gz/tmp #

步骤3: 解压源码

使用tar命令对源码进行解压

/tmp # tar xvf node-v8.6.0.tar.gz ...省略node-v8.6.0/benchmark/arrays/zero-int.js/tmp #/tmp # lsnode-v8.6.0         node-v8.6.0.tar.gz/tmp # cd node-v8.6.0//tmp/node-v8.6.0 # lsAUTHORS                COLLABORATOR_GUIDE.md  README.md              deps                   srcBSDmakefile            CONTRIBUTING.md        android-configure      doc                    testBUILDING.md            GOVERNANCE.md          benchmark              lib                    toolsCHANGELOG.md           LICENSE                common.gypi            node.gyp               vcbuild.batCODE_OF_CONDUCT.md     Makefile               configure              node.gypi/tmp/node-v8.6.0 #

步骤4: configure

执行命令:./configure

配置后续生成的二进制文件的目录,也可以直接设定到/usr/local等PATH搜索目录下,其实修改的是node_prefix的值。执行日志如下所示:

/tmp/node-v8.6.0 # ./configurecreating ./icu_config.gypi* Using ICU in deps/icu-smallcreating ./icu_config.gypi{ 'target_defaults': { 'cflags': [],                       'default_configuration': 'Release',                       'defines': [],                       'include_dirs': [],                       'libraries': []},  'variables': { 'asan': 0,                 'coverage': 'false',                 'debug_devtools': 'node',                 'debug_http2': 'false',                 'debug_nghttp2': 'false',                 'force_dynamic_crt': 0,                 'gas_version': '2.32',                 'host_arch': 'x64',                 'icu_data_file': 'icudt59l.dat',                 'icu_data_in': '../../deps/icu-small/source/data/in/icudt59l.dat',                 'icu_endianness': 'l',                 'icu_gyp_path': 'tools/icu/icu-generic.gyp',                 'icu_locales': 'en,root',                 'icu_path': 'deps/icu-small',                 'icu_small': 'true',                 'icu_ver_major': '59',                 'node_byteorder': 'little',                 'node_enable_d8': 'false',                 'node_enable_v8_vtunejit': 'false',                 'node_install_npm': 'true',                 'node_module_version': 57,                 'node_no_browser_globals': 'false',                 'node_prefix': '/usr/local',                 'node_release_urlbase': '',                 'node_shared': 'false',                 'node_shared_cares': 'false',                 'node_shared_http_parser': 'false',                 'node_shared_libuv': 'false',                 'node_shared_openssl': 'false',                 'node_shared_zlib': 'false',                 'node_tag': '',                 'node_use_bundled_v8': 'true',                 'node_use_dtrace': 'false',                 'node_use_etw': 'false',                 'node_use_lttng': 'false',                 'node_use_openssl': 'true',                 'node_use_perfctr': 'false',                 'node_use_v8_platform': 'true',                 'node_without_node_options': 'false',                 'openssl_fips': '',                 'openssl_no_asm': 0,                 'shlib_suffix': 'so.57',                 'target_arch': 'x64',                 'uv_parent_path': '/deps/uv/',                 'uv_use_dtrace': 'false',                 'v8_enable_gdbjit': 0,                 'v8_enable_i18n_support': 1,                 'v8_enable_inspector': 1,                 'v8_no_strict_aliasing': 1,                 'v8_optimized_debug': 0,                 'v8_promise_internal_field_count': 1,                 'v8_random_seed': 0,                 'v8_trace_maps': 0,                 'v8_use_snapshot': 'true',                 'want_separate_host_toolset': 0}}creating ./config.gypicreating ./config.mk/tmp/node-v8.6.0 #

步骤5: make && make install

执行命令:make && make install

执行日志如下所示:

/tmp/node-v8.6.0 # make && make installmake -C out BUILDTYPE=Release V=1...省略installing /usr/local/include/node/openssl/archs/VC-WIN32/opensslconf.hinstalling /usr/local/include/node/openssl/opensslconf.hinstalling /usr/local/include/node/zconf.hinstalling /usr/local/include/node/zlib.h/tmp/node-v8.6.0 #

注:make的时间较长,需要耐心等待。而make install主要是个copy动作,所以会很快。应为make速度很慢,如果CPU有多个,或者多核的情况下,可以考虑使用-j参数指定多个CPU加快速度。而至于CPU的个数几个合适,则可以考虑使用getconf来获取,getconf _NPROCESSORS_ONLN即可获取相应的个数。设定小于或等于此值以加快构建的速度,如果就一个CPU的话可以忽略。

步骤6: 结果确认

/tmp/node-v8.6.0 # which npm/usr/local/bin/npm/tmp/node-v8.6.0 # which node/usr/local/bin/node/tmp/node-v8.6.0 # node -vv8.6.0/tmp/node-v8.6.0 # npm -v5.3.0/tmp/node-v8.6.0 #

转载地址:https://liumiaocn.blog.csdn.net/article/details/102598121 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Jenkins基础:使用NPM构建前端应用2:在DSL中使用NodeJS
下一篇:如何构建基于Alpine的NodeJS镜像

发表评论

最新留言

很好
[***.229.124.182]2024年04月14日 10时11分21秒