專案地址: github.com/xiongwilee/…
基本特性:
- 快捷部署多人nginx+php的開發測試環境,也可以擴充套件構建其他語言;
- 基於Docker和docker-compose,不依賴K8S等高階編排工具,成本低廉、部署簡單;
- Docker內建整合jenkins,一鍵新增開發測試角色,無需額外配置;
- 支援微服務架構,適用於小公司or敏捷專案團隊,也可以作為Docker學習入門的case;
一、背景
在角色分工明確的團隊裡,什麼樣的條件才算是最優雅的聯調和測試環境?在大廠裡肯定都有很多高階的解決方案,比如這些:
大型團隊的合作框架下,必須依賴更復雜的DevOps架構(參考:DevOps詳解)。但對於成員不多、負責的Web專案工程量也不大的團隊,面臨的問題肯定也更單純:
- 前後端角色工程解耦,開發環境分離;
- 工程師只關注業務邏輯本身,持續整合;
- 環境和角色一鍵建立、一鍵更新、一鍵銷燬,環境之間不受影響;
即便是隻有這些需求,在以往的“開發機”的聯調環境裡,一旦需要新增開發或者測試人員,或者需要更新nginx的配置,再或者需要更新PHP、Nodejs的版本……對於測試環境的維護來說都是很痛苦的。
二、快速開始
注意: 當前部署方案僅依賴:Docker
,Docker-compose
,git
1、下載程式碼
$ git clone https://github.com/xiongwilee/docker-compose-boilerplate.git
複製程式碼
2、新增測試角色demo
$ cd docker-compose
$ sh build.sh -u demo -m admin:master
複製程式碼
此時,在app/
會建立demo
目錄,在nginx/conf.d
會建立demo.conf
檔案。
3、啟動服務
$ docker-compose up -d
複製程式碼
此時,再執行docker-compose ps
會發現建立了三個映象。然後,配置hosts使sample.demo.testdomain.com
指向當前機器,然後訪問http://sample.demo.testdomain.com 返回phpinfo()
資訊,說明建立成功。
三、部署架構說明
TIPS: 這個方案僅適用於小公司or敏捷專案團隊聯調測試環境的部署,同時也可以作為Docker學習入門的case,並不適用於有一定規模的生產環境。
在“開發機”上僅僅安裝docker、docker-compose、git之後就能跑起來Nginx、PHP的應用,當然得益於docker容器化的思想。其實這個的實現也僅僅利用了容器化的這個特性,最終docker-compose打包的整個服務會長駐記憶體,無需太多的管理成本。
最終的實現還具備兩個特點:
- 基於這個實現的boilerplate你可以輕易的遷移到其他專案,以及其他語言;
- 每個
sample
管理每個應用的倉儲地址、環境變數配置、更新程式碼後的鉤子等操作;
其實現原理為:通過指令碼檔案,管理docker-compose隱射到宿主機的配置、原始碼,同時將docker-compose暴露出來以實現服務的管理。架構圖如下:
1、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開發環境示例:可以看到就php
、nginx
、jenkins
三個基本容器,除了jenkins
,其他的容器均使用Dockerfile(build配置)來構建。
2、構建指令碼:build.sh
由於在docker中實現了nginx配置檔案及php原始碼檔案的對映到宿主機,需要通過管理宿主機上檔案就可以管理程式碼的釋出和部署了,build.sh
就是用來做這件事情的。
當然了,如果需要在部署程式碼完成之後,做重啟、編譯等操作,通過sample目錄下的鉤子就可以實現了。
具體實現可以參考build.sh
原始碼。
四、詳細配置
1、開發測試環境域名配置
在nginx/conf.d/sample
修改測試環境域名,示例中使用的testdomain.com
改成自己的測試環境域名即可。
另外,建議把測試域名泛解析到部署這臺服務的機器。
2、docker-compose.yml
配置說明
docker-compose的配置檔案基本不需要修改,只需要關注:nginx是80埠對映到80埠,jenkins是8080埠,而php-fpm的9000埠不對外開放即可。
當然了,如果php環境需要安裝依賴,就需要修改./php/Dockerfile
。此外,如果需要新增其他的語言環境,就需要新增一個容器的宣告。
3、模組配置
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
新增一個任務後只需要配置兩項:
- general:“引數化構建過程”:
- 選擇 "String Parameter",新增"web"、"web-fe"、"service"欄位
- 選擇"Boolean Parameter",新增"web_env"、“service_env”欄位。
- 構建:"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,涉及到的改動有:
- 新增Nodejs映象:
docker-compose.yml
- 新增部署任務:
build.sh
- 建立及刪除角色流程
- 部署流程
- nginx配置檔案示例:
nginx/conf.d/sample
五、貢獻
歡迎提供其他更專業的思路,歡迎提issue、fork;也可以郵件聯絡:xiongwilee[at]foxmail.com。