代碼部署(二):使用github+circleCI部署代碼到多臺服務(wù)器

本文講解的部署流程是:

  1. 推送代碼到github
  2. 觸發(fā)circleCI,開始進(jìn)行測試,然后執(zhí)行部署命令(部署命令的內(nèi)容就是使用上一篇文章講解的git部署代碼的方式)
  3. 服務(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é)

實際上把這些腳本/配置都寫好之后,以后每次需要新建一個新項目需要配置的就那幾步:

  1. github上的項目添加到circleCI
  2. 在circleCI項目設(shè)置中的ssh權(quán)限設(shè)置添加部署私鑰
  3. 創(chuàng)建項目目錄,然后進(jìn)入目錄
  4. git init
  5. [git checkout -b develop]
  6. git config receive.denyCurrentBranch ignore
  7. vi .git/hooks/post-receive
  8. 粘貼鉤子腳本,修改必要參數(shù)(如該環(huán)境需要cp的配置文件名)
  9. chmod a+x .git/hooks/post-receive
  10. 項目端復(fù)制入已經(jīng)寫好的circleCI腳本,修改必要參數(shù)(如要部署的目錄)
  11. 推送項目到github就可以完成部署了

后端項目在第一次推送之后還需要:

  1. 修改相應(yīng)目錄的寫權(quán)限
  2. 添加軟鏈接
  3. 其他初始化命令(引入庫需要執(zhí)行的安裝命令等)
    或者把這些第一次部署需要執(zhí)行的命令都編寫好腳本.下一篇文章我們使用的第三方部署工具把這些都做好了.

參考

circleCI文檔
stackoverflow->protocol error: expected old/new/ref, got 'shallow dee..

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容