博客 > 术业专攻> 自动化运维> 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号
扫码关注,全站教程免费播放
订单金额:
支付金额:
支付方式: