博客 > 术业专攻> 自动化运维> Jenkins> Jenkins实战应用–Jenkins构建nodejs项目 2019年08月29日 11:26:47
文章汇总地址如右:Jenkins入门教程。
如果相中哪个,点击进去便是。希望正在读这段话的你能够在这个小系列中获得自信以及喜悦!
之前自己好像在一个项目的构建当中说过这样的话,“而如果是其他的诸如前端啊,PHP之类的项目,则就更简单了”,说出去之后好像这些项目的构建操作真的非常简单一般的,也就没有在对此进行任何表述。
但是有不少公司其实是纯web端服务的,这个时候构建前端项目则显得成为一个主要的事儿了,那么究竟该如何来构建一个完整前端项目呢?
今天我就借以nodejs项目举例,不仅仅把node项目完整配置流程讲清楚,更借此机会把如何利用git分支的办法进行项目的回滚之操作给表述一下,这次表述是一个引子,以后或许会专门写一篇关于回滚的文章吧。
首先说nodejs是一个跑起来的服务,需要一些依赖,而每个开发所定义的或者使用的命令之类的又不一样,因此在做nodejs的准备工作的时候就很有必要与开发者结合着来做。
接下来进入正题,我们先来在Jenkins上做一些配置,先把代码给搞到目标服务器去。
首先创建一个新的项目test-node。
进入到项目的配置里,添加两项参数。
字符参数定义发布代码的分支。
源码管理依旧使用git的地址。
在构建这里先简单写几条命令,让新鲜的代码推到远程服务器去。注意,这里所写的并不是最终脚本哦。因此也就不贴出来了。
然后执行一下构建先:
真的是超级简陋的,刚刚开始,什么都没有呢。
好了,现在去远程服务器上做一下环境的准备工作。
来波小小的操作。
cd /opt wget https://nodejs.org/dist/v6.10.1/node-v6.10.1-linux-x64.tar.xz #下载源码包 tar xf node-v6.10.1-linux-x64.tar.gz mv /opt/node-v6.10.1-linux-x64 /urs/local/node ln -s /usr/local/node/bin/* /usr/local/bin/ #做软链接让命令可用,也可以写入到/etc/profile里,如果写入配置,那么内容如下: export NODE_HOME=/usr/local/node export PATH=$NODE_HOME/bin:$PATH export NODE_PATH=$NODE_HOME/lib/node_modules:$PATH node -v #验证安装是否成功。
然后去到刚才同步过来的目录当中。也就是node项目的根目录中。
确保此时是在项目根目录下。
[root@localhost h5-node]# pwd /usr/local/h5-node
然后安装项目中的依赖。
[root@localhost h5-node]# npm install --registry=https://registry.npm.taobao.org
这一步的操作因为我也不十分明白其中意义,百度一下还真有雷同的问题:https://segmentfault.com/q/1010000012142031
其实上边这一步是安装好本项目所有的依赖。
因为我这里的项目开发者用的是gulp进行管理的。因此来安装一下gulp与pm2(每次看到这个词儿就想到开发大哥操着小口音说“嘎破”的样子)命令。
[root@localhost h5-node]# npm i -g gulp [root@localhost h5-node]# npm i -g pm2
其中i是install,-g表示全局安装的意思。这两条命令安装都比较慢,请耐心等待。
成功的样子如下边:
[root@localhost h5-node]# npm i pm2 -g
[ ..............] - fetchMetadata: sill mapToRegistry uri https://registry.npmjs.org/yamljs
npm ERR! fetch failed https://tgz.pm2.io/gkt-1.0.0.tgz
npm WARN retry will retry, error on last attempt: Error: connect ETIMEDOUT 163.172.101.189:443
npm ERR! fetch failed https://tgz.pm2.io/gkt-1.0.0.tgz
npm WARN retry will retry, error on last attempt: Error: connect ETIMEDOUT 163.172.101.189:443
npm ERR! fetch failed https://tgz.pm2.io/gkt-1.0.0.tgz
/usr/local/node/bin/pm2 -> /usr/local/node/lib/node_modules/pm2/bin/pm2
/usr/local/node/bin/pm2-dev -> /usr/local/node/lib/node_modules/pm2/bin/pm2-dev
/usr/local/node/bin/pm2-docker -> /usr/local/node/lib/node_modules/pm2/bin/pm2-docker
/usr/local/node/bin/pm2-runtime -> /usr/local/node/lib/node_modules/pm2/bin/pm2-runtime
/usr/local/node/lib
└─┬ pm2@2.10.4
├─┬ async@2.6.1
│ └── lodash@4.17.10
├── blessed@0.1.81
├─┬ chalk@1.1.3
│ ├── ansi-styles@2.2.1
│ ├── escape-string-regexp@1.0.5
│ ├─┬ has-ansi@2.0.0
│ │ └── ansi-regex@2.1.1
│ ├── strip-ansi@3.0.1
│ └── supports-color@2.0.0
├─┬ chokidar@2.0.3
│ ├─┬ anymatch@2.0.0
│ │ └─┬ micromatch@3.1.10
│ │ ├── arr-diff@4.0.0
│ │ ├─┬ define-property@2.0.2
│ │ │ └─┬ is-descriptor@1.0.2
│ │ │ ├── is-accessor-descriptor@1.0.0
│ │ │ └── is-data-descriptor@1.0.0
│ │ ├─┬ extend-shallow@3.0.2
│ │ │ ├── assign-symbols@1.0.0
│ │ │ └─┬ is-extendable@1.0.1
│ │ │ └── is-plain-object@2.0.4
│ │ ├─┬ extglob@2.0.4
│ │ │ ├─┬ define-property@1.0.0
│ │ │ │ └─┬ is-descriptor@1.0.2
│ │ │ │ ├── is-accessor-descriptor@1.0.0
│ │ │ │ └── is-data-descriptor@1.0.0
│ │ │ ├─┬ expand-brackets@2.1.4
│ │ │ │ ├── debug@2.6.9
│ │ │ │ ├── define-property@0.2.5
│ │ │ │ ├── extend-shallow@2.0.1
│ │ │ │ └── posix-character-classes@0.1.1
│ │ │ └── extend-shallow@2.0.1
│ │ ├── fragment-cache@0.2.1
│ │ ├── kind-of@6.0.2
│ │ ├─┬ nanomatch@1.2.9
│ │ │ ├─┬ is-odd@2.0.0
│ │ │ │ └── is-number@4.0.0
│ │ │ └── is-windows@1.0.2
│ │ ├── object.pick@1.3.0
│ │ └── regex-not@1.0.2
│ ├── async-each@1.0.1
│ ├─┬ braces@2.3.2
│ │ ├── arr-flatten@1.1.0
│ │ ├── array-unique@0.3.2
│ │ ├─┬ extend-shallow@2.0.1
│ │ │ └── is-extendable@0.1.1
│ │ ├─┬ fill-range@4.0.0
│ │ │ ├── extend-shallow@2.0.1
│ │ │ ├─┬ is-number@3.0.0
│ │ │ │ └─┬ kind-of@3.2.2
│ │ │ │ └── is-buffer@1.1.6
│ │ │ ├── repeat-string@1.6.1
│ │ │ └── to-regex-range@2.1.1
│ │ ├── isobject@3.0.1
│ │ ├── repeat-element@1.1.2
│ │ ├─┬ snapdragon@0.8.2
│ │ │ ├─┬ base@0.11.2
│ │ │ │ ├─┬ cache-base@1.0.1
│ │ │ │ │ ├─┬ collection-visit@1.0.0
│ │ │ │ │ │ ├── map-visit@1.0.0
│ │ │ │ │ │ └── object-visit@1.0.1
│ │ │ │ │ ├── get-value@2.0.6
│ │ │ │ │ ├─┬ has-value@1.0.0
│ │ │ │ │ │ └─┬ has-values@1.0.0
│ │ │ │ │ │ └── kind-of@4.0.0
│ │ │ │ │ ├─┬ set-value@2.0.0
│ │ │ │ │ │ └── extend-shallow@2.0.1
│ │ │ │ │ ├─┬ to-object-path@0.3.0
│ │ │ │ │ │ └── kind-of@3.2.2
│ │ │ │ │ ├─┬ union-value@1.0.0
│ │ │ │ │ │ └─┬ set-value@0.4.3
│ │ │ │ │ │ └── extend-shallow@2.0.1
│ │ │ │ │ └─┬ unset-value@1.0.0
│ │ │ │ │ └─┬ has-value@0.3.1
│ │ │ │ │ ├── has-values@0.1.4
│ │ │ │ │ └── isobject@2.1.0
│ │ │ │ ├─┬ class-utils@0.3.6
│ │ │ │ │ ├── arr-union@3.1.0
│ │ │ │ │ ├── define-property@0.2.5
│ │ │ │ │ └─┬ static-extend@0.1.2
│ │ │ │ │ ├── define-property@0.2.5
│ │ │ │ │ └─┬ object-copy@0.1.0
│ │ │ │ │ ├── copy-descriptor@0.1.1
│ │ │ │ │ ├── define-property@0.2.5
│ │ │ │ │ └── kind-of@3.2.2
│ │ │ │ ├── component-emitter@1.2.1
│ │ │ │ ├─┬ define-property@1.0.0
│ │ │ │ │ └─┬ is-descriptor@1.0.2
│ │ │ │ │ ├── is-accessor-descriptor@1.0.0
│ │ │ │ │ └── is-data-descriptor@1.0.0
│ │ │ │ ├─┬ mixin-deep@1.3.1
│ │ │ │ │ ├── for-in@1.0.2
│ │ │ │ │ └── is-extendable@1.0.1
│ │ │ │ └── pascalcase@0.1.1
│ │ │ ├── debug@2.6.9
│ │ │ ├─┬ define-property@0.2.5
│ │ │ │ └─┬ is-descriptor@0.1.6
│ │ │ │ ├─┬ is-accessor-descriptor@0.1.6
│ │ │ │ │ └── kind-of@3.2.2
│ │ │ │ ├─┬ is-data-descriptor@0.1.4
│ │ │ │ │ └── kind-of@3.2.2
│ │ │ │ └── kind-of@5.1.0
│ │ │ ├── extend-shallow@2.0.1
│ │ │ ├── map-cache@0.2.2
│ │ │ ├── source-map@0.5.7
│ │ │ ├─┬ source-map-resolve@0.5.2
│ │ │ │ ├── atob@2.1.1
│ │ │ │ ├── decode-uri-component@0.2.0
│ │ │ │ ├── resolve-url@0.2.1
│ │ │ │ ├── source-map-url@0.4.0
│ │ │ │ └── urix@0.1.0
│ │ │ └── use@3.1.0
│ │ ├─┬ snapdragon-node@2.1.1
│ │ │ ├─┬ define-property@1.0.0
│ │ │ │ └─┬ is-descriptor@1.0.2
│ │ │ │ ├── is-accessor-descriptor@1.0.0
│ │ │ │ └── is-data-descriptor@1.0.0
│ │ │ └─┬ snapdragon-util@3.0.1
│ │ │ └── kind-of@3.2.2
│ │ ├── split-string@3.1.0
│ │ └─┬ to-regex@3.0.2
│ │ └─┬ safe-regex@1.1.0
│ │ └── ret@0.1.15
│ ├─┬ glob-parent@3.1.0
│ │ ├── is-glob@3.1.0
│ │ └── path-dirname@1.0.2
│ ├── inherits@2.0.3
│ ├─┬ is-binary-path@1.0.1
│ │ └── binary-extensions@1.11.0
│ ├─┬ is-glob@4.0.0
│ │ └── is-extglob@2.1.1
│ ├─┬ normalize-path@2.1.1
│ │ └── remove-trailing-separator@1.1.0
│ ├── path-is-absolute@1.0.1
│ ├─┬ readdirp@2.1.0
│ │ ├── graceful-fs@4.1.11
│ │ ├─┬ minimatch@3.0.4
│ │ │ └─┬ brace-expansion@1.1.11
│ │ │ ├── balanced-match@1.0.0
│ │ │ └── concat-map@0.0.1
│ │ ├─┬ readable-stream@2.3.6
│ │ │ ├── core-util-is@1.0.2
│ │ │ ├── isarray@1.0.0
│ │ │ ├── process-nextick-args@2.0.0
│ │ │ ├── safe-buffer@5.1.2
│ │ │ ├── string_decoder@1.1.1
│ │ │ └── util-deprecate@1.0.2
│ │ └── set-immediate-shim@1.0.1
│ └── upath@1.1.0
├── cli-table-redemption@1.0.1
├── commander@2.13.0
├─┬ cron@1.3.0
│ └── moment-timezone@0.5.17
├─┬ debug@3.1.0
│ └── ms@2.0.0
├── eventemitter2@1.0.5
├── fclone@1.0.11
├─┬ mkdirp@0.5.1
│ └── minimist@0.0.8
├── moment@2.22.1
├─┬ needle@2.2.1
│ ├── debug@2.6.9
│ ├─┬ iconv-lite@0.4.23
│ │ └── safer-buffer@2.1.2
│ └── sax@1.2.4
├─┬ nssocket@0.6.0
│ ├── eventemitter2@0.4.14
│ └── lazy@1.0.11
├── pidusage@1.2.0
├─┬ pm2-axon@3.1.0
│ ├── amp@0.3.1
│ ├── amp-message@0.1.2
│ └── escape-regexp@0.0.1
├── pm2-axon-rpc@0.5.1
├─┬ pm2-deploy@0.3.9
│ ├── async@1.5.2
│ └── tv4@1.3.0
├─┬ pm2-multimeter@0.1.2
│ └── charm@0.1.2
├─┬ pmx@1.6.4
│ ├── deep-metrics@0.0.1
│ ├── json-stringify-safe@5.0.1
│ └─┬ vxx@1.2.2
│ ├─┬ continuation-local-storage@3.2.1
│ │ ├── async-listener@0.6.9
│ │ └── emitter-listener@1.1.1
│ ├── debug@2.6.9
│ ├── extend@3.0.1
│ ├── is@3.2.1
│ ├── lodash.findindex@4.6.0
│ ├── lodash.isequal@4.5.0
│ ├── lodash.merge@4.6.1
│ ├── methods@1.1.2
│ ├── shimmer@1.2.0
│ └── uuid@3.2.1
├─┬ promptly@2.2.0
│ └─┬ read@1.0.7
│ └── mute-stream@0.0.7
├── semver@5.5.0
├─┬ shelljs@0.7.8
│ ├─┬ glob@7.1.2
│ │ ├── fs.realpath@1.0.0
│ │ ├─┬ inflight@1.0.6
│ │ │ └── wrappy@1.0.2
│ │ └── once@1.4.0
│ ├── interpret@1.1.0
│ └─┬ rechoir@0.6.2
│ └─┬ resolve@1.7.1
│ └── path-parse@1.0.5
├─┬ source-map-support@0.5.6
│ ├── buffer-from@1.0.0
│ └── source-map@0.6.1
├── sprintf-js@1.1.1
├── v8-compile-cache@1.1.2
├─┬ vizion@0.2.13
│ └── async@1.5.2
└─┬ yamljs@0.3.0
└─┬ argparse@1.0.10
└── sprintf-js@1.0.3
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: gkt@https://tgz.pm2.io/gkt-1.0.0.tgz (node_modules/pm2/node_modules/gkt):
npm WARN network SKIPPING OPTIONAL DEPENDENCY: connect ETIMEDOUT 163.172.101.189:443
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.1.2 (node_modules/pm2/node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
此时基本上构建node项目的准备工作就已经完备了,但是此时有一个问题,那就是之前自己安装完上边两条命令之后就以为可以使用了,然后就在Jenkins上开始构建,发现总是会报错,说找不到这个命令,改成绝对路径执行就能执行了,后来明白了。
那么重新执行一下软链接命令就行了,或者是写入了/etc/profile中的话,记得在脚本当中及时使用source命令对环境进行加载。
ln -s /usr/local/node/bin/* /usr/local/bin/
现在就可以通过准备好了的环境,先在远程服务器上跑一下服务,如果本地可以跑起来,那么接下来的事儿就好办了。
用启动命令跑一下:
第一次启动会有如下输出:
[root@localhost h5-node]# npm run testEnv &
[1] 3854
> 51fanbei-web@0.0.0 testEnv /usr/local/h5-node
> pm2 start ecosystem.json --watch --env test
-------------
__/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____
_\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___
_\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__
_\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___
_\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____
_\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________
_\/\\\_____________\/\\\_____________\/\\\___/\\\/___________
_\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_
_\///______________\///______________\///__\///////////////__
Community Edition
Production Process Manager for Node.js applications
with a built-in Load Balancer.
Start and Daemonize any application:
$ pm2 start app.js
Load Balance 4 instances of api.js:
$ pm2 start api.js -i 4
Monitor in production:
$ pm2 monitor
Make pm2 auto-boot at server restart:
$ pm2 startup
To go further checkout:
http://pm2.io/
-------------
[PM2] Spawning PM2 daemon with pm2_home=/root/.pm2
[PM2] PM2 Successfully daemonized
[PM2][WARN] Applications 51web not running, starting...
[PM2] App [51web] launched (1 instances)
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ 51web │ 0 │ fork │ 3880 │ online │ 0 │ 0s │ 3% │ 13.1 MB │ root │ enabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
Use `pm2 show ` to get more details about an app
[1]+ 完成 npm run testEnv
好啦,起来啦,使用pm2 list可以看到服务此刻的状态。
那么,现在是时候完善一波脚本了。
首先是Jenkins项目配置处的脚本:此处的脚本任务非常简单,那就是调用一下服务器上的真实脚本,咱有事儿服务器上说,大概就是这么个意思。
内容也非常简单:
source /etc/profile && /bin/bash /usr/local/scripts/deploy.sh $mode $branch
现在来到Jenkins服务器本机完善重要的中转脚本,此脚本主要完成三件事儿:其一是将代码从Git仓库拉过来然后推送到远程服务器;其二就是依据选项参数中的变量内容来传递不同的操作内容;其三就是记录每次部署的git版本号,从而实现后来的回滚。
或许此时你可以根据我上边给出的思路,先尝试着思索一下这个脚本该怎么完成,我不希望你直接看了我的文章照搬照抄之后什么都没懂,这种废了功夫一无所获的情况,不是我想看到的。
因此,很反感翻页的我,要在这里设置一个翻页。
© 2018 www.qingketang.net 鄂ICP备18027844号-1
武汉快勤科技有限公司 13554402156 武汉市东湖新技术开发区关山二路特一号国际企业中心6幢4层7号
扫码关注,全站教程免费播放
订单金额:
支付金额:
支付方式: