聯調環境快速部署——基於docker-compose的CI/CD實踐

項目地址: github.com/xiongwilee/…php

基本特性:nginx

  1. 快捷部署多人nginx+php的開發測試環境,也能夠擴展構建其餘語言;
  2. 基於Docker和docker-compose,不依賴K8S等高級編排工具,成本低廉、部署簡單;
  3. Docker內置集成jenkins,一鍵添加開發測試角色,無需額外配置;
  4. 支持微服務架構,適用於小公司or敏捷項目團隊,也能夠做爲Docker學習入門的case

1、背景

在角色分工明確的團隊裏,什麼樣的條件纔算是最優雅的聯調和測試環境?在大廠裏確定都有不少高級的解決方案,好比這些:git

大型團隊的合做框架下,必須依賴更復雜的DevOps架構(參考:DevOps詳解)。但對於成員很少、負責的Web項目工程量也不大的團隊,面臨的問題確定也更單純:github

  1. 先後端角色工程解耦,開發環境分離;
  2. 工程師只關注業務邏輯自己,持續集成;
  3. 環境和角色一鍵建立、一鍵更新、一鍵銷燬,環境之間不受影響;

即使是隻有這些需求,在以往的「開發機」的聯調環境裏,一旦須要添加開發或者測試人員,或者須要更新nginx的配置,再或者須要更新PHP、Nodejs的版本……對於測試環境的維護來講都是很痛苦的。web

2、快速開始

注意: 當前部署方案僅依賴:Docker,Docker-compose,gitdocker

一、下載代碼

$ git clone https://github.com/xiongwilee/docker-compose-boilerplate.git
複製代碼

二、添加測試角色demo

$ cd docker-compose
$ sh build.sh -u demo -m admin:master
複製代碼

此時,在app/會建立demo目錄,在nginx/conf.d會建立demo.conf文件。後端

三、啓動服務

$ docker-compose up -d
複製代碼

此時,再執行docker-compose ps會發現建立了三個鏡像。而後,配置hosts使sample.demo.testdomain.com指向當前機器,而後訪問http://sample.demo.testdomain.com 返回phpinfo()信息,說明建立成功。bash

3、部署架構說明

TIPS: 這個方案僅適用於小公司or敏捷項目團隊聯調測試環境的部署,同時也能夠做爲Docker學習入門的case,並不適用於有必定規模的生產環境。markdown

在「開發機」上僅僅安裝docker、docker-compose、git以後就能跑起來Nginx、PHP的應用,固然得益於docker容器化的思想。其實這個的實現也僅僅利用了容器化的這個特性,最終docker-compose打包的整個服務會長駐內存,無需太多的管理成本。架構

最終的實現還具有兩個特色:

  1. 基於這個實現的boilerplate你能夠輕易的遷移到其餘項目,以及其餘語言;
  2. 每一個sample管理每一個應用的倉儲地址、環境變量配置、更新代碼後的鉤子等操做;

其實現原理爲:經過腳本文件,管理docker-compose隱射到宿主機的配置、源碼,同時將docker-compose暴露出來以實現服務的管理。架構圖以下:

一、docker-compose配置文件:docker-compose.yml

先看docker-compose的配置文件docker-compose.yml(篇幅緣由,刪掉了一部分配置):

version: '3'
services:
    # 全部的PHP環境構建在app容器裏
 php:
 build: ./php
 expose:
 - "9000"
    # nginx容器
 nginx:
 build: ./nginx
        # 端口映射
 ports:
 - "80:80"
        # 依賴關係聲明,先跑php全部服務
 depends_on:
 - "php"
    # jenkins容器
 jenkins:
 image: jenkins:latest
 ports:
 - "8080:8080"
 - "50000:50000"
複製代碼

這其實就是一個普通的PHP開發環境示例:能夠看到就phpnginxjenkins三個基本容器,除了jenkins,其餘的容器均使用Dockerfile(build配置)來構建。

二、構建腳本:build.sh

因爲在docker中實現了nginx配置文件及php源碼文件的映射到宿主機,須要經過管理宿主機上文件就能夠管理代碼的發佈和部署了,build.sh就是用來作這件事情的。

固然了,若是須要在部署代碼完成以後,作重啓、編譯等操做,經過sample目錄下的鉤子就能夠實現了。

具體實現能夠參考build.sh源碼。

4、詳細配置

一、開發測試環境域名配置

nginx/conf.d/sample修改測試環境域名,示例中使用的testdomain.com改爲本身的測試環境域名便可。

另外,建議把測試域名泛解析到部署這臺服務的機器。

二、docker-compose.yml配置說明

docker-compose的配置文件基本不須要修改,只須要關注:nginx是80端口映射到80端口,jenkins是8080端口,而php-fpm的9000端口不對外開放便可。

固然了,若是php環境須要安裝依賴,就須要修改./php/Dockerfile。此外,若是須要添加其餘的語言環境,就須要添加一個容器的聲明。

三、模塊配置

1)部署腳本build.sh

業務模塊的配置基本是經過部署腳本build.sh來操做的。執行./build.sh提示以下:

Example:
  ./build.sh -u xiongwilee -m php:online,service:online
Usage:
  -u 必填,角色名                       示例:default
  -m 選填,要更新代碼的業務模塊         示例:php:online,service:online
  -e 選填,更新業務模塊對應的環境變量   示例:php:true,service:false
  -d 選填,刪除角色                     示例:default
複製代碼

2)PHP模塊

新增角色實時上是根據php/sample目錄建立了一個角色名對應的文件夾。在sample裏只有四個文件:

a. 倉儲配置
  • .gitaddress:聲明當前模塊的遠程倉儲地址
b. 鉤子
  • on_add.sh:建立角色時下載PHP模塊代碼完成以後的回調鉤子,用已更新環境變量等文件,執行./build.sh -u {name}會被調用
  • on_upd.sh:某個模塊更新完成以後的回調鉤子,用以編譯、重啓服務等操做,執行./build.sh -u {name} -m web:master會被調用
  • on_env.sh:更新環境變量的鉤子,執行./build.sh -u {name} -m web:master -e web:true都會被調用。
c. 示例目錄app/sample/sample

在sample目錄下還有個sample目錄,這個是一個php模塊示例;新增角色以後訪問sample.{name}.testdomain.com就能夠來測試是否成功新增。

3)Nginx配置

a. nginx/conf.d目錄

和php/sample目錄同樣,在nginx/conf.d下也有個sample文件,這個也是在新增角色時使用的示例配置文件。注意,新增角色會把sample中的${name}替換成當前角色名。

b. nginx/log目錄

nginx/log目錄及nginx全部日誌文件的宿主機映射目錄。

4)Jenkins配置方案

jenkins默認開啓8080端口,你能夠直接經過http://jenkins.testdomain.com:8080訪問jenkins服務。具體初始化過程這裏不詳述。

a. 安裝插件獲取當前用戶名

在經過Jenkins執行build.sh腳本時,上文提到的角色名怎麼獲取呢?其實就是jenkins的用戶名,你能夠經過建立多個jenkins的用戶來建立測試環境角色。

參考jenkins插件-Build User Vars Plugin簡單說明安裝jenkins插件。

安裝完成以後就能夠經過BUILD_USER環境變量獲取當前jenkins的用戶名了(固然了,新建jenkins用戶的用戶名最好是拼音或英文)。

b. Docker鏡像中的Jenkins與宿主機通訊

因爲jenkins存在Docker鏡像中,每次jenkins操做須要執行build.sh都須要使鏡像中的jenkins與宿主機通訊。這裏使用的方法是,在jenkins的鏡像添加到宿主機的信任關係。

而後就能夠經過ssh apple@{jenkins內網IP} "sh build.sh"來直接執行宿主機裏的腳本了(這裏確定還有更優雅的方法)。

c. 添加job

添加一個任務後只須要配置兩項:

  1. general:「參數化構建過程」:
    • 選擇 "String Parameter",添加"web"、"web-fe"、"service"字段
    • 選擇"Boolean Parameter",添加"web_env"、「service_env」字段。
  2. 構建:"Execute Shell":
echo "正在將 web-fe:${web_fe},web:${web},service:${service} 部署到 ${BUILD_USER_ID} 環境"

ssh apple@{jenkins內網IP} "sh ~/docker-compose/build.sh -u ${BUILD_USER_ID} -m web-fe:${web_fe},web:${web},service:${service} -e web:${web_env},service:${service_env}";
複製代碼

這樣,經過這個任務就能夠直接在jenkins中執行宿主機中的build.sh腳本,從而實現新增角色、更新代碼的操做了。

最後,若是須要在PHP的服務基礎上集成其餘語言的服務,好比Nodejs,涉及到的改動有:

  1. 添加Nodejs鏡像:docker-compose.yml
  2. 添加部署任務:build.sh
    • 建立及刪除角色流程
    • 部署流程
  3. nginx配置文件示例:nginx/conf.d/sample

5、貢獻

歡迎提供其餘更專業的思路,歡迎提issue、fork;也能夠郵件聯繫:xiongwilee[at]foxmail.com

相關文章
相關標籤/搜索