基于 Docker 快速搭建 Gitlab 与 Gitlab CI/CD 服务
此文档基于现有项目运行实践整理, 其中包含了许多 GitlabCI/CD 相关概念, 阅读需要有一定的 GitlabDockerCI/CD 基础知识
[TOC]
此项目能做什么
分享一些关于团队 Git 版本控制使用心得
提供一份 Docker 版本的 Gtilab 私有化仓库应用实现, 让你在开发团队内部快速构建一套 Git 托管仓库系统
提供一份 Gitlab Docker 容器编排实现参考, 分离 Gitlab/Redis/PostgreSQL/Gitlab-CI 和运行时数据
提供一份 Gitlab Runner Docker 版本实现, 在 Runner 容器内部增加了对 PHP 的支持, 利用 Laravel Envoy 实现远程操作多台主机, 实现分布式自动构建与交付
加深对软件从编码 = 构建 = 测试 = 部署的整个生命周期的认知,
为 web/Web API 类型互联网产品自动化提供参考, 适合中小型创业研发团队快速迭代版本
Git Flow / Github Flow /Gitlab Flow Git 工作流
Git 团队开发中, 大家都在向仓库中提交功能代码, 时间久了, 分支与版本就逐渐增多而变得复杂, 因此, 一个合理的版本管理流程在项目初期就非常重要
使用 Git, 多数时候推荐流行的 git-flow 工作流程 git-flow 备忘清单 通常, develop 分支作为测试版本使用, 所有开发者都能够向该分支合并代码, 以保证代码经过评审和功能验证 master 分支作为线上版本使用, 只有仓库管理员才能向该分支合并代码, 以确保线上版本稳定
feature branches 功能特性分支, 基于 develop 分支开发, 在功能开发完成后, 代码会被合并到 develop 分支, 此分支也自动删除
develop 测试分支, 一般基于该分支构建应用的测试环境
release branches 发布分支新功能开发完成, 经过了代码评审和功能验证后, 仓库管理员使用
git flow release start 1.0.0
命令方式合并 develop 分支到 master 分支使用该命令, 需要确保 master 分支与 develop 分支基础版本一致
hotfixes 修复分支, 一般而言, 在线上环境出现问题, 需要紧急修复时, 需创建 hotfix 修复补丁分支, 它基于 master 分支开发, 补丁修复代码会被合并至 master 与 develop 分支
master 生产分支, 一般基于该分支中构建应用的生产环境
在单人 Git 开发场景下, 此流程足以满足需求, 但是在多人的开发团队中, 有时候稍显 "无力", 而 Gitlab/Github 推荐使用 PR/MR 的方式, 开发者需要主动发起分支合并申请, 在得到确认后, 分支开发才算完成
开发者基于主干分支先创建新的功能性分支, 在功能开发完成后, 需要作 Merge Request 申请, 也即是主动请求合并功能分支代码到主干分支仓库管理员会评审每一次 MR, 只有评审通过, 新功能才被提交上线
快速运行 Gitlab
Gitlab 提供社区与企业版本, 官网 提供多种 Gitlab 安装方式此项目是基于 Docker 版本的 Gitlab 实现, 开发者无需更多关心 Gitlab 安装过程, Docker 镜像已做好了环境和依赖, 只需要一台 * Unix 机器, 并安装 Docker, 可以放心安装和卸载
该项目基于 Docker GitLab 镜像构建, 它将 Gitlab/PostgreSQL/Redis 容器进行了分离, 更友好的理解其运行依赖, 组织结构等内容, 提供一套容器编排配置参考, 支持 Docker Compose 快速构建与维护
运行以下命令, 确保你的主机已经安装好了 Docker 与 Docke-Compose
克隆仓库
- $ git clone https://github.com/bravist/gitlab-docker
- $ cd ~/gitlab-docker
配置环境变量, 推荐使用默认配置
$ cp .env.example .env
使用 docker-compose 自动构建镜像和启动容器
$ docker-compose build && docker-compose up -d
查看容器并访问 Gitlab Web 控制台
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 8827363f45d8 sameersbn/gitlab:10.3.3 "/sbin/entrypoint.sh" 4 seconds ago Up 4 seconds 443/tcp, 0.0.0.0:10022->22/tcp, 0.0.0.0:10080->80/tcp gitlabdocker_gitlab_1
- db0dd3b3d23f bravist/gitlab-ci-php-envoy:1.0 "/usr/bin/dumb-init" 7 seconds ago Up 6 seconds gitlab-ci-php-envoy-runner
- f598844c561c sameersbn/redis:latest "/sbin/entrypoint.sh" 7 seconds ago Up 6 seconds 6379/tcp gitlab-redis
- 73d93b7cd110 sameersbn/postgresql:9.6-2 "/sbin/entrypoint.sh" 7 seconds ago Up 5 seconds 0.0.0.0:5432->5432/tcp gitlab-postgresql
使用浏览器访问: http://localhost:10080/ 默认会启动一台 Gitlab Runner 容器, 支持快速配置你的 CI/CD
![Sign in . GitLab](Sign in . GitLab.png)
持续集成 / 持续交互(CI/CD)
CI/CD 的全称是 Continuous Integration & Deployment (持续集成 / 部署), 是 extreme programming (极限编程) 的一部分我们常用 CI 来做一些自动化工作, 这种自动化工作会运行在一台集中的机器上, 比如程序的打包, 单元测试, 部署等 维基百科 - 持续集成
Gitlab 从 8.* 版本后支持 CI/CD, 要使用 CI/CD, 先理解一些概念
Pipeline
一次 Pipeline 就是一次完整的构建任务, 里面可以包含多个阶段( stages )
Stage
Stages 表示任务构建的阶段一次 Pipeline 中允许定义多个 Stages, 这些 Stages 会有以下特点:
所有 Stages 会按照顺序运行, 即当一个 Stage 完成后, 下一个 Stage 才会开始
只有当所有 Stages 完成后, 该构建任务 (Pipeline) 才会成功
如果任何一个 Stage 失败, 那么后面的 Stages 不会执行, 该构建任务 (Pipeline) 失败
Job
Jobs 表示构建工作, 表示某个 Stage 里面执行的工作 我们可以在 Stages 里面定义多个 Jobs, 这些 Jobs 会有以下特点:
相同 Stage 中的 Jobs 会并行执行
相同 Stage 中的 Jobs 都执行成功时, 该 Stage 才会成功
如果任何一个 Job 失败, 那么该 Stage 失败, 即该构建任务 (Pipeline) 失败
我把 Pipelines 理解为流水线, 流水线包含有多个阶段( stages ), 每个阶段包含有一个或多个工序( jobs ), 比如先购料组装测试包装再上线销售, 每一次 Push 或者 MR 都要经过流水线之后才可以合格出厂
Gilab 中, 仓库的. gitlab.ci.yml 文件负责定义项目具体工作任务和流水线, Gitlab Runner 基于配置好的流水线逐步执行任务, 直到任务完成, 如果中途错误, 它会立即停止后续的任务如果项目使用 Gitlab CI, 需要提前添加该文件
- stages:
- - pull_code_test
- - pull_code_production
- - install_deps
- - test
- - build
- - deploy_test
- - deploy_production
- variables:
- PHP_FPM_CONTAINER: lnmp-php-fpm
- WORK_DIR: /usr/share/nginx/html/
- PROJECT: laravel-demo
- GIT_DIR: /mnt/lnmp-docker
- # 拉取代码
- pull_code_test:
- stage: pull_code_test
- only:
- - develop
- script:
- - cd ${GIT_DIR}/${PROJECT}
- - git pull origin develop
- pull_code_production:
- stage: pull_code_production
- only:
- - master
- script:
- - cd ${GIT_DIR}/${PROJECT}
- - git pull origin master
- # 安装依赖
- install_deps:
- stage: install_deps
- script:
- - docker exec -w ${WORK_DIR}/${PROJECT} ${PHP_FPM_CONTAINER} composer install
- build:
- stage: build
- script:
- # Run migrations
- - docker exec -w ${WORK_DIR}/${PROJECT} ${PHP_FPM_CONTAINER} php artisan migrate
- # Cache clearing
- - docker exec -w ${WORK_DIR}/${PROJECT} ${PHP_FPM_CONTAINER} php artisan cache:clear
- # Create a cache file for faster configuration loading
- - docker exec -w ${WORK_DIR}/${PROJECT} ${PHP_FPM_CONTAINER} php artisan config:cache
- # Create a route cache file for faster route registration
- - docker exec -w ${WORK_DIR}/${PROJECT} ${PHP_FPM_CONTAINER} php artisan route:clear
- deploy_test:
- stage: deploy_test
- script:
- - cd ${GIT_DIR}
- - docker-compose down && docker-compose build && docker-compose up -d
- deploy_production:
- stage: deploy_production
- script:
- - cd ${GIT_DIR}
- - docker-compose restart
Gitlab Runner - 自动构建与部署的执行
GitLab Runner 是一个开源项目, 它用来运行你定制的任务 (jobs) 并把结果返回给 GitLab GitLab Runner 配合 GitLab CI (GitLab 内置的持续集成服务) 协调完成任务 GitLab Runner
简单的说, Gitlab Runner 是独立运行配置好了 Gitlab CI/CD 项目的机器, 它负责 Gitlab 项目的自动构建和部署的运行
Gitlab Runner 安装有多种方式, 具体可以参考 官方文档 , 这里推荐使用基于 Docker 的版本 bravist/gitlab-ci-php-envoy , 镜像源码已同步在此项目中, 上面的章节也能看到运行的容器
Gitlab Runner 安装运行之后, 需要 注册到 Gitlab 项目中去 , 才能使用其功效
1. 获取注册参数
登录 Gitlab 控制台, 选择一个 Gitlab 仓库, 进入 Settings =CI / CD =Runners settings =Expand, 获取 Runners 相关参数
2. 为项目注册一个 Shell 类型的 Gitlab Runner
- $ docker exec -it gitlab-ci-php-envoy-runner gitlab-ci-multi-runner register
- Running in system-mode.
- # 输入 CI URL
- Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
- http://gitlab.weipeiapp.com:10080/
- # 输入 CI Token
- Please enter the gitlab-ci token for this runner:
- eU9zcqjReSozw6a1RLL8
- # 输入描述信息
- Please enter the gitlab-ci description for this runner:
- [f6c7de92c743]: Gitlab CI usage
- # 输入标签信息
- Please enter the gitlab-ci tags for this runner (comma separated):
- v1.0
- # 是否运行未标记的版本
- Whether to run untagged builds [true/false]:
- [false]: true
- # 是否运行当前项目
- Whether to lock the Runner to current project [true/false]:
- [true]: true
- Registering runner... succeeded runner=eU9zcqjR
- # 输入 Runner 的类型
- Please enter the executor: shell, virtualbox, docker-ssh+machine, kubernetes, docker, docker-ssh, parallels, ssh, docker+machine:
- shell
- Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
注册成功后, 页面会多出一个正在运行的 Runner 绿色标志
Gitlab CI/CD 运行流程
如果你了解 bravist/lnmp-docker , 对于下面的图不会陌生, 主要提供了一套 Web 应用自动构建与交付流程架构
通常情况下 Gitlab Runner 与 Gitlab 无需运行在同一台服务器, 他们之间通信基于授信 TOKEN, 整个运行流程是:
基于 Gitlab Flow 完成功能开发
提交 Merge Request, 等待功能发布申请
评审 Merge Request, 允许合并分支请求
触发 Gitlab Runner 运行
执行项目 .gitlab.ci.yml 配置好的流水线任务
完成 CI/CD 流水线工作, 工作结束
以一个前端项目为例, 构建过程会做以下任务
拉取 Git 代码
安装前端依赖
打包编译
Gitlab CI/CD 分布式构建参考
本项目 Gitlab Runner 默认采用 Shell 方式执行部署任务, 也即是 Runner 使用 SSH 登录到应用主机你可以在 Runner 容器中生成新的 ssh 秘钥对(或者使用能够登录到应用主机的其他 ssh 秘钥对), 确保能成功 SSH 到应用主机
进入到 Runner 容器
docker exec -it gitlab-ci-php-envoy-runner sh
使用 ssh 登录远程应用主机
ssh root@47.*.*.69
如果成功登录, 表示自动部署链接工作没有问题如果你的应用部署了多台服务器, 推荐使用 Larave Envoy 部署任务 Laravel Envoy 基于 PHP 实现, 提供了灵活的配置方便在应用主机构建任务 bravist/gitlab-ci-php-envoy Runner 基于 gitlab/gitlab-runner 镜像, 又增加了对 PHP 的支持, 完全支持 Laravel Envoy 部署
要使用 Laravel Envoy, 需要在仓库中增加 Envoy.blade.php 文件, 定义好所有主机需要做的事情
- @servers(['sandbox' => 'root@47.*.*.45', 'production' => 'root@47.*.*.69'])
- @story('sandbox_deploy', ['on' => ['sandbox']])
- git
- logistics-debt
- @endstory
- @story('production_deploy', ['on' => ['production']])
- git
- logistics-debt
- @endstory
- @task('git')
- cd /mnt/lnmp-docker/www/{{ $project }}/
- git config --global user.email "chenghuiyong1987@gmail.com"
- git config --global user.name "Gitlab Runner"
- git pull origin {{ $branch }}
- @endtask
- @task('logistics-debt')
- cd /mnt/lnmp-docker/www/{{ $project }}/logistics-debt
- cnpm install
- npm run build
- @endtask
同时, 在仓库的. gitlab-ci.yml 文件中定义使用 Envoy 执行构建任务
- stages:
- - sandbox
- - production
- variables:
- ENVOY: /root/.composer/vendor/bin/envoy
- sandbox:
- stage: sandbox
- script:
- - cd $CI_PROJECT_DIR
- - $ENVOY run sandbox_deploy --branch=develop --project=$CI_PROJECT_NAME
- only:
- - develop
- production:
- stage: production
- script:
- - cd $CI_PROJECT_DIR
- - $ENVOY run production_deploy --branch=master --project=$CI_PROJECT_NAME
- only:
- - master
来源: http://www.tuicool.com/articles/uMNNfqI