手摸手,带你部署Node(Docker、Linux)

2,157 阅读12分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

  • 在线音乐戳我呀!
  • 音乐博客源码上线啦!
  • 前两个月有一段时间没有写文章了,不是我懒,而是最近项目加班太严重了,连续加班一个星期,项目经理自己下班早,看不到凌晨三点努力的我们,就说版本不可延期,上线后请一天假休息还撕破嘴皮。
  • 做一件事,最心酸的莫过于你已经很努力干活了,甚至没有一点怨言,只想听到别人对你的赞扬,心里可能就足矣,最怕人家根本不领情,反倒过来说你这不好,那不好。
  • 当然晚上还是会花点时间学习,毕竟时间就像牛奶一样,挤一点总会有的。
  • 之前在顺德工作服务器是Win,导致我的服务器一直都是Win,换工作到广州,服务器基本都是Linx,发现Linx各种好,对于我现在,空间是一道硬伤,于是我决定迁移成Linx系统。
  • 下面一步一步带你走进全过程 | Node篇(内含部署实战)。

头上的绿有点多,来,大叔我免费帮你剪一下。

59.jpg

需求

目前音乐博客部署在Win7上,应用主要有:

需要将以上应用迁移到Linx上,干!

很多公司不让碰服务器,现在可以看看关注我,记录从Linux上无到有,全过程。
这一篇是主要还是写给还在用win服务器的、准备迁移Linux的朋友,可以练习迁移服务器到Linux,Linux有很多好处,最可见的就是空间、速度快...
迁移过程中,势必会有很多坑等着你来解决,上方的需求都会写上,本篇主要讲解Docker、Linux部署Node,其他应用后续持续更新,敬请期待!

一、Docker部署NodeJs应用

音乐博客后端以Node作为主后台,需要安装Node镜像。

1.1 拉取Node镜像

我们先拿一个Node小例子,来docker上启动起来。

先从国内的镜像网站上pull下一下nodejs镜像。

docker pull hub.c.163.com/nce2/nodejs:0.12.2

2.png

下载完后查看我们的镜像,找到他的名称,等会我们会用到。

3.png

1.2 创建Node程序

写一个最简单Node小例子基于express框架,返回Hello word.注意我们监听的是8888端口。

创建package.json,并写入相关信息和依赖。

{
  "name": "webtest",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "lpxxn",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.13.3"
  }
}

创建server.js

'use strict';

var express = require('express');

var PORT = 8888;

var app = express();
app.get('/', function (req, res) {
  res.send('Hello world\n');
});

app.listen(PORT);
console.log('Running on http://localhost:' + PORT);

1.3 创建Dockerfile

我们在Docker上运行程序,那离不开Dockerfile主角,构建镜像的时候,docker执行的正是Dockerfile文件,这个文件是创建镜像所必须的文件。

FROM hub.c.163.com/nce2/nodejs:0.12.2

# Create app directory
RUN mkdir -p /home/Service
WORKDIR /home/Service

# Bundle app source
COPY . /home/Service
RUN npm install

EXPOSE 8888
CMD [ "npm", "start" ]

参数说明

  • FROM hub.c.163.com/nce2/nodejs:0.12.2

    • FROM是构建镜像的基础源镜像,hub.c.163.com/nce2/nodejs:0.12.2 这个是镜像的名称,也就是我们一开始从国内服务器上拉下来的那个Image。如果本地没有Docker 会自己pull镜像。

    • 所以2.1 拉取Node镜像这一步,我们可以偷个懒😁。

  • RUN mkdir -p /home/Service

    • RUN可以用来执行命令,比如:run npm irun npm -v等等。

    • RUN 用于在Image里创建一个文件夹,将来用于保存我们的代码。

    • 这里的新建文件夹说在Docker内部创建的,而不是Linux。

  • WORKDIR /home/Service

    • WORKDIR是将我们创建的文件夹做为工作目录。
  • COPY . /home/Service

    • COPY是把本机当前目录下的所有文件拷贝到Image的/home/Service文件夹下。

    • 把Linux的Node小应用拷贝到Docker的/home/Service文件夹下。

  • RUN npm install

    • RUN 使用npm 安装我们的app需要的所有依赖。
  • EXPOSE 8888

    • 由于我们的web app监听的是8888端口,我们把这个端口暴露给主机,这样我就能从外部访问web了。
  • CMD [ "npm", "start" ]

    • 运行npm start命令,这个命令会运行 node service.js来启动我们的web app。

1.4 构建Image

Node镜像已安装,Dockerfile文件也已创建,node小应用也有了,接下来就是借助Dockerfile把Node小应用打包到Docker中。

在你Dockerfile文件所在的目录下运行下面的命令来构建一个Image。

docker build -t mynodeapp .

别忘了最后的那个点。

4.png

构建完后查看一下我们的镜像。

5.png

有人可能要问了,我Dockerfile文件中RUN npm i的依赖呢,怎么没看到?

32.png

不会在Linux中的,是打包在Docker镜像中。

1.5 运行镜像

应用已经打包成功,接下来运行该包。

docker run -d -p 8888:8888 mynodeapp

#又或者
docker run -d -p 8888:8888 ac5  #后面会解释

参数说明

  • -d 表明容器会在后台运行。

  • -p 表示端口映射。

  • 把本机的8888端口映射到容器container的8888端口,这样外网就能通过本机的8888端口访问我们的web了。(这里的本地指的是Linux)

  • ac5是我们Image的ID因为前3个就已经能定位出这个Image,所以我就没有把后边的再写出来。

换句话说:我们在docker run启动镜像的时候,可以写镜像的名字,或者写镜像的前三位id。

通过docker ps 查看我们刚运行的Container的ID。

6.png

注意:这里的id是容器id(镜像运行id),而上面提到的ac5是镜像id(应用打包镜像id)

1.6 查看容器日志

打印log 7370就是我们的Container ID(容器id),和Image ID(镜像)一样,你也可以全写出来,正常我们就写前4位,已经足够标识出这个Container了。

docker ps 7350

7.png

如果你想到Container里可以执行下面的命令(进入容器内部),进入到里边后就可以像操作普通的linux 一样。如果想退出可执行exit命令。

8.png

1.7 测试

我们先通过curl 看能不能访问我们的web。

curl -i localhost:8888

不通。docker应用启动后,并不能访问。

再curl一下百度的。

curl -i www.baidu.com

10.png

验证结果:访问外网是没问题的,证明网络没问题,但内部服务端口不通。

第一个问题来了:权限不足,引起的。加sudo管理员权限。

sudo docker run -d -p 8888:8888 ac5

这是一个linux上经典问题,没权限。

我们再curl一下。

9.png

端口通了。

小总结:如何验证该端口能不能访问,通过curl命令。

二、在线音乐后台node部署过程史

讲到Docker安装使用Node,我也顺便贴上实战过程中,我的在线音乐后台Node部署遇到的错误也分享一下下。(Linux小白)

2.1 npm i时候报错

在Docker里面运行Node项目,执行Dockerfile文件到npm i的时候报了一个错误。

29.png

试过好几个方法,当时解决不了,干脆Node服务代码连同nodules_modules文件夹也丢进去,在外面就已经安装好,我们的Docker直接启动即可。

这也是一种解决方法,当然这肯定不好,那我们先运行起项目先,先打通,后续在优化解决问题。

说给使用npm版本7.13.0运行,好,那我们就在Dockerfile里面加上RUN npm i -gnpm@7.13.0

注意这里的在Docker中安装升级的哦~

2.2 Dockerfile文件最好放在项目同目录

现在我们已经将npm升级,不报错了,但也没有显示任何信息,最怕的就是这种运行不起来还没有报错信息的问题了。

30.png

我猜测是Node版本的问题。

于是在Dockerfile文件中将引入Node版本从10换成FROM node:latest,成功。

31.png

因为docker ps是运行成功的容器才会显示在这里面,在写给还用Win服务器的朋友,该转型Linux啦的2.5有提到。

要注意的一点是Dockerfile文件最好放在项目同目录,一开始Dockerfile放在别的地方,导致起不起来,路径的问题。

小总结:npm、node版本都使用新点,之前的版本可能是有冲突的。Dockerfile文件最好放在项目同目录,一开始Dockerfile放在别的地方,导致起不起来,路径的问题

2.3 nodemon:Permission Denied

node项目运行起来,报错:nodemon:Permission Denied

43.png

原因说Node版本的问题,2.2 Dockerfile文件最好放在项目同目录的时候将版本升级到最新引起的,其实上方:将npm升级,不报错了,但也没有显示任何信息。

真正的原因不是Node版本的问题,而是Dockerfile文件没有放在项目同目录,所以运行起来没有任何信息。

解决方法将Node版本又降回去,即:FROM node:10.22.0,和本地开发保持一致。

三、Linux部署NodeJs应用

上面1.7 测试端口不通的时候,我默默做了另外一件事,在Linux上运行一下Node小应用,看看能不能访问,验证是不是docker的问题。

Linux上安装Node有两种方法:

  • 通过事先下载好的包,放进去linux中解压安装。

  • 通过wget把包下载下来。

3.1 通过事先下载好的包,放进去linux中解压安装

3.1.1 去官网下载和自己系统匹配的文件

Node英文网址

Node中文网址

通过 uname -a 命令查看到我的Linux系统位数是64位(备注:x86_64表示64位系统, i686 i386表示32位系统)。

11.png

故下载一下红色框中文件 ,版本为v6.10.0

12.png

3.1.2 下载下来的tar文件上传并解压,通过建立软连接变为全局

软连接是什么?

23.jpg

上传服务器可以是自己任意路径,目前我的放置路径为:cd /app/software/

解压上传(解压后的文件我这边将名字改为了nodejs,这个地方自己随意,只要在建立软连接的时候写正确就可以)

#1. 解压
tar -xvf   node-v6.10.0-linux-x64.tar.xz

#2. 改名字
mv node-v6.10.0-linux-x64  nodejs

确认一下nodejs下bin目录是否有node 和npm文件,如果有执行软连接,如果没有重新下载执行上边步骤。

建立软连接,变为全局:

ln -s /app/software/nodejs/bin/npm /usr/local/bin/

ln -s /app/software/nodejs/bin/node /usr/local/bin/

最后一步检验nodejs是否已变为全局。

在Linux命令行node -v 命令会显示nodejs版本。

13.png

3.2 通过wget把包下载下来

3.2.1 安装wget

yum install -y wget

3.2.2 下载nodejs最新的bin包

wget https://nodejs.org/dist/v9.3.0/node-v9.3.0-linux-x64.tar.xz

另外你也可以在你喜欢的任意系统上下载最新的bin包,然后通过FTP上传到CentOS上。

3.2.3 解压包

包类型:

  • tar

  • tar.gz

如果是tar类型的包,请依次执行:

xz -d node-v9.3.0-linux-x64.tar.xz

tar -xf node-v9.3.0-linux-x64.tar

如果是tar.gz类型的包,请解压执行:

tar -zxvf node-v0.10.24.tar.gz

3.2.4 部署bin文件

先确认你nodejs的路径,我这里的路径为~/node-v9.3.0-linux-x64/bin。确认后依次执行。

ln -s ~/node-v9.3.0-linux-x64/bin/node /usr/bin/node

ln -s ~/node-v9.3.0-linux-x64/bin/npm /usr/bin/npm

注意ln指令用于创建关联(类似与Windows的快捷方式)必须给全路径,否则可能关联错误。

3.2.5 测试

node -v

如果正确输出版本号,则部署成功。

可惜我,报错-bash: /usr/local/bin/node: Permission denied

14.png

检查之后,问题说没权限,于是删除node环境,重新安装低版本的node,解压的时候在linux上解压,不要在win上解压,win解压完后是有几个文件是解压失败的。(小坑)

然后在全局配置一下。

ln -s /app/software/nodejs/bin/npm /usr/local/bin/

ln -s /app/software/nodejs/bin/node /usr/local/bin/

linux 系统下卸载Node.js

先卸载npm

sudo npm uninstall npm -g

再卸载node

yum remove nodejs npm -y

看看是否有残留

进入 /usr/local/lib 删除所有 node 和 node_modules文件夹

进入 /usr/local/include 删除所有 node 和 node_modules 文件夹

进入 /usr/local/bin 删除 node 的可执行文件

Linux:-bash: unzip: command not found

Linux下解压.zip文件报错

-bash: unzip: command not found

解决办法:

yum install unzip zip

3.3 建立软连接可能会出现fail问题

在建立软连接时如果出现下面问题,就去删除 /usr/lcoal/bin 下的 node 和npm。

24.jpg

25.jpg

3.4 Linux上安装npm、cnpm

安装node。

wget https://nodejs.org/dist/v10.15.0/node-v10.15.0-linux-x64.tar.xz

解压。

tar -xf node-v10.15.0-linux-x64.tar.xz

配置全局变量。

# vim /etc/profile

PATH=$PATH:/usr/local/node/node-v10.15.0-linux-x64/bin

更新配置文件。

source /etc/profile

33.png

安装cnpm。

npm install -g cnpm --registry=https://registry.npm.taobao.org

最后

我们完成了需求之一:Node作为主后台,需要安装Node镜像。

Node是我们JavaScript的后台,一定要崛起呀,朋友们!

我们总是喜欢以项目来驱动学习,不是吗?

我也是,通过个人项目 - 在线音乐 来驱动我学习Linux系统、Docker、Java、Nginx等等前端可能接触不到的知识,我想这可能就是管理层的“广度”。

下篇讲解Oracle,回见啦~

相关文献

Docker实践--部署Nodejs应用

docker应用启动后浏览器无法访问

在Linux系统安装Nodejs 最简单步骤

Linux系统安装Nodejs的万能方法

Node中的“Permission Denied”

指定Node版本

Linux:-bash: unzip: command not found

linux 系统下安装和卸载Node.js

linux-安装npm、cnpm

以往推荐

Typora拖拉图片生成在线图片 | Gitee图床

多图详解,一次性啃懂原型链(上万字)

Vue-Cli3搭建组件库

Vue实现动态路由(和面试官吹项目亮点)

项目中你不知道的Axios骚操作(手写核心原理、兼容性)

VuePress搭建项目组件文档

vue-typescript-admin-template后台管理系统

原文链接

juejin.cn/post/702392…