目前工作中,虽然作为一名开发,但是平时也较多地负责产品在各个环境的部署与更新,随着时间的推移与迭代的频率增加,一套自动化集成部署流程的应用势在必行。不仅节约时间,也避免在大量繁琐操作中的人为错误,同时也为了方便管理数量比较多的模块。
目前产品主要用到的语言主要有java、c,由于web端做了前后端分离,前端的工程化也已经成型,js(主要用到vue)也算上吧。
经过一段时间的了解与实践,最终决定集成jenkins与gitlab实现自动部署。
本文安装方式均采用yum方式进行。
gitlab运行相关进程如下:
[root@gitlab ~]# gitlab-ctl status run: gitaly: (pid 690) 1031s; run: log: (pid 689) 1031s run: gitlab-monitor: (pid 686) 1031s; run: log: (pid 684) 1031s run: gitlab-workhorse: (pid 683) 1031s; run: log: (pid 681) 1031s run: logrotate: (pid 688) 1031s; run: log: (pid 687) 1031s run: nginx: (pid 685) 1031s; run: log: (pid 682) 1031s run: node-exporter: (pid 674) 1031s; run: log: (pid 673) 1031s run: postgres-exporter: (pid 691) 1031s; run: log: (pid 680) 1031s run: postgresql: (pid 669) 1031s; run: log: (pid 667) 1031s run: prometheus: (pid 679) 1031s; run: log: (pid 677) 1031s run: redis: (pid 666) 1031s; run: log: (pid 665) 1031s run: redis-exporter: (pid 671) 1031s; run: log: (pid 670) 1031s run: sidekiq: (pid 678) 1031s; run: log: (pid 668) 1031s run: unicorn: (pid 676) 1031s; run: log: (pid 675) 1031sgitlab的配置详见/etc/gitlab/gitlab.rb,配置修改之后需执行gitlab-ctl reconfigure使配置生效。
gitlab的日志存放路径在/var/log/gitlab/下。
gitlab-ctl tail #查看所有日志 gitlab-ctl tail nginx/gitlab_access.log #查看nginx访问日志Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台。这是一个免费的源代码,可以处理任何类型的构建或持续集成。集成Jenkins可以用于一些测试和部署技术。
注意,jenkins需要jdk支持。
yum install -y java-1.8.0-openjdk.x86_64安装jenkins
cd /etc/yum.repos.d/ wget http://pkg.jenkins.io/redhat/jenkins.repo rpm --import http://pkg.jenkins.io/redhat/jenkins.io.key yum install -y jenkins systemctl start jenkins注意:由于本文的gitlab和jenkins安装在一台机器上,jenkins的默认端口被gitlab占用了,因此将jenkins端口改为了7070。可在/etc/sysconfig/jenkins中进行配置。
新版本的jenkins启动时需要输入一个密钥,可以在第一次启动日志里面看到,也可以通过/var/lib/jenkins/secrets/initialAdminPassword进行查看。将密钥输入到解锁页面的输入框即可。
接下来的插件安装选择推荐的即可。
至此,jenkins安装完成。
先在jenkins上建立一个项目,选择”构建一个自由风格的软件项目”
在源码管理处选择Git,并填写相关信息。本文采用http的方式进行代码仓库的配置(也可以配置ssh方式,具体方式请自行google,额。。)
在构建触发器步骤选择”Build when a change is pushed to GitLab…”,表示在push代码到gitlab时触发构建。注意URL后面的地址等会儿在配置gitlab的webhook时用到。
在构建步骤选择执行shell,便可在触发事件执行时执行指定的shell脚本进行构建。
构建最核心的部分便在shell部分,这也是jenkins能在很多项目的构建中运用。因为之前的步骤全是一些通用的配置,针对不同的项目编写不同的部署脚本便可完成项目的自动构建于部署。本文采用的是vue项目做测试,在安装了nodejs的基础上,脚本内容如下(测试版本,细节请忽略-关键是shell脚本写的渣…)
注意: 在jenkins构建执行shell脚本时:单脚本时,若脚本中有exit 1(非0时)则整个构建失败,结果显示为红色;多脚本时,若其中任意一个脚本返回exist 1,则结果为警告,显示为黄色。
在/nick/ci/hxjpro/下准备了两个脚本:
[root@gitlab ~]# cd /nick/ci/hxjpro/ [root@gitlab hxjpro]# ls deploy.sh scp.exp其中deploy用于编译vue工程并打包(例子中没有以压缩包的方式进行传输,因为那样的话还需要远程执行命令,在实际使用中可以打包项目进行传输,然后执行远程命令。具体远程执行命令方式可参考linux expect使用),scp用于将文件传输到远程服务器。
deploy.sh内容
echo "start deploying ..." echo "------------------------------" echo "executing 'cnpm install'..." cnpm install echo "'cnpm install done!'" echo "------------------------------" echo "executing 'npm run build'..." npm run build echo "'npm run build' done!" echo "------------------------------" echo "packaging dist" tar -zcvf dist.tar.gz ./dist echo "package done!" echo "------------------------------" echo "sending dist to remote server : 192.168.0.106" ./scp.exp ./dist root@192.168.0.106:/nick/proj/hxjpro/ echo "send file to remote server done!" echo "------------------------------" echo "deploy finished!"scp.exp脚本内容
#!/usr/bin/expect set timeout 20 if { [llength $argv] < 2} { puts "Usage:" puts "$argv0 local_file remote_path" exit 1 } set local_file [lindex $argv 0] set remote_path [lindex $argv 1] set passwd nick123 set passwderror 0 spawn scp -r $local_file $remote_path expect { "*assword:*" { if { $passwderror == 1 } { puts "passwd is error" exit 2 } set timeout 1000 set passwderror 1 send "$passwd\r" exp_continue } "*es/no)?*" { send "yes\r" exp_continue } timeout { puts "connect is timeout" exit 3 } }以上便是jenkins的配置内容,关键是脚本的编写。
在真实项目中,项目的构建脚本一般比较复杂。比如java可以采用maven进行编译构建打包,或者ant进行构建打包。C可以采用对应的方式进行构建打包。而这些步骤均可整理成脚本,按以上方式进行配置即可。
为了方便,本文以一个前端(基于vue)工程为例子进行自动化构建部署实验。
gitlab与jenkins集成的原理主要通过gitlab的webhook实现,通过在gitlab上配置相关事件便可触发。
将工程提交到gitlab(可参考gitlab新建项目下的指导步骤)。然后在gitlab上进入工程详情页面,点击左边的Setting -> Integrations,将jenkins构建触发器配置的URL内容填写到URL输入框然后保存。
填完之后,点击”Test -> Push events”测试一下webhook地址,若返回200则表示配置成功!!!
特别注意:我在配置此步骤时花费了很多时间,因为gitlab和jenkins安装在同一台机器上,且gitlab版本较新,所以在测试url地址时老是报错,然后跟踪gitlab日志,发现
WARN: URI::InvalidURIError: URI::InvalidURIError ...最开始以为是配置问题,经过几遍的重复配置,发现没效果。然后经过不断google(吐血了…),终于发现这篇文章:Webhook does not work for me when i update to date!,大概意思就是说新版的gitlab在http模块部分有一个”允许本地请求”的判定,该配置默认是关闭的,需要通过配置打开。首先,用root账号登录gitlab,点击首页的”Configure GitLab”
找到左侧菜单底部的”Settings”,找到”Outbound requests”,勾选保存,OK!
(再次吐血…)
这时候,在回去点击webhook配置的”Test -> Push events”,如果提示403,可在jenkins的”系统管理->全局安全配置”,将”启用安全”配置去掉即可(内网暂时不考虑安全性问题,若有需求可自行google哈)。
配置完成之后,点击test应该返回200,此时去到jenkins的工程的构建列表,应该可以看到一个正在构建的任务,该任务正好就是test触发的。至此,gitlab配置ok了!!!
在本地的git项目提交代码并push到gitlab远程仓库,便可看到jenkins触发了构建任务进行自动构建,等构建完成,访问目标服务器的地址,便可看到最新的代码已经被自动部署到远程服务器,而我们需要做的仅需要commit和push代码。
最后贴一个jenkins的完整构建日志(有点长):
Started by GitLab push by nick 构建中 在工作空间 /var/lib/jenkins/workspace/hxjpro 中 [WS-CLEANUP] Deleting project workspace... [WS-CLEANUP] Done Cloning the remote Git repository Cloning repository http://gitlab.example.com/nick/hxjpro.git > git init /var/lib/jenkins/workspace/hxjpro # timeout=10 Fetching upstream changes from http://gitlab.example.com/nick/hxjpro.git > git --version # timeout=10 > git fetch --tags --progress http://gitlab.example.com/nick/hxjpro.git +refs/heads/*:refs/remotes/origin/* > git config remote.origin.url http://gitlab.example.com/nick/hxjpro.git # timeout=10 > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10 > git config remote.origin.url http://gitlab.example.com/nick/hxjpro.git # timeout=10 Fetching upstream changes from http://gitlab.example.com/nick/hxjpro.git > git fetch --tags --progress http://gitlab.example.com/nick/hxjpro.git +refs/heads/*:refs/remotes/origin/* skipping resolution of commit remotes/origin/master, since it originates from another repository > git rev-parse refs/remotes/origin/master^{commit} # timeout=10 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10 Checking out Revision 795f5f5d9868bea52800540f1786a07af5c6bab6 (refs/remotes/origin/master) > git config core.sparsecheckout # timeout=10 > git checkout -f 795f5f5d9868bea52800540f1786a07af5c6bab6 Commit message: "re-css" > git rev-list --no-walk fd9e89c6cadf44da5d5d76182be32aa877635f68 # timeout=10 [hxjpro] $ /bin/sh -xe /tmp/jenkins9132476457336492692.sh + cp /nick/ci/hxjpro/deploy.sh /nick/ci/hxjpro/scp.exp /var/lib/jenkins/workspace/hxjpro + sh /var/lib/jenkins/workspace/hxjpro/deploy.sh start deploying ... ------------------------------ executing 'cnpm install'... platform unsupported babel-loader@7.1.4 › webpack@3.11.0 › watchpack@1.6.0 › chokidar@2.0.3 › fsevents@^1.1.2 Package require os(darwin) not compatible with your platform(linux) [fsevents@^1.1.2] optional install error: Package require os(darwin) not compatible with your platform(linux) ✔ Installed 51 packages ✔ Linked 1022 latest versions /tmp/chromedriver is not writable: EACCES: permission denied, open '/tmp/chromedriver/1524928348389.tmp' Downloading https://tnpm-hz.oss-cn-hangzhou.aliyuncs.com/dist/chromedriver/2.38/chromedriver_linux64.zip Saving to /var/lib/jenkins/workspace/hxjpro/node_modules/_chromedriver@2.38.2@chromedriver/tmp/chromedriver/chromedriver_linux64.zip Received 781K... Received 1563K... Received 2345K... Received 3127K... Received 3684K total. Extracting zip contents Copying to target path /var/lib/jenkins/workspace/hxjpro/node_modules/_chromedriver@2.38.2@chromedriver/lib/chromedriver Fixing file permissions Done. ChromeDriver binary available at /var/lib/jenkins/workspace/hxjpro/node_modules/_chromedriver@2.38.2@chromedriver/lib/chromedriver/chromedriver ✔ Run 2 scripts deprecate cnpm@5.2.0 › urllib@2.27.0 › proxy-agent@2.3.1 › socks-proxy-agent@3.0.1 › socks@^1.1.10 If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0 Recently updated (since 2018-04-21): 26 packages (detail see file /var/lib/jenkins/workspace/hxjpro/node_modules/.recently_updates.txt) Today: → autoprefixer@7.2.6 › postcss@^6.0.17(6.0.22) (13:21:21) → autoprefixer@7.2.6 › caniuse-lite@^1.0.30000805(1.0.30000832) (12:01:06) → babel-loader@7.1.4 › webpack@3.11.0 › ajv-keywords@^3.1.0(3.2.0) (17:30:06) → babel-jest@21.2.0 › babel-plugin-istanbul@4.1.6 › test-exclude@4.2.1 › micromatch@3.1.10 › snapdragon@0.8.2 › source-map-resolve@0.5.1 › atob@^2.0.0(2.1.1) (01:34:11) → babel-loader@7.1.4 › webpack@3.11.0 › watchpack@1.6.0 › chokidar@2.0.3 › upath@^1.0.0(1.0.5) (01:59:11) → html-webpack-plugin@2.30.1 › toposort@^1.0.0(1.0.7) (20:32:28) → babel-loader@7.1.4 › webpack@3.11.0 › watchpack@1.6.0 › chokidar@2.0.3 › fsevents@^1.1.2(1.2.3) (01:30:08) → css-loader@0.28.11 › cssnano@3.10.0 › autoprefixer@6.7.7 › caniuse-db@^1.0.30000634(1.0.30000832) (11:17:54) ✔ All packages installed (1230 packages installed from npm registry, used 17s, speed 691.32kB/s, json 1073(9.22MB), tarball 2.28MB) 'cnpm install done!' ------------------------------ executing 'npm run build'... > hxjpro@1.0.0 build /var/lib/jenkins/workspace/hxjpro > node build/build.js Hash: [1m9343444ba098c99ce03d[39m[22m Version: webpack [1m3.11.0[39m[22m Time: [1m11949[39m[22mms [1mAsset[39m[22m [1mSize[39m[22m [1mChunks[39m[22m [1m[39m[22m [1m[39m[22m [1mChunk Names[39m[22m [1m[32mstatic/img/home_pic3.jpg[39m[22m 5.68 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner5.a083291.jpg[39m[22m 148 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner2.f99a28d.jpg[39m[22m 100 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner3.2092838.jpg[39m[22m 122 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33mstatic/img/loading-3.0982d06.gif[39m[22m [1m[33m309 kB[39m[22m [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m [1m[33mstatic/js/vendor.84375e9d5f718d36afbc.js[39m[22m [1m[33m681 kB[39m[22m [1m0[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m vendor [1m[32mstatic/js/app.8449664edde9547e1c00.js[39m[22m 55.5 kB [1m1[39m[22m [1m[32m[emitted][39m[22m app [1m[32mstatic/js/manifest.2ae2e69a05c33dfc65f8.js[39m[22m 857 bytes [1m2[39m[22m [1m[32m[emitted][39m[22m manifest [1m[32mstatic/css/app.1392ca036da408c1c7b02db97f245406.css[39m[22m 27.9 kB [1m1[39m[22m [1m[32m[emitted][39m[22m app [1m[32mstatic/css/app.1392ca036da408c1c7b02db97f245406.css.map[39m[22m 50.1 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/js/vendor.84375e9d5f718d36afbc.js.map[39m[22m 1.57 MB [1m0[39m[22m [1m[32m[emitted][39m[22m vendor [1m[32mstatic/js/app.8449664edde9547e1c00.js.map[39m[22m 166 kB [1m1[39m[22m [1m[32m[emitted][39m[22m app [1m[32mstatic/js/manifest.2ae2e69a05c33dfc65f8.js.map[39m[22m 4.97 kB [1m2[39m[22m [1m[32m[emitted][39m[22m manifest [1m[32mindex.html[39m[22m 578 bytes [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner2.jpg[39m[22m 100 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner3.jpg[39m[22m 122 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner5.jpg[39m[22m 148 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/home_pic2.jpg[39m[22m 7.25 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/social.ec45b2e.png[39m[22m 10.4 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/hxjLogo.png[39m[22m 1.67 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/loading-2.gif[39m[22m 4.29 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33mstatic/img/loading-3.gif[39m[22m [1m[33m309 kB[39m[22m [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m [1m[32mstatic/img/500418277_banner.jpg[39m[22m 110 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33mstatic/img/apple-apple-devices-clean-205316.jpg[39m[22m [1m[33m633 kB[39m[22m [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m [1m[33mstatic/img/banner1.jpg[39m[22m [1m[33m257 kB[39m[22m [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m [1m[32mstatic/img/banner4.jpg[39m[22m 123 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/banner6.jpg[39m[22m 124 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/favicon.ico[39m[22m 4.29 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/home_pic1.jpg[39m[22m 5.4 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/homeBanner.jpg[39m[22m 24.8 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33mstatic/img/loading-4.gif[39m[22m [1m[33m380 kB[39m[22m [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m [1m[32mstatic/img/loading.gif[39m[22m 7.25 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/newsbanner.jpg[39m[22m 82.2 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/photograph.jpg[39m[22m 30.5 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/post-1.jpg[39m[22m 144 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[32mstatic/img/post-2.jpg[39m[22m 85.4 kB [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33mstatic/img/banner1.jpeg[39m[22m [1m[33m3.36 MB[39m[22m [1m[39m[22m [1m[32m[emitted][39m[22m [1m[33m[big][39m[22m Build complete. Tip: built files are meant to be served over an HTTP server. Opening index.html over file:// won't work. 'npm run build' done! ------------------------------ packaging dist ./dist/ ./dist/index.html ./dist/static/ ./dist/static/img/ ./dist/static/img/banner5.a083291.jpg ./dist/static/img/social.ec45b2e.png ./dist/static/img/banner2.f99a28d.jpg ./dist/static/img/banner3.2092838.jpg ./dist/static/img/loading-3.0982d06.gif ./dist/static/img/banner2.jpg ./dist/static/img/banner3.jpg ./dist/static/img/banner5.jpg ./dist/static/img/home_pic2.jpg ./dist/static/img/home_pic3.jpg ./dist/static/img/hxjLogo.png ./dist/static/img/loading-2.gif ./dist/static/img/loading-3.gif ./dist/static/img/500418277_banner.jpg ./dist/static/img/apple-apple-devices-clean-205316.jpg ./dist/static/img/banner1.jpg ./dist/static/img/banner4.jpg ./dist/static/img/banner6.jpg ./dist/static/img/favicon.ico ./dist/static/img/home_pic1.jpg ./dist/static/img/homeBanner.jpg ./dist/static/img/loading-4.gif ./dist/static/img/loading.gif ./dist/static/img/newsbanner.jpg ./dist/static/img/photograph.jpg ./dist/static/img/post-1.jpg ./dist/static/img/post-2.jpg ./dist/static/img/banner1.jpeg ./dist/static/js/ ./dist/static/js/vendor.84375e9d5f718d36afbc.js ./dist/static/js/app.8449664edde9547e1c00.js ./dist/static/js/manifest.2ae2e69a05c33dfc65f8.js ./dist/static/js/vendor.84375e9d5f718d36afbc.js.map ./dist/static/js/app.8449664edde9547e1c00.js.map ./dist/static/js/manifest.2ae2e69a05c33dfc65f8.js.map ./dist/static/css/ ./dist/static/css/app.1392ca036da408c1c7b02db97f245406.css ./dist/static/css/app.1392ca036da408c1c7b02db97f245406.css.map package done! ------------------------------ sending dist to remote server : 192.168.0.106 spawn scp -r ./dist root@192.168.0.106:/nick/proj/hxjpro/ root@192.168.0.106's password: index.html 0% 0 0.0KB/s --:-- ETA index.html 100% 586 193.9KB/s 00:00 banner5.a083291.jpg 0% 0 0.0KB/s --:-- ETA banner5.a083291.jpg 100% 145KB 1.3MB/s 00:00 social.ec45b2e.png 0% 0 0.0KB/s --:-- ETA social.ec45b2e.png 100% 10KB 1.3MB/s 00:00 banner2.f99a28d.jpg 0% 0 0.0KB/s --:-- ETA banner2.f99a28d.jpg 100% 98KB 1.2MB/s 00:00 banner3.2092838.jpg 0% 0 0.0KB/s --:-- ETA banner3.2092838.jpg 100% 119KB 1.4MB/s 00:00 loading-3.0982d06.gif 0% 0 0.0KB/s --:-- ETA loading-3.0982d06.gif 100% 302KB 1.3MB/s 00:00 banner2.jpg 0% 0 0.0KB/s --:-- ETA banner2.jpg 100% 98KB 1.4MB/s 00:00 banner3.jpg 0% 0 0.0KB/s --:-- ETA banner3.jpg 100% 119KB 1.2MB/s 00:00 banner5.jpg 0% 0 0.0KB/s --:-- ETA banner5.jpg 100% 145KB 1.2MB/s 00:00 home_pic2.jpg 0% 0 0.0KB/s --:-- ETA home_pic2.jpg 100% 7250 314.3KB/s 00:00 home_pic3.jpg 0% 0 0.0KB/s --:-- ETA home_pic3.jpg 100% 5680 853.1KB/s 00:00 hxjLogo.png 0% 0 0.0KB/s --:-- ETA hxjLogo.png 100% 1672 229.0KB/s 00:00 loading-2.gif 0% 0 0.0KB/s --:-- ETA loading-2.gif 100% 4294 742.2KB/s 00:00 loading-3.gif 0% 0 0.0KB/s --:-- ETA loading-3.gif 100% 302KB 877.2KB/s 00:00 500418277_banner.jpg 0% 0 0.0KB/s --:-- ETA 500418277_banner.jpg 100% 107KB 945.1KB/s 00:00 apple-apple-devices-clean-205316.jpg 0% 0 0.0KB/s --:-- ETA apple-apple-devices-clean-205316.jpg 100% 618KB 744.1KB/s 00:00 banner1.jpg 0% 0 0.0KB/s --:-- ETA banner1.jpg 100% 251KB 1.0MB/s 00:00 banner4.jpg 0% 0 0.0KB/s --:-- ETA banner4.jpg 100% 120KB 1.0MB/s 00:00 banner6.jpg 0% 0 0.0KB/s --:-- ETA banner6.jpg 100% 121KB 645.9KB/s 00:00 favicon.ico 0% 0 0.0KB/s --:-- ETA favicon.ico 100% 4286 279.0KB/s 00:00 home_pic1.jpg 0% 0 0.0KB/s --:-- ETA home_pic1.jpg 100% 5404 467.4KB/s 00:00 homeBanner.jpg 0% 0 0.0KB/s --:-- ETA homeBanner.jpg 100% 24KB 669.4KB/s 00:00 loading-4.gif 0% 0 0.0KB/s --:-- ETA loading-4.gif 100% 371KB 737.0KB/s 00:00 loading.gif 0% 0 0.0KB/s --:-- ETA loading.gif 100% 7247 245.7KB/s 00:00 newsbanner.jpg 0% 0 0.0KB/s --:-- ETA newsbanner.jpg 100% 80KB 885.0KB/s 00:00 photograph.jpg 0% 0 0.0KB/s --:-- ETA photograph.jpg 100% 30KB 921.9KB/s 00:00 post-1.jpg 0% 0 0.0KB/s --:-- ETA post-1.jpg 100% 140KB 859.0KB/s 00:00 post-2.jpg 0% 0 0.0KB/s --:-- ETA post-2.jpg 100% 83KB 1.0MB/s 00:00 banner1.jpeg 0% 0 0.0KB/s --:-- ETA banner1.jpeg 100% 3282KB 3.2MB/s 00:01 banner1.jpeg 100% 3282KB 1.6MB/s 00:02 vendor.84375e9d5f718d36afbc.js 0% 0 0.0KB/s --:-- ETA vendor.84375e9d5f718d36afbc.js 100% 690KB 1.3MB/s 00:00 app.8449664edde9547e1c00.js 0% 0 0.0KB/s --:-- ETA app.8449664edde9547e1c00.js 100% 55KB 1.1MB/s 00:00 manifest.2ae2e69a05c33dfc65f8.js 0% 0 0.0KB/s --:-- ETA manifest.2ae2e69a05c33dfc65f8.js 100% 857 302.8KB/s 00:00 vendor.84375e9d5f718d36afbc.js.map 0% 0 0.0KB/s --:-- ETA vendor.84375e9d5f718d36afbc.js.map 100% 1562KB 1.5MB/s 00:01 app.8449664edde9547e1c00.js.map 0% 0 0.0KB/s --:-- ETA app.8449664edde9547e1c00.js.map 100% 164KB 1.3MB/s 00:00 manifest.2ae2e69a05c33dfc65f8.js.map 0% 0 0.0KB/s --:-- ETA manifest.2ae2e69a05c33dfc65f8.js.map 100% 4972 323.7KB/s 00:00 app.1392ca036da408c1c7b02db97f245406.css 0% 0 0.0KB/s --:-- ETA app.1392ca036da408c1c7b02db97f245406.css 100% 27KB 1.2MB/s 00:00 app.1392ca036da408c1c7b02db97f245406.css.map 0% 0 0.0KB/s --:-- ETA app.1392ca036da408c1c7b02db97f245406.css.map 100% 49KB 1.3MB/s 00:00 send file to remote server done! ------------------------------ deploy finished! Finished: SUCCESS参考文章 - CentOS服务器上搭建Gitlab安装步骤、中文汉化详细步骤、日常管理以及异常故障排查 - 持续集成之Jenkins+Gitlab简介 [一] - gitlab push代码通过webhooks自动触发jenkins构建设置
