[React 从零实践05-后台] Gitlab-CI使用Docker自动化部署

导航

[react] Hooks

[React 从零实践01-后台] 代码分割
[React 从零实践02-后台] 权限控制
[React 从零实践03-后台] 自定义hooks
[React 从零实践04-后台] docker-compose 部署react+egg+nginx+mysql
[React 从零实践05-后台] Gitlab-CI使用Docker自动化部署

[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程
[源码-vue03] watch 侦听属性 - 初始化和更新
[源码-vue04] Vue.set 和 vm.$set
[源码-vue05] Vue.extend

[源码-vue06] Vue.nextTick 和 vm.$nextTick

[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI

[深入01] 执行上下文
[深入02] 原型链
[深入03] 继承
[深入04] 事件循环
[深入05] 柯里化 偏函数 函数记忆
[深入06] 隐式转换 和 运算符
[深入07] 浏览器缓存机制(http缓存机制)
[深入08] 前端安全
[深入09] 深浅拷贝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模块化
[深入13] 观察者模式 发布订阅模式 双向数据绑定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手写Promise
[深入20] 手写函数
[深入21] 算法 - 查找和排序

(一) 前置知识

(1) 一些单词

appropriate:适合的
obtain:获得,赢得 // Obtain a token 获取token
section:切开,部分
specific:特有的,特殊的,特征
process:进程,处理
( Runner is active and can process any new jobs  -------活动的runner可以处理任何新的jobs)

cluster:集群
( You can easily install a Runner on a Kubernetes cluster. 你可以很方便的在k8s集群中安装runner )

manually:手工 adv
manual:手动的,说明书 adj/n
automatically:自动
deny:拒绝,否认 // adj => denied

structure:结构
determine:规定
( The .gitlab-ci.yml file defines the structure and order of the pipelines, and determine 定义结构和顺序,规定:)

feedback:反馈
commonly:通常,一般
( A simple pipeline commonly has three stages: 一个简单的pipeline通常有三个stage )

explain:解释
brief:短暂的,简单的
( let’s first explain in brief what this is all about 首先简单的解释下 )
certain:确定的 // a certain project 确定的项目
virtual machines:虚拟机
officially:官方的

ascend:升序
descend:降序
release:发布

General:常规的,大体的,通用的
( General pipelines:通用的pipeline )
( general seting:通用设置,常规设置 )

advanced:高级设置,高级选项

shallow:浅
( shallow clone 浅拷贝 )

pipeline:管道
stage:阶段
job:工作

stuck:卡住
( job is stuck, check runners // job卡住了 )

resume:继续
pause:暂停
schedule:时间表
parallel:并行,平行
above:上面的 // If anything of the above rings a bell 如果上面的情况都有的话
SSH key pair // ssh密钥对
stdin:标准输入 // Identity added: (stdin) ((stdin))

verify:验证
Make sure the private server’s SSH host keys are verified. // 确保专用服务器的SSH主机密钥已验证

inherit:继承 // Configuration entries that this job inherits from. 该作业继承的配置项
compress:压缩
general:总的

-----------------------------------------------分割线--------------------------------------------------------

general:常规的,大体的,通用的
integrations:集成
wiki:维基百科
metrics:指标
expire:失效,到期
verify:核实 // git commit --no-verify -m "jump"
advanced:高级的,高级选项
stable:稳定 // Keep stable branches secure 保持稳定分支的安全

owner:所有者
maintainer:维护者
developer:开发者
reporter:记者
guest:访客


-----------------------分割线 2021/06/15-----------------------
slug 偷懒

(2) linux 一些命令

(1)
ctrl + w  ------ 往回删除一个单词,光标放在末尾处
ctrl + i  ------ 清屏


(2)
scp
- scp命令用于复制文件和目录
- scp 是 secure copy 的缩写,表示安全拷贝
- 语法:
- scp [可选参数] file_source file_target 
  - scp -r file_source file_target 
  - -r 表示递归复制,r是recursive递归的缩写 ( recursive:递归 )

- 从本地拷贝到远程
scp local_file remote_ip:remote_folder
scp local_file remote_username@remote_ip:remote_folder  指定了用户名
表示从本地拷贝local_file文件到远程服务器的remote_folder文件夹中
( 重要:scp local_file remote_usename@remote_ip:remote_folder 这个命令将在.gitlab-ci.yml文件中用到 )


(3) rm -rf authorized_keys 
 // 问题:提示 rm: 无法删除"authorized_keys": 不允许的操作
 // 解决:
chattr -i authorized_keys
chattr -a authorized_keys
chattr -u authorized_keys
然后再删除:rm -rf authorized_keys
 

(4) > 和 >> 的区别
ls -l > 123.txt       // 表示将输出结果覆盖到123.txt
ls -l >> 123.txt      // 表示将输出结果追加到123.txt
区别:
>  会覆盖之前的内容
>> 是追加,不会覆盖
记忆:
>>比>多是追加,>少所以覆盖


(5)
&&:表示前一命令句执行成功时,才执行后一条命令
||:表示前一条命令执行失败时,才执行后一条命令
&:表示任务在后台执行
|:表示管道,上一条命令的输出,作为下一条命令的参数


(6) 
cat index.txt | tr "abc" "ABC"
// 上面的命令表示:把index.txt中的 "a" 换成 "A","b" 换成 "B","c" 换成 "C"
// 注意:不是把"abc"换成"ABC"
// 例如:123abcaaa => 123ABCAAA
// 分解:
//  | 表示前面命令的输出作为后面命令的参数

(3) sshpass 一个非交互的ssh工具

  • sshpass是一个简单的,轻量级的非交互的ssh命令行工具。
  • 安装:yum install -y sshpass (centos中使用)
  • 安装:apt-get install -y sshpass (ubuntu中使用)
  • 常用操作如下
1. 连接本地主机
sshpass -p xxxx ssh xxx@xxx
sshpass -p {密码} ssh {用户名}@{主机ip}

2. 连接远程主机
sshpass -p {密码} ssh -p {端口号} {用户名}@{主机ip}

3. 读取文件中的密码连接远程主机
sshpass -f {密码文本文件} ssh {用户名}@{主机IP} 

4. 从远程主机拷贝取目录到本地 !!!
sshpass -p {密码} scp {用户名}@{主机}:{远程目录} {本地目录或者文件}

5. 从本地拷贝到远程 !!!( 这个比较重要,因为我们要从docker中拷贝build文件夹到宿主机 )!!!
sshpass -p {密码} scp {本地目录} {用户名}@{主机}:{远程目录}

6. 连接远程主机并执行命令 !!!
sshpass -p {密码} ssh -o StrictHostKeyChecking=no {用户名}@{主机IP} 要执行的命令     
// -o StrictHostKeyChecking=no :忽略密码提示
// 如'rm -rf /tmp/test

(二) gitlab-CI

对比一下下面的文章

(1) gitlab CI/CD 介绍

  • gitlab提供的持续集成服务,在 ( commit ) 或者 ( push ) 时会自动触发 ( pipeline ),实现需要两样东西:
    • 在项目的根目录添加 ( .gitlab-ci.yml ) 文件
    • gitlab-runner
  • .gitlab-ci.yml
    • yml文件定义了 pipeline 的结构和顺序,并且规定如下:
    • 用gitlab-runner执行什么
    • 当遇到进程成功或者失败的特殊情况时,应该做什么
  • pipeline => stages => jobs
    • pipeline在 ( 项目 => CI/CI => pipeline中 )
    • pipiline一般情况包括三个stage => build test deploy

(2) ( pipeline ),( stages ),( jobs ) 三个概念

  • 概念
    • pipeline - 管道
    • stages - 阶段
    • jobs - 工作
  • 注意点
    • 可以设置以什么样的方式触发pipeline,比如commit或者MR
    • pipeline => stages
      • 一个 ( pipeline ) 可以包含多个 ( stage )
      • ( stage ) 依次顺序执行 ( 串行 )
      • 成功:所有 stage 成功完成,pipeline才会成功
      • 失败:一个stage失败后面的stage将不会执行
    • stages => jobs
      • 一个 ( stage ) 可以包含多个 ( job )
      • ( job ) 在一个stage中是并行执行的 ( 并行 )
      • 成功:所有 job 成功完成,stage 才会成功
      • 失败:一个job失败,则stage失败
+------------------+           +----------------+
|                  |  trigger  |                |
|   Commit / MR    +---------->+    Pipeline    |
|                  |           |                |
+------------------+           +----------------+

+--------------------------------------------------------+
|                                                        |
|  Pipeline                                              |
|                                                        |
|  +-----------+     +------------+      +------------+  |
|  |  Stage 1  |---->|   Stage 2  |----->|   Stage 3  |  |
|  +-----------+     +------------+      +------------+  |
|                                                        |
+--------------------------------------------------------+

+------------------------------------------+
|                                          |
|  Stage 1                                 |
|                                          |
|  +---------+  +---------+  +---------+   |
|  |  Job 1  |  |  Job 2  |  |  Job 3  |   |
|  +---------+  +---------+  +---------+   |
|                                          |
+------------------------------------------+

(三) gitlab-runner

(1) gitlab-runner 用来干嘛的?

  • runner主要是用来跑gitlab-ci.yml文件中定义的 ( jobs ) 的
  • runner可以是物理机,容器,集群等等
  • runner 和 gitlab 通过api进行通信,所以唯一的要求就是 runner的机器 能访问gitlab服务器( runner和服务器要分开部署 )
  • runner可以服务于确定的项目或者多个项目,甚至所有的项目,对于所有的姓名叫 shared runner
  • runner的类型
    • shared runners
      • 如果是使用 ( gitlab.com ) 而不是使用的自己的服务器安装的gitlab的话,可以使用shared runners
      • 对于公共项目和私有项目,对时长有不同的限制,私有只能跑2000分钟每个月
    • Specific Runners
      • 对于自己搭建的gitlab一般考虑使用自己的服务器安装特定的gitlab-runner

(2) gitlab-runner 如何才能工作?

  • 1.安装 gitlab-runner
  • 2.注册 gitlab-runnner 在项目或者组中

(3) gitlab-runner 有多少种安装方式?

  • 安装gitlab-runner
  • gitlab-runner可以安装在各种系统上,比如macos,windows,linux等等
  • ( 安装 ) 的方式一共有 ( 三种 ):
    • docker 方式安装
    • 下载二进制包
    • rpm包
  • ( 最方便 ) 的安装方式:使用 ( gitlab/gitlab-runnner ) 容器来安装

(4) 安装 - [Docker 安装 gitlab-runner]

  • 安装 - Dokcer安装gitlab-runner
  • 我们这里使用 Docker 方式安装 ( 强烈推荐,因为十分简单 )
  • 如何做到重启容器后,gitlab-runner所在的容器数据不丢失?
    • 1.使用本地数据卷
    • 2.使用数据卷容器
  • 具体安装过程
      1. 首先确保有 ( Docker环境 )
      1. docker pull gitlab/gitlab-runnner ( 拉取镜像 )
      1. 用下面的命令 ( 生成容器 ),生成gitla-runner容器后,就可以进行下一步注册流程了
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register

或者:下面的命令

// 后台方式生成容器,( 生成容器的目的 ) 主要是把容器中的 ( 配置映射到宿主机 ),然后 ( 注册gitlab-runner )
docker run -d --name gitlab-runner --restart always \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

(5) 注册 - [Docker 注册 gitlab-runner]

  • 注册 - Docker方式注册gitlab-runner
  • 第(4)步安装好gitlab-runner容器,获取到容器中的配置后,还需要进行注册 ( 注册新的runner, 注册后才能运行job )
  • 具体的注册过程
    • 1.新建用于 ( 注册的容器 )
      • 输入命令docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
      • 注意:第四步安装过程也生成了容器,那个容器主要是为了获取容器中runner的配置并映射到宿主机,获取的配置供注册使用
      • 其实:也可以直接使用第4步安装时生成的runner容器,只是数据卷不一样
    • 2.注册容器后,就会进入交互式命令注册gitlab-runner的流程,详细过程如下
注册流程

1. 生成注册用的docker容器
docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register

2. 运行上面步骤1的命令后,进入交互式注册命令过程,过程进入第3步

3. Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
   https://gitlab.com/

4. Please enter the gitlab-ci token for this runner
   jKKqXFTaMyBNNPwy-vFJ
   // 如何获取token => gitlab网站对应的项目/setting/CICD/Runners/Specific Runners中获取token

5. Please enter the gitlab-ci description for this runner
   7-react-admin-ts-runner

6. Please enter the gitlab-ci tags for this runner (comma separated)
   7-react-admin-ts-runner // tag

7. Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell
   docker // 1. 输入执行器,多数情况下都使用docker
   shell  // 2. 如何在deploy阶段,因为需要拷贝dist文件夹,则deploy的job可以使用shell来获取通过dependencies获取的artifacts

8. Please enter the Docker image (eg. ruby:2.6)
   node // 镜像,主要作用是如果在 ( .gitlab-ci.yml ) 文件中没有指定image,就会使用这里指定的image
   
输入完以上命令,会提示注册成功,同时在 => gitlab网站对应的项目/setting/CICD/Runners/Specific Runners中获取token中会显示刚刚注册的runner
image
image
image
image
image

(四) .gitlab-ci.yml

.gitlab-ci.yml 官方文档

(4.1) 常用关键字

关键字 描述
image 使用Docker镜像,下面两种都有效 <br /> image: name <br /> image: entrypoint
stages(数组) 定义pipeline中的stage,( 即定义构建阶段 ) 是一个数组 ------------------- 所有的stage
stage 一个job的流程,默认test --------------------------------------------------- 具体的stage
tags(数组) 通过标签管理或匹配runner,即该job用哪个runner去执行 <br /> tags在注册runner时需要指定 <br /> tages是一个数组,因为job可以指定多个runner <br /> 一般带s的是一个数组
script(数组) runner执行的shell脚本
artifacts 作用:主要用来不同的stage之间传递数据,arfifaces制品可以在gitlab-ui上下载 <br /> 应用:通用的做法是将 build 阶段打包出来的文件定义为 artifacts,这样在 deploy 阶段就可以直接使用了 <br /> expire_in: artifacets 的过期时间,因为这些数据都是保存在 Gitlab 机器上的,过于久远的资源就可以删除掉了 <br /> paths(数组):从什么地方获取artifaces,路径是相对于项目目录($ CI_PROJECT_DIR)的,不能直接在其外部链接。 可以使用遵循通配符模式和filepath.Match的通配符。 <br /> name:arfifacts制品的名字 <br /> when: 比如 when: in_success 在job成功时获取arfifacts
dependencies <br /> (数组) 作用: 获取artifacts制品,需要提供job的名称,即获取哪个job的artifacts <br /> 注意点: 只能获取该job之前的job的artifacts,如果artifacts过期,则dependencies会失败 <br />
cache 作用:缓存,加快构建的速度,在后续运行之间应缓存的文件列表 <br /> 注意点:全局的缓存,可供所有job使用 <br />作用和artifacts相似 <br /> 可用:cache:paths,cache:key,cache:untracked和cache:policy。
paths(数组):需要缓存的目录<br /> key:独一无二的缓存,解决缓存被覆盖的问题
only(数组) 指定当前 job 适用的 git (分支、Tag) 列表 ----------- 分支,变量,change等
except(数组) 除了git的哪些分支,其他都使用该job --------------- 分支,变量,change等
rules(数组) rules会逐渐代替only和except <br /> 具体规则如下:<br /> if:表示条件成立,就会触发该job<br /> changes:表示文件被修改后,就会触发该job<br /> exists:表示文件存在,就会触发该job<br />
variables 定义变量,要使用变量时通过 ${变量名} 获取变量
allow_failure 允许 job 失败, 失败的job不会影响commit的状态,也不会影响下一个job
when when有以下值:<br /> on_success:当之前的所有job ( 都成功 ) 才会执行的job <br /> on_failure:当之前的所有job ( 都失败 ) 才会执行的job <br /> always:无论之前的job是成功还是失败,都会执行的job <br /> manual:需要手动执行的job <br /> delayed:需要延迟执行的job <br /> never:不执行job或者pipeline <br />
before_script <br />(数组) 在 job 开始之前运行的脚本
retry 指定在 job 失败后,再执行的次数,eg:retry:2 表示失败后再执行两次,如果都失败,一共执行三次
parallel 设置 job 并行运行的数量,注意是某一个job并行运行的次数 <br /> 区分: <br /> 1. 在同一个stage中的所有job是并行运行的 <br /> 2. parallel指定的是同一个job并行运行的次数
extends 该job继承的别的job的配置项,相同的被覆盖,不同的被继承 <br /> 注意:被继承的job一般以 . 号开头

(4.2) 常用内置变量

  • 常见的一些内置变量
  • 内置变量 - 文档
  • 内置变量 - 文档2
  • 参考教程
    |关键字|描述|
    |--|--|
    CI_PROJECT_NAME|当前正在构建的项目名称
    CI_BUILD_REF_NAME => CI_COMMIT_REF_NAME|用于构建项目的分支或tag名称
    CI_BUILD_REF_SLUG => CI_COMMIT_REF_SLUG|先将$CI_COMMIT_REF_NAME的值转换成小写,最大不能超过63个字节,然后把除了0-9和a-z的其他字符转换成-。在URLs和域名名称中使用

    slug:是偷懒的意思,表示全小写偷懒写法
    CI_BUILD_REF => CI_COMMIT_SHA| commit的版本号
    CI_COMMIT_TAG| commit的tag名称,只有创建了tags才会出现
    CI_JOB_NAME| .gitlab-ci.yml中定义的job的名称
    CI_JOB_STAGE| .gitlab-ci.yml中定义的stage的名称
    CI_COMMIT_BRANCH|提交分支名称,可用于分支管道,包括默认分支的管道。 不适用于合并请求管道或标签管道

(4.3) ci-lint 做 gitlab-ci.yml 语法检测

  • CI/CD > Pipelines or CI/CD > Jobs in your project and click CI lint

(五) SSH-keys

(1) 为什么要使用SSH keys?

我们这里要学习SSH keys的主要原因是

1. 当您的CI / CD作业在Docker容器中运行(意味着环境已包含在内)并且您想要在私有服务器中部署代码时,您需要一种访问它的方法。 这是SSH密钥对派上用场的地方。

2. 把gitlab-runner容器环境打包的dist文件夹传递到宿主机,当然也可以直接新建nginx环境的runner环境,我这里是因为之前已经在在别的docker配置好了nginx

  • 如果你想将runner中的dist文件夹,部署到自己的服务器,需要用ssh实现免密登陆
  • 如果你想执行从 ( 构建环境 ) 到 ( 远程服务器 ) 的SSH
  • 如果你想将文件从 ( 构建环境 ) 同步到 ( 远程服务器 )

(2) 通过 .gitlab-ci.yml 文件注入SSH-keys的详细步骤 ( 注意:下面是 Docker 环境的步骤 )

SSH keys when using the Docker executor

  • 1.通过 ( ssh-keygen ) 在本地生成密钥对 ( ssh-keys ) ( 服务器或者本地生成ssh-keys )
    • ssh-keygen -t rsa -b 2048 -C "email@example.com""
    • 上面的命令会生成 .ssh文件夹, 里面就有 id_rsaid_rsa.pub 等文件
    • 然后把服务器上生成的ssh-keys的id_rsa.pub添加到项目所在的gitlab账户中
  • 2.把第一步生成的 ( 私钥id_rsa ) 添加到项目的 ( variables ) 中
    • key: SSH_PRIVATE_KEY
    • value: id_rsa
    • Settings/CICD/Variables中设置变量即可
  • 3.通过ssh-agent命名在job中加载私钥
    • 在 .gitlab-ci.yml 的 before_script 添加以下相关命令
    • 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
    • eval $(ssh-agent -s)
    • echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    • mkdir -p ~/.ssh
    • chmod 700 ~/.ssh
  • 4.确保私有服务器的SSH主机密钥经过验证
    • SSH host keys are verified官网文档
    • 1.在服务器中输入 ssh-keyscan 服务器地址
    • 2.添加新的变量
      • key: SSH_KNOWN_HOSTS
      • value: 就是1步骤输出的值
      1. 在 .gitlab-ci.yml 的 before_script 数组中添加
      • echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
      • chmod 644 ~/.ssh/known_hosts
  • 5.最后一步,将第一步中创建的公钥添加到要从构建环境中访问的服务中
    • 注意:如果是私有仓库的话需要配置 Deploy keys
    • deploy key官网说明
    • 如何启用 deploy key
      • 1.在项目中打开 Settings > Repository
      • 2.展开 Deploy Keys
      • 3.指定title,和公共密钥
      • 4.勾选是否具有可写权限
      • 5.当添加时,可能报错
        • Fingerprint has already been taken, Deploy keys projects deploy key fingerprint has already been taken
        • 粘贴格式的问题,直接复制到vscode中,一行就不会报错了


          image

(六) 【public仓库项目】实现gitlab-ci流程

(1) .gitlab-ci.yml具体配置如下,亲测成功

image: node

variables:
  PROJECT_NAME: "7-react-admin-ts"

stages:
  - environment
  - build
  - deploy

environment-stage-name-job:
  stage: environment
  image: node
  tags:
    - 7-react-ci
  script:
    - echo "gitlab-ci start"
    - echo ${PROJECT_NAME}
  allow_failure: true
  parallel: 2

environment-stage-env-job:
  stage: environment
  image: node
  tags:
    - 7-react-ci
  script:
    - echo ${CI_COMMIT_SHA}
    - echo ${CI_PROJECT_NAME}
    - echo ${CI_PROJECT_NAMESPACE}
    - echo ${CI_PROJECT_PATH}
    - echo ${CI_PROJECT_URL}
    - echo ${GITLAB_USER_NAME}
    - echo ${GITLAB_USER_EMAIL}
    - echo ${CI_PROJECT_DIR}
    - echo ${CI_PIPELINE_ID}
    - echo ${CI_COMMIT_REF_NAME}
  allow_failure: true

build-stage-job:
  stage: build
  image: node
  tags:
    - 7-react-ci
  only:
    - master
  script:
    - echo "build job start"
    - apt-get install -y git
    - npm install -g cnpm --registry=https://registry.npm.taobao.org
    - git --version
    - cnpm -v
    - npm -v
    - node -v
    - ls
    - rm -rf ${PROJECT_DIR}
    - git clone ${REMOTE_PROJECT_URL}
    - cd ${PROJECT_DIR}
    - cnpm install
    - cnpm run build
    - ls
  allow_failure: false
  retry: 2
  artifacts:
    name: "build_dist"
    paths: 
      - ${BUILD_DIR}
    when: on_success
    expire_in: 7 week

deploy-stage-job:
  # extends: .deploy-stage-job 继承
  stage: deploy
  image: node
  tags:
    - 7-react-ci
  only: 
    - master
  dependencies:
    - build-stage-job
  before_script:
    - echo "deploy job start"
    - ls
    - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    - echo "deploy start"
    - ls
    - apt-get update
    - apt-get install -y sshpass
    - sshpass -p ${PASSWORD} scp -r ${BUILD_DIR} root@49.233.215.163:build_dir
  allow_failure: false
  retry: 2
  when: on_success
image
image
image
image
image

(2) 将gitlab-ci中获取到的build文件夹,部署到docker nginx 容器中

经过 一到六步 后,已经可以自动在master改变后,自动获取打包后的文件夹,还差最后一步部署,将build文件夹部署到 nginx 容器中,使用数据卷映射实现实时更新和数据持久化,就可以访问了

(1) docker pull nginx
(2) docker run -it --name=nginx_ci \
    -p 7777:81 \
    -v /root/build_dir/build:/usr/share/nginx/html \
    -v /root/deploy-ci-test/conf.d:/etc/nginx/conf.d \
    nginx

说明:
(1)/root/build_dir/build   中放的是前端打包后的文件
(2)/root/gitlab-ci-test/conf.d 中放的时 nginx 配置文件 default.conf 文件
(3)default.conf如下
server {
    listen 81;
    server_name localhost;
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/  /index.html;
    }
    
    location /api {
        proxy_pass  http://49.233.215.163:7001;
    }
}

(3) 遇到的坑

  • 使用公共仓库时,git clone 的方式选择 https 方式
  • 每个job的环境是不共享的,比如你在job1中安装了git,在job2中是没有的
  • 公共项目的ci部署和私有项目的ci部署是不一样的
  • 在react中使用了代码分割和style-component后,在本地会有warning的chunk警告,而在ci中就会报错,需要把CI变量修改成false

项目源码

资料

配合我以前的gitlab-ci学习笔记 https://juejin.im/post/6844904103944912904#heading-0
远程服务器安装gitlab https://juejin.im/post/6844903826248433677
同一个pipeline中不同stage之间的数据传递 https://blog.csdn.net/textdemo123/article/details/94432961
如何设置gitlab-ci的deploy keys https://newsn.net/say/git-pull-no-password.html
gitlab-ci中的环境变量文章 https://juejin.im/post/6844903608731828232#heading-0
linux中的&&和&,|和|| https://blog.csdn.net/chinabestchina/article/details/72686002

https://www.joelled.com/yuncourse/190.html
https://blog.csdn.net/cindy647/article/details/108536703
https://blog.csdn.net/cuandeqin2083/article/details/94129642
https://github.com/facebook/create-react-app/issues/5372

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容