使用 CODING 自動部署 Hyperf 專案

congcong發表於2021-07-20

本篇部署不是叢集部署,適合個人或小公司專案使用。

GitHub由於是國外平臺,程式碼拉取速度不是特別理想。所以使用了CODING作為程式碼託管平臺。

Hyperf是一款Swoole框架,如果是Mac開發可以直接在宿主機安裝Swoole擴充套件進行開發,如果在Mac上使用Docker的話速度會變慢。
如果用windows開發,可以使用WSL2,安裝Docker進行開發。不過感覺還是慢,推薦使用PhpStorm的Deployment服務直接使用檔案自動上傳伺服器,然後在伺服器安裝Docker環境進行開發。

建立基礎專案

  1. 首先我們點選右上角,建立一個專案

使用 CODING 自動部署 Hyperf 專案
進入專案後點選右上角,建立一個程式碼倉庫

使用 CODING 自動部署 Hyperf 專案

  1. 安裝 Hyperf
    安裝方式
    然後和我們剛剛建立的遠端倉庫關聯(預設大家都有這個能力)

編寫構建計劃

這裡先大概說下我們整體的部署流程。

首先檢出分支,然後會根據分支下的Dockerfile生成映象,然後推送映象到coding的製品倉庫。最後登入伺服器拉取映象進行部署。

流程清楚了那麼我們就開始編寫構建計劃吧

  1. 建立構建計劃
    首先我們先建立一個構建計劃,構建計劃就是弄一套指令,讓它按照我們自己設定的規則執行
    使用 CODING 自動部署 Hyperf 專案
    然後選擇構造計劃模板,我們這裡選擇自定義模板

使用 CODING 自動部署 Hyperf 專案

按照預設配置即可,這裡我們先使用線上的Jenkinsfile,後續可以根據自己需求使用程式碼倉庫中的Jenkinsfile

使用 CODING 自動部署 Hyperf 專案

開始進行流程配置

使用 CODING 自動部署 Hyperf 專案

  1. 生成映象並推送

    pipeline {
    agent any
    stages {
     stage("檢出") {
       steps {
         checkout([
           $class: 'GitSCM',
           branches: [[name: GIT_BUILD_REF]],
           userRemoteConfigs: [[
             url: GIT_REPO_URL,
             credentialsId: CREDENTIALS_ID
         ]]])
       }
     }
    
    stage('生成映象') {
       steps {
         echo '生成映象中……'
         sh 'ls'
         sh 'docker build -t ${IMAGE_NAME} -f Dockerfile ./'
         echo '生成映象完成'
       }
     }
    
     stage('推送映象') {
       steps {
         echo '推送映象中...'
         sh 'docker login -u image-xxxx -p ${DOCKER_TOKEN} xxx-docker.pkg.coding.net'
         sh 'docker tag ${IMAGE_NAME} xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}'
         sh 'docker push xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}'
         echo '推送完成'
       }
     }
    }
    }

    我們先來看生成映象,因為Hyperf官方已經在專案中寫好了Dockerfile,我們可根據自己需求更改直接使用就好。很簡單就是執行了一個docker命令,但是裡面有一個映象名,這個我們拿出來定義一個變數然後在檔案中就可以通過${IMAGE_NAME} 這種方式來訪問了。
    定義變數:

使用 CODING 自動部署 Hyperf 專案

映象生成了,往哪兒推送?別急,我們先儲存構建計劃。
然後新建一個製品庫,就是存放我們docker映象的地方

使用 CODING 自動部署 Hyperf 專案

建立成功後,如圖

使用 CODING 自動部署 Hyperf 專案

然後複製倉庫中的登入和推送命令配置到我們構造計劃檔案中

我們這裡選擇使用令牌的方式進行登入,點選這個按鈕,複製生成的令牌。替換剛才的登入命令

使用 CODING 自動部署 Hyperf 專案

由於登入密碼是敏感的,我們按照第一次建立環境變數的方式再次新增一個變數${DOCKER_TOKEN} 替換登入密碼

到此為止,其實已經完成專案自動生成映象並上傳倉庫。已經可以在伺服器手動Docker映象拉取部署了。(伺服器需要已安裝Docker,不然玩兒毛)

  1. 自動部署
stage('部署') {
      steps {
        echo '部署中...'
        script {
          def remote = [:]
          remote.name = 'my-server'
          remote.allowAnyHosts = true
          // 主機地址
          remote.host = '123.123.123.132'
          remote.port = 22
          // 使用者名稱
          remote.user = 'root'
         // credentialsId: coding登入主機的祕鑰
          withCredentials([sshUserPrivateKey(credentialsId: 'coding的key', keyFileVariable: 'id_rsa')]) {
            remote.identityFile = id_rsa
            // 登入並拉取映象
            sshCommand remote: remote, command: "docker login -u image-xxxx -p ${DOCKER_TOKEN} xxx-docker.pkg.coding.net"
            sshCommand remote: remote, command: "docker pull xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}:latest"
            // 停止舊的服務,注意加 ||true,不然第一次部署會報錯
            sshCommand remote: remote, command: "docker stop ${PROJECT_NAME} || true"
            sshCommand remote: remote, command: "docker rm ${PROJECT_NAME} || true"
            // 啟動新服務
            sshCommand remote: remote, command: "docker run -d --restart always -p 10090:9501 -v /www/go_pocket_api.env:/opt/www/.env --name ${PROJECT_NAME} -d xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}:latest"
            // 再啟動一個容器,防止服務中斷
            sshCommand remote: remote, command: "docker stop ${PROJECT_NAME}2 || true"
            sshCommand remote: remote, command: "docker rm ${PROJECT_NAME}2 || true"
            sshCommand remote: remote, command: "docker run -d --restart always -p 10091:9501 -v /www/go_pocket_api.env:/opt/www/.env --name ${PROJECT_NAME}2 -d xxx-docker.pkg.coding.net/practice/practice/blog/${IMAGE_NAME}:latest"
          }

        }
        echo '部署完成'
      }
    }

上部分配置參考了Hyperf作者文章
如何單機部署 Hyperf 專案

上面我們注意有個credentialsId,這個是coding能登入我們伺服器的關鍵。這個東西會在condig讀取祕鑰,然後使用祕鑰登入我們的伺服器進行操作。
所以伺服器需要支援ssh祕鑰登入。
生成方式:
點選專案設定:

使用 CODING 自動部署 Hyperf 專案

然後錄入憑據,最後使用憑據id填入上面的credentialsId

錄入憑據的方法
最後我們還需要配置觸發規則,也就是什麼情況執行部署。推送到master,或者推送新標籤後觸發。

使用 CODING 自動部署 Hyperf 專案

還有一點需要注意,由於自動部署需要訪問我們的docker映象倉庫。所以我們需要把執行構建的伺服器IP新增到docker映象倉庫的白名單裡面。
(因為我們使用的免費的,所以使用了coding自己的伺服器,基本夠用。不夠用可以夠買coding提供的構建伺服器。好像也不貴。)

首先複製構建伺服器ip

使用 CODING 自動部署 Hyperf 專案

寫入到白名單

使用 CODING 自動部署 Hyperf 專案
然後新增兩個IP到白名單

使用 CODING 自動部署 Hyperf 專案

儲存即可

完整版Jenkinsfile

pipeline {
  agent any
  stages {
    stage("檢出") {
      steps {
        checkout([
          $class: 'GitSCM',
          branches: [[name: GIT_BUILD_REF]],
          userRemoteConfigs: [[
            url: GIT_REPO_URL,
            credentialsId: CREDENTIALS_ID
        ]]])
      }
    }

   stage('生成映象') {
      steps {
        echo '生成映象中……'
        sh 'ls'
        sh 'docker build -t ${IMAGE_NAME} -f Dockerfile ./'
        echo '生成映象完成'
      }
    }

    stage('推送映象') {
      steps {
        echo '推送映象中...'
        sh 'docker login -u image-xxxx -p ${DOCKER_TOKEN} xxx-docker.pkg.coding.net'
        sh 'docker tag ${IMAGE_NAME} xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}'
        sh 'docker push xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}'
        echo '推送完成'
      }
    }

    stage('部署') {
      steps {
        echo '部署中...'
        script {
          def remote = [:]
          remote.name = 'my-server'
          remote.allowAnyHosts = true
          // 主機地址
          remote.host = '123.123.123.132'
          remote.port = 22
          // 使用者名稱
          remote.user = 'root'
         // credentialsId: coding登入主機的祕鑰
          withCredentials([sshUserPrivateKey(credentialsId: 'coding的key', keyFileVariable: 'id_rsa')]) {
            remote.identityFile = id_rsa
            // 登入並拉取映象
            sshCommand remote: remote, command: "docker login -u image-xxxx -p ${DOCKER_TOKEN} xxx-docker.pkg.coding.net"
            sshCommand remote: remote, command: "docker pull xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}:latest"
            // 停止舊的服務,注意加 ||true,不然第一次部署會報錯
            sshCommand remote: remote, command: "docker stop ${PROJECT_NAME} || true"
            sshCommand remote: remote, command: "docker rm ${PROJECT_NAME} || true"
            // 啟動新服務
            sshCommand remote: remote, command: "docker run -d --restart always -p 10090:9501 -v /www/go_pocket_api.env:/opt/www/.env --name ${PROJECT_NAME} -d xxx-docker.pkg.coding.net/practice/blog/${IMAGE_NAME}:latest"
            // 再啟動一個容器,防止服務中斷
            sshCommand remote: remote, command: "docker stop ${PROJECT_NAME}2 || true"
            sshCommand remote: remote, command: "docker rm ${PROJECT_NAME}2 || true"
            sshCommand remote: remote, command: "docker run -d --restart always -p 10091:9501 -v /www/go_pocket_api.env:/opt/www/.env --name ${PROJECT_NAME}2 -d xxx-docker.pkg.coding.net/practice/practice/blog/${IMAGE_NAME}:latest"
          }

        }
        echo '部署完成'
      }
    }

  }
}

需要注意,執行前需要先建立好env檔案,因為Docker掛載時如果原始檔不存在會自動建立目錄。參考Docker掛載檔案不存在情況

.env檔案沒想好有什麼自動不需要建立的方式,寫入到映象環境變數中??
大家有好的思路可以交流

然後我們本地修改程式碼,推送到master或者推送標籤根據自己設定的觸發規則來。神奇的事情發生了。

使用 CODING 自動部署 Hyperf 專案

Nginx配置

upstream test {
    server 127.0.0.1:10090;
    server 127.0.0.1:10091;
}
server {
    listen       80;
    server_name  www.xxx.com;
    location / {
        proxy_pass          http://test;
        proxy_set_header    Host                $host:$server_port;
        proxy_set_header    X-Real-IP           $remote_addr;
        proxy_set_header    X-Real-PORT         $remote_port;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    }
}

到此,部署完成。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章