有两种方法来安装Node,yum的奇怪行为

环境 is a word in Chinese.

环境:云服务器(EC2)
操作系统:亚马逊 Linux 2

通常的节点安装和yum的奇妙之处。

首先安装nodejs!
看起来nodejs 18是最新版本,我们试试吧!
第一步是添加存储库,可以使用以下命令添加。

[ec2-user@ip-10-0-251-210 ~]$ sudo yum install -y gcc-c++ make
...(略)
Complete!
[ec2-user@ip-10-0-251-210 ~]$ curl -sL https://rpm.nodesource.com/setup_18.x | sudo -E bash -

## Installing the NodeSource Node.js 18.x repo...
...(略)
## Run `sudo yum install -y nodejs` to install Node.js 18.x and npm.
...(略)

好的,看起来不错!我将执行安装命令!

[ec2-user@ip-10-0-251-210 ~]$ sudo yum install -y nodejs
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
nodesource                                               | 2.5 kB     00:00
nodesource/x86_64/primary_db                               |  37 kB   00:00
277 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package nodejs.x86_64 2:18.14.2-1nodesource will be installed
--> Processing Dependency: libc.so.6(GLIBC_2.28)(64bit) for package: 2:nodejs-18.14.2-1nodesource.x86_64
--> Processing Dependency: libm.so.6(GLIBC_2.27)(64bit) for package: 2:nodejs-18.14.2-1nodesource.x86_64
--> Finished Dependency Resolution
Error: Package: 2:nodejs-18.14.2-1nodesource.x86_64 (nodesource)
           Requires: libc.so.6(GLIBC_2.28)(64bit)
Error: Package: 2:nodejs-18.14.2-1nodesource.x86_64 (nodesource)
           Requires: libm.so.6(GLIBC_2.27)(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

哎?需要:libc.so.6(GLIBC_2.28)(64位)的话,好像需要安装这个libc.so.6(GLIBC_2.28)(64位)。

稍微调查了一下,发现nodejs 18和Amazon Linux 2的兼容性似乎并不是很好。
https://itneko.com/amazon-linux2-nodejs18/

所以,我打算安装16而不是18!

那么,首先我们要添加16的存储库!

[ec2-user@ip-10-0-251-210 ~]$ curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash -

## Installing the NodeSource Node.js 16.x repo...
...(略)
## Run `sudo yum install -y nodejs` to install Node.js 16.x and npm.
...(略)

好的,看起来不错!我们可以使用sudo yum install -y nodejs命令来安装nodejs!

[ec2-user@ip-10-0-251-210 ~]$ sudo yum install -y nodejs
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
277 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package nodejs.x86_64 2:18.14.2-1nodesource will be installed
--> Processing Dependency: libc.so.6(GLIBC_2.28)(64bit) for package: 2:nodejs-18.14.2-1nodesource.x86_64
--> Processing Dependency: libm.so.6(GLIBC_2.27)(64bit) for package: 2:nodejs-18.14.2-1nodesource.x86_64
--> Finished Dependency Resolution
Error: Package: 2:nodejs-18.14.2-1nodesource.x86_64 (nodesource)
           Requires: libc.so.6(GLIBC_2.28)(64bit)
Error: Package: 2:nodejs-18.14.2-1nodesource.x86_64 (nodesource)
           Requires: libm.so.6(GLIBC_2.27)(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

哎呀,等一下,你又嘗試安裝18版了嗎?明明已經添加了16版的倉庫…

好吧,我会删除所有与node相关的RPM软件包并尝试重新安装!

[ec2-user@ip-10-0-251-210 ~]$ rpm -qa | grep -i node
nodesource-release-el7-1.noarch
[ec2-user@ip-10-0-251-210 ~]$ sudo yum remove nodesource-release-el7-1.noarch -y
...(略)
Removed:
  nodesource-release.noarch 0:el7-1

Complete!

让我们确认一下文件是否从/etc/yum.repos.d目录中消失了。

[ec2-user@ip-10-0-251-210 ~]$ ls -a /etc/yum.repos.d | grep node
[ec2-user@ip-10-0-251-210 ~]$

听起来不错!那我就再试一次安装吧!

[ec2-user@ip-10-0-251-210 ~]$ curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash -
(略)
[ec2-user@ip-10-0-251-210 ~]$ sudo yum install -y nodejs
Failed to set locale, defaulting to C
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
277 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package nodejs.x86_64 2:18.14.2-1nodesource will be installed
--> Processing Dependency: libc.so.6(GLIBC_2.28)(64bit) for package: 2:nodejs-18.14.2-1nodesource.x86_64
--> Processing Dependency: libm.so.6(GLIBC_2.27)(64bit) for package: 2:nodejs-18.14.2-1nodesource.x86_64
--> Finished Dependency Resolution
Error: Package: 2:nodejs-18.14.2-1nodesource.x86_64 (nodesource)
           Requires: libc.so.6(GLIBC_2.28)(64bit)
Error: Package: 2:nodejs-18.14.2-1nodesource.x86_64 (nodesource)
           Requires: libm.so.6(GLIBC_2.27)(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

假的,我还没有18岁呢!

实际上,即使使用 “sudo yum remove {包名}” 命令删除了 RPM 包,仍然会保留缓存。

让我们再试着抹掉一次。

[ec2-user@ip-10-0-251-210 ~]$ sudo yum remove nodesource-release-el7-1.noarch -y
...
Removed:
  nodesource-release.noarch 0:el7-1

Complete!
[ec2-user@ip-10-0-251-210 ~]$ ls -a /etc/yum.repos.d | grep node
[ec2-user@ip-10-0-251-210 ~]$
[ec2-user@ip-10-0-251-210 ~]$ ls /var/cache/yum/x86_64/2 | grep nodesource
nodesource
nodesource-source

噢,那个地方有啊!

让我试着手动删除。

[ec2-user@ip-10-0-251-210 ~]$ sudo rm -rf /var/cache/yum/x86_64/2/nodesource
[ec2-user@ip-10-0-251-210 ~]$ sudo rm -rf /var/cache/yum/x86_64/2/nodesource-source/

再次尝试安装看看。。。

[ec2-user@ip-10-0-251-210 ~]$ curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash -
(略)
[ec2-user@ip-10-0-251-210 ~]$ sudo yum install -y nodejs
...(略)
Installed:
  nodejs.x86_64 2:16.19.1-1nodesource

Complete!

这次很成功!

之后查了一下才发现,好像可以使用 yum clean 来删除相同数量的 RPM 包和缓存。

让我们确认一下版本吧。

[ec2-user@ip-10-0-251-210 ~]$ node --version
v16.19.1
[ec2-user@ip-10-0-251-210 ~]$ npm --version
8.19.3

这个版本似乎是正确的!

但是在操作系统上安装还是比较麻烦的。我们来使用Docker吧!

安裝 Docker 和 Docker Compose,啟動 Node 的 Docker 容器。

[ec2-user@ip-10-0-251-210 ~]$ sudo amazon-linux-extras install -y docker
Installing docker
...(略)
Installed:
  docker.x86_64 0:20.10.17-1.amzn2.0.2

Complete!
...(略)

安装完成了!我会启动并检查状态。

[ec2-user@ip-10-0-251-210 ~]$ sudo systemctl start docker
[ec2-user@ip-10-0-251-210 ~]$ sudo systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Thu 2023-03-09 17:22:40 UTC; 5s ago
...(略)

看起来一切顺利!接下来安装docker-compose。

[ec2-user@ip-10-0-251-210 ~]$ sudo mkdir -p /usr/local/lib/docker/cli-plugins
[ec2-user@ip-10-0-251-210 ~]$ VER=2.4.1
[ec2-user@ip-10-0-251-210 ~]$ sudo curl \
>   -L https://github.com/docker/compose/releases/download/v${VER}/docker-compose-$(uname -s)-$(uname -m) \
>   -o /usr/local/lib/docker/cli-plugins/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 25.2M  100 25.2M    0     0  8885k      0  0:00:02  0:00:02 --:--:-- 11.3M
[ec2-user@ip-10-0-251-210 ~]$ sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
[ec2-user@ip-10-0-251-210 ~]$ sudo ln -s /usr/local/lib/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose

Docker Compose安装完成了!让我们来验证版本。

[ec2-user@ip-10-0-251-210 ~]$ docker-compose --version
Docker Compose version v2.4.1

好的,看起来都可以!

只需编写Compose文件并启动容器即可。

首先,创建一个用于存放代码的文件夹,并进入其中。

mkdir node-test-project
cd node-test-project

接下来,创建并保存以下文件。

# docker-compose.yml

version: '3.7'
services:
  node:
    image: node:18.15.0-slim
    container_name: node
    tty: true
    ports:
      - 3000:3000
    logging:
      driver: "json-file"
      options:
        max-size: "50m"

最后只需启动!

[ec2-user@ip-10-0-251-210 node-test-project]$ docker-compose up -d
[+] Running 6/6
 ⠿ node Pulled                         6.0s
   ⠿ 3f9582a2cbe7 Pull complete        1.7s
   ⠿ 94e5d5746476 Pull complete        1.8s
   ⠿ 11587a4aecf2 Pull complete        3.4s
   ⠿ d1ed1db27c1b Pull complete        3.5s
   ⠿ 8f4c41bcb791 Pull complete        3.6s
[+] Running 2/2
 ⠿ Network node-test-project_default  Created  0.0s
 ⠿ Container node                     Started  1.7s

让我们检查容器是否已启动,并确认node和npm的版本!

[ec2-user@ip-10-0-251-210 node-test-project]$ docker-compose ps
NAME     COMMAND                  SERVICE     STATUS      PORTS
node     "docker-entrypoint.s…"   node        running     0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
[ec2-user@ip-10-0-251-210 node-test-project]$ docker exec node node --version
v18.15.0
[ec2-user@ip-10-0-251-210 node-test-project]$ docker exec node npm --version
9.5.0

虽然 Docker 的安装本身有些麻烦,但一旦安装好,可以立即使用任何软件,这真是太棒了。