使用 CODING 自动部署 Hyperf 项目

PHP技术
569
0
0
2022-05-24
标签   Hyperf

本篇部署不是集群部署,适合个人或小公司项目使用。

GitHub由于是国外平台,代码拉取速度不是特别理想。所以使用了CODING作为代码托管平台。

Hyperf是一款Swoole框架,如果是Mac开发可以直接在宿主机安装Swoole扩展进行开发,如果在Mac上使用Docker的话速度会变慢。

如果用windows开发,可以使用WSL2,安装Docker进行开发。不过感觉还是慢,推荐使用PhpStorm的Deployment服务直接使用文件自动上传服务器,然后在服务器安装Docker环境进行开发。

创建基础项目

  1. 首先我们点击右上角,创建一个项目

使用 CODING 自动部署 Hyperf 项目

进入项目后点击右上角,创建一个代码仓库

使用 CODING 自动部署 Hyperf 项目

  1. 安装 Hyperf
  2. 安装方式
  3. 然后和我们刚刚创建的远程仓库关联(默认大家都有这个能力)

编写构建计划

这里先大概说下我们整体的部署流程。

首先检出分支,然后会根据分支下的Dockerfile生成镜像,然后推送镜像到coding的制品仓库。最后登录服务器拉取镜像进行部署。

流程清楚了那么我们就开始编写构建计划吧

  1. 创建构建计划
  2. 首先我们先创建一个构建计划,构建计划就是弄一套指令,让它按照我们自己设定的规则执行
  3. 使用 CODING 自动部署 Hyperf 项目
  4. 然后选择构造计划模板,我们这里选择自定义模板

使用 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 '推送完成'
   }
 }
}
}
  1. 我们先来看生成镜像,因为Hyperf官方已经在项目中写好了Dockerfile,我们可根据自己需求更改直接使用就好。很简单就是执行了一个docker命令,但是里面有一个镜像名,这个我们拿出来定义一个变量然后在文件中就可以通过${IMAGE_NAME} 这种方式来访问了。
  2. 定义变量:

使用 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;
    }
}

到此,部署完成。