gitlab-runner docker基于sftp实现项目CI/CD自动部署

最近在给单位组建了CI/CD,要求对开发人员git的代码进行build和deploy,第一次从头研究CI/CD,真的踩了不少坑,尤其是deploy部分,卡了我三天了。

起因

环境:

ubuntu物理机专门做CI/CD工具机,已经使用了docker-compose同时安装了gitlab和gitlab-runner

gitlab用于代码托管,gitlab-runner用于run gitlab-ci,实现自动编译,测试,部署一步到位

一台远程的WEB服务器,生产环境

问题:

由于gitlab-runner是在docker下跑的,而gitlab-runner使用的执行环境也是docker,这就导致一个问题,编译后的文件无法直接拷贝到物理机,docker是个完全隔离的沙盒,docker也会在结束CI/CD后立马销毁,好在在docker CI/CD任务没有完成前,我们是可以获得build的文件的。

如何把需要部署的文件,例如jar,bin包部署到服务器呢?我思考了很多种方案:

  • 使用scp复制到远程,失败:需要账号密码,gitlab-ci都不给你机会输入
  • 使用sshpass+scp,可以条过密码,但过程繁琐,而且还是出现了权限问题,没深入
  • 使用ftp,由于ftp这个老东西无论是被动模式还是主动模式对双方开放随机端口,我觉得不安全,放弃
  • 使用rsync,要同时配置服务端,客户端,真的很麻烦,都不想看
  • 最后决定使用sftp,利用了服务器自带的ssh用户(需要新建安全的用户,指定目录)
  • jekenis,这个很强大,也很重,需要较长学习周期,部署各种服务,但我方项目较小,暂不考虑,优先考虑轻量级的sftp

以上都是我参考了大量在线的文档,博客,最后总结了一套自己的docker下sftp deploy方法

这里用node下vue项目举例,比如build过后的vue项目会产生一个dist目录,我现在要把这个下面所有的文件都发布到web服务器上!

开始

首先,你需要先把runner添加到gitlab才能run呀,这个在上两篇docker-compose搭建gitlab的文章中讲述过,这里在提醒下:gilab打开项目,左边菜单栏,Settings-》CI/CD,下拉runner,找到url和token,通过gitlab-runner register注册进去,注册完,就可以看到新的runner显示绿色可用状态。
在这里插入图片描述
下一步,你需要写gitlab-ci.yml和deploy.sh,当然你也可以一并写到gitlab-ci.yml中。我分开了,因为我喜欢写shell!

我的.gitlab-ci.yml

stages:
    - build
    - deploy

cache:
    key:
        files:
            - package.json
    paths:
        - node_modules

build:
    stage: build
    before_script:
        - npm config set registry https://registry.npm.taobao.org
    script:
        - npm install
        - npm run build
    artifacts:
        expire_in: 1 day
        paths:
            - dist

deploy:
    stage: deploy
    image: ubuntu:20.04
    before_script:
        - rm /etc/apt/sources.list
        - echo 'deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse' >> /etc/apt/sources.list
        - echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse' >> /etc/apt/sources.list
        - echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse' >> /etc/apt/sources.list
        - mkdir ~/.ssh
        - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >~/.ssh/config
        - 'which lftp || ( apt-get update -y && apt-get install lftp -y )'
    script:
        - bash ./deploy.sh

关于gitlab-ci这个yml脚本,我必须特别说明下,里面有很多精华是我踩了很多的坑才写出来的。

下面是一篇官方文档:

Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD

重点在before_script里面:

  • 首先你需要更换ubuntu的apt源到国内,提高速度,否则CI/CD很慢!
  • 把npm也换到国内,否则也很慢!
  • 然后你需要关闭ssh验证,这个很繁,docker下的runner系统每次都会问(每次run都是一个新环境),但你无法输入yes,所以你必须关闭StrictHostKeyChecking,否则失败。在你本地一般不会报错,原因是你看看.ssh下的kownhosts阿!你已经允许过了!
  • 安装lftp,用这个工具上传到sftp!很方便!

deply.sh

#!/bin/bash
#指定对端FTP服务器的用户名和密码
USER="xxxx"
PASSWD="xxxx"
IP='xxx.xxx.xxx.xxxx'
P='22'
DIR='example.com'
targetDay=$(date -d "-1 days" +"%Y-%m-%d")

lftp -u $USER,$PASSWD sftp://$IP:$P <<EOM
    mirror -R dist $DIR
    bye
EOM

[ $? -eq 0 ] && echo "Upload SFTP server successful [$targetDay]"

这里这个deploy.sh其实是可以合并到yml里的,因为gitlab-ci.yml本来就是shell脚本的简化而以,用了gitlab-ci就不必要单独写shell,这里独立出来对我来说更加清晰,我解释下里面内容:

  • 首先定义连接sftp服务器的变量,用户名,密码阿之类的。这些以后要放到gitlab-runner的variables里更安全,不然提交git的人都知道部署生产服务器的账户密码了,在大公司里是绝对不可以的。
  • 关于上一条里的用户,肯定是不建议用root的,可以useradd新建一个用户,把www目录分配给他,我新建了一个deploy用户,最好再把网站deploy目录也chmod 777一下,不然还可能会有“permission denied”问题
  • lftp里面上传的是整个目录,要用mirror命令!注意不是put, 也不能用所谓的put -r,这都是坑阿,坑的我哭了。

一看job succeed,甚是激动,终于从坑里爬出来了。

在这里插入图片描述

posted @ 2020-12-24 21:13  devilyouwei  阅读(523)  评论(0编辑  收藏  举报