使用 CODING 自动部署 Hyperf 项目

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

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 协议》,转载必须注明作者和本文链接
本帖由系统于 2年前 自动加精
讨论数量: 6

我用这个不到一分钟,镜像得弄个版本,不然一堆。

2年前 评论
congcong (楼主) 2年前
Lion- (作者) 2年前
congcong (楼主) 1年前

注意了,如果是部署阿里云主机。需要把构建服务器IP加入阿里云ECS主机的白名单。当然了也可以用阿里云云效。殊途同归的都是。

1年前 评论

mark一下。等下实践试试

11个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!