前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Node.js服务端开发教程 (二):新的软件交付方式

Node.js服务端开发教程 (二):新的软件交付方式

作者头像
一斤代码
发布2019-11-06 19:26:30
3.2K0
发布2019-11-06 19:26:30
举报
文章被收录于专栏:大前端开发大前端开发

在上文中,我们从零开始安装了必需的一些NestJS开发环境,并使用命令行工具生成了第一个NestJS服务端程序,而且也初步了解了怎么把这个程序运行起来。

不过,作为一名优秀的软件工程师,光清楚开发程序的功能,是不太够的。因为软件早晚要拿到正式的环境、或其他各种各样的环境下去运行的,可怕的是,你根本不知道这些环境是什么操作系统,上面装了哪些软件,软件的版本是什么!有可能在你开发的电脑上运行的好好的程序,一到其他的电脑上就各种报错,根本运行不起来或是出现各种奇怪的问题。

这就是程序员界著名的“我本地是好的呀”问题。

为了解决这种环境差异带来的问题,业内陆续出现了各种各样的解决方案,比如早前的虚拟机,以及最近几年比较火的容器化。我们今天就想通过容器化的方式,将我们的第一个NestJS程序打包成一个拥有环境一致、代码一致、入口单一、不受外界影响的可交付产品。

说到容器化,有些朋友可能会脱口而出:Docker!对,没错,我们今天就是要使用到Docker。不过容器化工具不止Docker一种,像CoreOS之类的也是同类产品,只是Docker太出名了,导致很多朋友都把Docker当做容器化的代名词。另外容器化扩展出来的东西很庞大,比如容器编排(大家肯定听说过现在大名鼎鼎的Kubernetes,简称K8S;还有Docker自家旗下的Swarm),这些容器编排工具在集群管理和微服务领域有着非常重要的作用。内容太多,我们今天只粗浅的了解最简单的Docker使用。

安装Docker

没安装过Docker的朋友,先来安装下工具吧。如果你用的是Windows或Mac的电脑,可以从 https://www.docker.com/products/docker-desktop 这个网址下载Docker Desktop;Linux的用户可以通过各自的包管理工具(yum、apt等)进行安装。

安装完成后在命令行上输入下面的命令,确保Docker服务已经运行起来并正常可用:

代码语言:javascript
复制
docker ps

如果你看到了以下的信息(只要有红色的那几个表头就行),说明一切已经准备就绪:

如果你看到的是类似如下的信息,说明你的Docker服务器程序还没运行起来,请检查你的Docker Desktop(Windows、Mac)或dockerd(Linux)是不是正常启动了:

构建NestJS程序

还记得前文中,我们是怎么把程序运行起来?

代码语言:javascript
复制
npm run start 
# 使用 yarn 则是:yarn run start

这个命令其实执行了2个步骤:

  • 将TypeScript编写的程序构建转换成JavaScript程序,放到dist目录下
  • 通过Node.js执行dist目录下的main.js主程序

而对于我们发布程序的过程来说,只需要构建就可以了,并不需要运行。因此,我们只需要执行项目的构建命令:

代码语言:javascript
复制
npm run build
# 使用 yarn 则是:yarn run build

执行完成后,同样会构建出dist目录及目录下的程序文件。然后做个小实验,执行下面的命令:

代码语言:javascript
复制
node dist/main.js

是不是发现,它同样可以把我们的NestJS程序跑起来?其实,在通过构建后,dist目录下的文件就是一个单独可拿出去发布的东西了(其实还有package.json),把dist目录以及package.json复制到其他的电脑上,就可以把这个程序完整的运行起来(当然别忘了先通过npm或yarn安装依赖)。

介绍以上的内容,是为了让大家清楚的了解我们真正要发布的东西有哪些。我们要认识到,发布程序的时候,我们不可能把源代码都给到别人,让他们从源代码来运行我们的程序,这不仅不方便,也不太符合商业利益。

打包成镜像

下面,我们要真正开始用到Docker了!我们要为我们的项目中添加一些文件,让我们的项目具有容器化发布的能力。

先添加一个.dockerignore文件,内容如下:

代码语言:javascript
复制
node_modules
src
test

这个文件的作用,有点像Git的.gitignore文件。它是用来在Docker打包镜像复制文件的过程中,排除掉不需要复制的文件的。在这个文件中,排除了2部分的内容:

1.项目的源代码目录、测试代码目录

因为我们发布给别人的镜像里并不需要它们。

2. node_moudues依赖包目录

排除它,完全是为了避免操作系统不同的问题。试想一下,如果你本地开发机的操作系统是Windows的,你本地安装的node_modules目录中可能含有在安装时编译成跟当前操作系统密切关联的addons,这种addons在镜像操作系统中(一般都是Linux)没有办法运行,程序就会出错。所以,node_modules依赖包一定要在打包镜像的时候在镜像里面运行安装,才能保证依赖包是符合镜像所运行的操作系统的。

接着,要添加的文件是Dockerfile,Docker打包镜像的描述文件:

代码语言:javascript
复制
# 使用基于Alpine Linux制作的Node.js 12.13版本的基础镜像
FROM node:12.13-alpine

# 设置镜像的工作目录是 /app
WORKDIR /app

# 复制源代码目录内容到镜像的 /app 目录中去
#(会忽略掉.dockerignore中声明的内容)
COPY . /app

# 在镜像的工作目录下执行下列命令:
# 1. 设置yarn源为淘宝镜像源,加速依赖包下载
# 2. 执行yarn安装package.json中的项目依赖
RUN yarn config set registry http://registry.npm.taobao.org/ && \
    yarn

# 设置环境变量
ENV NODE_ENV=production

# 设置镜像启动后的容器对外暴露(外界可访问)的端口
EXPOSE 3000

# 镜像容器启动时执行的命令
# 即使用node来执行NestJS编译后的dist目录下的main.js
CMD ["node", "dist/main.js"]

有了上面的2个文件后,我们就可以开始打包镜像了。在我们的项目根目录下,执行:

代码语言:javascript
复制
docker build -t myserver:v1 .

命令行上一阵闪烁,打包结束!赶紧执行一段命令来确认一下打包后的镜像信息:

代码语言:javascript
复制
docker images

我们看到刚刚打包的名为myserver,版本标记为v1,大小为488MB的镜像。成功!

镜像有了,那我们怎么来运行这个镜像,它真的能跟我们预期的那样跑起来吗?快来试试下面的命令:

代码语言:javascript
复制
#以后台守护进程的方式,运行在3000端口
docker run -d -p 3000:3000 myserver:v1

执行完毕,那怎么来确认它真的已经跑起来了呢?docker ps 一下呗,如果你能在执行的结果列表里发现这个myserver:v1的镜像所产生的容器,则说明已经运行成功了:

代码语言:javascript
复制
docker ps

快去浏览器里打开 http://localhost:3000/ 看看那句既朴素又雅致,让人感到亲切又兴奋激动,好似来自远方的朋友的热情问候:Hello World!

发布镜像

前面打包完成的myserver:v1,已经是一个可以到处发布的镜像了。但是当前它还只是在你的电脑上呆着,怎么能让要使用它的其他人获取到这个镜像呢?这个就需要依靠镜像仓库了,就如我们的Dockerfile里那个 node:12.13-alpine 基础镜像,其实也是从远程的镜像仓库服务器上下载的,默认使用的是官方镜像仓库Docker Hub(https://hub.docker.com/)。我们可以在自己的服务器上安装docker registry,搭建一个自己的镜像仓库私服,保证企业内部授权用户才能访问。也可以使用一些第三方的云仓库,比如阿里云的容器镜像服务就挺好用的,上传下载速度也不错。

每个镜像仓库需要先登录才能使用,所以,请先在你使用的镜像仓库服务方获取必要的登录账号和密码等信息。然后登录:

代码语言:javascript
复制
docker login --username=your_account your_registry.domain.com

登录完成后,你就可以开始向仓库中上传镜像了:

代码语言:javascript
复制
#镜像设置别名,别名需要符合目标镜像仓库的规定
docker tag myserver:v1 registry.cn-shanghai.aliyuncs.com/moredist-test/myserver:v1

#上传镜像
docker push registry.cn-shanghai.aliyuncs.com/moredist-test/myserver:v1

成功执行后,本地的镜像就被上传到了镜像仓库服务器上去了。

至此,其他有权限访问该镜像仓库的人,就可以拉取你的程序镜像,并把镜像运行在任何安装了Docker的计算机上了。拉取镜像(未登录过的需要先登录):

代码语言:javascript
复制
docker pull registry.cn-shanghai.aliyuncs.com/moredist-test/myserver:v1

总结

我们花了一定的篇幅去介绍这种容器化的交付方式,并且乍一看还稍微有点工作量,但是这真的是一种非常值得你花点时间去学习的东西,这些投入,可以帮助你在以后的工作中有更高效、更优质的产出,如果借助于一些CI/CD工具(比如Jenkins、Gitlab等),可以为你和你的团队减少很多的重复劳动和出错的几率,让日常工作更轻松一些。同时,作为一个服务端开发人员,这些东西会让你产生更广阔的思考空间,得到更多的隐性能力提升。

加油吧,少年!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装Docker
  • 构建NestJS程序
  • 打包成镜像
  • 发布镜像
  • 总结
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档