本文講解的部署流程是:
- 推送代碼到github
- 觸發(fā)circleCI,開始進(jìn)行測試,然后執(zhí)行部署命令(部署命令的內(nèi)容就是使用上一篇文章講解的git部署代碼的方式)
- 服務(wù)器接收到代碼,觸發(fā)鉤子,執(zhí)行其他需要執(zhí)行的項目升級命令
問題
這樣的部署流程有一個問題,當(dāng)執(zhí)行到composer update這樣的命令的時候,項目是不能正常訪問的,這在生產(chǎn)環(huán)境中是不能接受的.
解決方式:
在執(zhí)行部署的時候,新建一個目錄執(zhí)行部署新的版本,完成后,修改軟鏈接到新的目錄.
有一些現(xiàn)成的工具(比如:deployer)可以幫助我們完成這些,后面我會寫一篇文章專門介紹.
或者你也可以根據(jù)自己的需求自己編寫部署命令解決這些問題.
接下來,我們結(jié)合使用github和circleCI實現(xiàn)更強(qiáng)大的功能.
CircleCI可以直接與github整合,提供構(gòu)建/測試/部署功能.這篇文章主要介紹如何使用github+circleCI部署代碼到服務(wù)器.
以一個laravel的php項目為例介紹circleCI的使用
circleCI端的配置
通過github登錄circleCI后,可以看到你擁有的github項目,需要哪個項目就添加那個到circleCI就好了,circleCI會自動完成github端的配置.
使用命令ssh-keygen -f deploy就可以生成一對鑰匙,然后需要在circleCI項目設(shè)置->ssh權(quán)限設(shè)置中新增剛生成的私鑰(如果不設(shè)置hostname的話,對所有服務(wù)器有效).對應(yīng)的公鑰配置在服務(wù)器的~/.ssh/authorized_keys(部署用戶的對應(yīng).ssh目錄)中.
我是所有的項目部署均使用相同的一對鑰匙,所以circleCI的上所有的項目配置相同的私鑰,然后不配置hostname,所有服務(wù)器authorized_keys添加相同的公鑰.
circle.yml文件
在項目根目錄創(chuàng)建circle.yml文件.
1. 部署代碼主要看deployment塊,分為staging 和production兩個環(huán)境,分別對應(yīng)develop和master分支.當(dāng)你把代碼推送到github的不同分支時,就會執(zhí)行不同的命令,你可以在這里寫git命令來把代碼推送到不同服務(wù)器.詳細(xì)的部署配置參考
2. 使用git命令推送之前需要配置好git相應(yīng)的遠(yuǎn)程分支.在./script/circleCI/git_production.sh中有體現(xiàn).
circle.yml(php 項目)示例:
## Customize the test machine
machine:
timezone:
Asia/Shanghai # Set the timezone
php:
# https://circleci.com/docs/environment#php
version: 7.1.0
# Add some environment variables
environment:
CIRCLE_ENV: test
## Customize dependencies
dependencies:
pre:
# - npm update -g npm
# - nvm install 6
# - nvm use 6
# - node -v
- yes|cp .env.staging .env
- yes|cp composer.json.circle composer.json
# - npm install -g gulp
override:
# 禁止circleCI自動執(zhí)行的命令,比如會自動根據(jù)有沒有package.json執(zhí)行npm install等
- echo "Ignore CircleCI defaults"
# - composer install
# - composer update
# - php artisan vendor:publish --tag=laravel-admin
# - php artisan vendor:publish --tag=easy-mall
# - php artisan migrate
# - npm install
# - gulp --production
# we automatically cache and restore many dependencies between
# builds. If you need to, you can add custom paths to cache:
cache_directories:
#- "custom_1" # relative to the build directory
#- "~/custom_2" # relative to the user's home directory
- ~/.composer/cache
- vendor
# - node_modules
## Customize test commands
test:
override:
- echo "Ignore CircleCI defaults"
# - vendor/bin/phpunit
## dev:開發(fā)環(huán)境,使用文件系統(tǒng)直接部署
## staging::對應(yīng)develop分支
## produciton:對應(yīng)master分支,部署正式環(huán)境
## 這個部署分支和環(huán)境只是個參考,下一篇文章會專門說明部署環(huán)境
deployment:
staging:
branch: develop
commands:
- ./script/circleCI/git_staging.sh
production:
branch: master
commands:
- ./script/circleCI/git_production.sh
notify:
webhooks:
- url: https://jianliao.com/v2/services/webhook/xxx
git_production.sh示例
# 檢查git remote是否有對應(yīng)的部署地址,沒有則添加. 用來部署項目時使用
#!/bin/sh
#要部署的項目服務(wù)器目錄地址,包含生產(chǎn)環(huán)境項目地址和預(yù)演環(huán)境地址
server_paths=(
/app/back_end/temp/production
)
#要部署的服務(wù)器地址
servers=(
ssh://username@ipaddress1:port
ssh://mallto@ipaddress2:port
)
remotes=$(/usr/bin/git remote)
echo $remotes
i=0
for server in ${servers[@]}
do
#echo ${server}
#部署到指定的server_paths
for server_path in ${server_paths[@]}
do
temp_remote=${server}${server_path}
echo ${temp_remote}
remote_name=$(echo -n ${temp_remote} | md5sum | awk '{print $1}')
echo ${remote_name}
remote_names[i]=${remote_name}
i=`expr $i + 1`
if [[ $remotes == *${remote_name}* ]]
then
echo "readd"
git remote remove ${remote_name}
git remote add ${remote_name} ${temp_remote}
else
echo "first add"
git remote add ${remote_name} ${temp_remote}
fi
done
done
git fetch --unshallow
for remote_name_item in ${remote_names[@]}
do
git push -f ${remote_name_item} master
done
通知結(jié)果
slack雖然好用,但是國內(nèi)訪問有問題,為了保證能夠及時收到消息,我比較了零信和簡聊.測試中零信經(jīng)常漏掉circleCI的通知,簡聊每次都收到了所以使用簡聊.
在簡聊的頻道中添加circleCI的服務(wù),會得到一個webhooks地址,添加到circleCI的配置文件即可.
總結(jié)
實際上把這些腳本/配置都寫好之后,以后每次需要新建一個新項目需要配置的就那幾步:
- github上的項目添加到circleCI
- 在circleCI項目設(shè)置中的ssh權(quán)限設(shè)置添加部署私鑰
- 創(chuàng)建項目目錄,然后進(jìn)入目錄
git init[git checkout -b develop]git config receive.denyCurrentBranch ignorevi .git/hooks/post-receive- 粘貼鉤子腳本,修改必要參數(shù)(如該環(huán)境需要cp的配置文件名)
chmod a+x .git/hooks/post-receive- 項目端復(fù)制入已經(jīng)寫好的circleCI腳本,修改必要參數(shù)(如要部署的目錄)
- 推送項目到github就可以完成部署了
后端項目在第一次推送之后還需要:
- 修改相應(yīng)目錄的寫權(quán)限
- 添加軟鏈接
- 其他初始化命令(引入庫需要執(zhí)行的安裝命令等)
或者把這些第一次部署需要執(zhí)行的命令都編寫好腳本.下一篇文章我們使用的第三方部署工具把這些都做好了.
參考
circleCI文檔
stackoverflow->protocol error: expected old/new/ref, got 'shallow dee..