使用Github action自动部署,需要准备以下东西:
一台能上外网的Linux服务器,并且安装了docker
将已有项目推送到Github仓库
注册阿里云容器镜像服务(免费)
在阿里云容器镜像服务上添加命名空间
创建存储镜像的仓库
创建好以后,选择刚才创建的仓库,点击左侧基本信息,复制一下这个公网地址备用
登录你的github进入项目仓库,依次点击settings>Secrets>New secret
点击New secret以后出来的页面有2个选项,Name和Value,Name对应上图红框所示,Value填入Name对应的值,简单解释一下:
DOCKER_REPOSITORY: 镜像仓库地址,也就是上一个步骤复制到的公网地址
DOCKER_USERNAME:登录阿里云的账号
DOCKER_PASSWORD: 登录阿里云的密码
HOST:部署项目的服务器ip
HOST_PORT:服务器ssh端口号(默认是22)
HOST_USERNAME:服务器登录用户名(ps:非root权限账号请子u该账号所属组为docker)
HOST_PASSWORD: 登录服务器的密码
ps:这里的Secrets不会被pull,别人也看不到,所以还是比较安全
在github的项目仓库面板,依次点击code>Add file>create new file,Name your file填入Dockerfile,文件内容如下:
1FROM node:12.18.0-buster-slim 2RUN mkdir -p /usr/src 3COPY . /usr/src 4WORKDIR /usr/src 5RUN npm i 6EXPOSE 4000 7CMD ["node","app.js"]
ps:EXPOSE根据你的实际情况修改
填好之后点击下方的绿色commit new file按钮
简单解释一下:
顺便说一下RUN和CMD 的区别,相同点,都是执行命令,不同点在于,RUN 是在打包镜像的时候执行,CMD是在运行容器的执行
在github仓库面板点击Actions按钮,找到Node.js,选择Set up this workflow
在内容区域ctrl+a全选然后删除,粘贴进以下内容:
1name: Docker Image CI/CD 2on: 3 push: 4 branches: [ master ] 5jobs: 6 build: 7 runs-on: ubuntu-latest 8 steps: 9 - uses: actions/checkout@v2 10 - name: Build Image 11 run: docker build -t ${{ secrets.DOCKER_REPOSITORY }}:latest ./ 12 - name: Login to registry 13 run: docker login --username=${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_PASSWORD }} registry.cn-hangzhou.aliyuncs.com 14 - name: Push Image 15 run: docker push ${{ secrets.DOCKER_REPOSITORY }}:latest 16 pull-docker: 17 needs: [build] 18 name: Pull Docker 19 runs-on: ubuntu-latest 20 steps: 21 - name: Deploy 22 uses: appleboy/ssh-action@master 23 with: 24 host: ${{ secrets.HOST }} 25 username: ${{ secrets.HOST_USERNAME }} 26 password: ${{ secrets.HOST_PASSWORD }} 27 port: ${{ secrets.HOST_PORT }} 28 script: | 29 docker stop $(docker ps --filter ancestor=${{ secrets.DOCKER_REPOSITORY }} -q) 30 docker rm -f $(docker ps -a --filter ancestor=${{ secrets.DOCKER_REPOSITORY }}:latest -q) 31 docker rmi -f $(docker images ${{ secrets.DOCKER_REPOSITORY }}:latest -q) 32 docker login --username=${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_PASSWORD }} registry.cn-hangzhou.aliyuncs.com 33 docker pull ${{ secrets.DOCKER_REPOSITORY }}:latest 34 docker run -d -p 8000:4000 ${{ secrets.DOCKER_REPOSITORY }}:latest 35
然后点击右侧Start commit>Commit changes
有点懵逼?来一份注释吧
1name: Docker Image CI/CD # workflow名称,可以随意改 2on: # workflow的事件钩子,告知程序说明时候出发自动部署 3 push: 4 branches: [ master ] # 在master分支有push操作的时候自动部署 5jobs: 6 build: # 打包并上传docker镜像 7 runs-on: ubuntu-latest # 依赖的环境 8 steps: 9 - uses: actions/checkout@v2 10 - name: Build Image 11 # ${{ secrets.DOCKER_REPOSITORY }}是读取之前在Secret创建的名为DOCKER_REPOSITORY的值 12 run: docker build -t ${{ secrets.DOCKER_REPOSITORY }}:latest ./ # 打包并docker镜像,版本为latest 13 - name: Login to Registry # 登录阿里云镜像服务器 14 run: docker login --username=${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_PASSWORD }} registry.cn-hangzhou.aliyuncs.com 15 - name: Push Image # 推送镜像,设置版本为latest 16 run: docker push ${{ secrets.DOCKER_REPOSITORY }}:latest 17 pull-docker: # docker部署 18 needs: [build] 19 name: Pull Docker 20 runs-on: ubuntu-latest 21 steps: 22 - name: Deploy 23 uses: appleboy/ssh-action@master 24 with: 25 host: ${{ secrets.HOST }} # 服务器ip 26 username: ${{ secrets.HOST_USERNAME }} # 服务器登录用户名 27 password: ${{ secrets.HOST_PASSWORD }} # 服务器登录密码 28 port: ${{ secrets.HOST_PORT }} # 服务器ssh端口 29 script: | 30 # 停止旧版容器 31 docker stop $(docker ps --filter ancestor=${{ secrets.DOCKER_REPOSITORY }} -q) 32 # 删除旧版容器 33 docker rm -f $(docker ps -a --filter ancestor=${{ secrets.DOCKER_REPOSITORY }}:latest -q) 34 # 删除旧版镜像 35 docker rmi -f $(docker images ${{ secrets.DOCKER_REPOSITORY }}:latest -q) 36 # 登录阿里云镜像服务器 37 docker login --username=${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_PASSWORD }} registry.cn-hangzhou.aliyuncs.com 38 # 拉取最新latest版本镜像 39 docker pull ${{ secrets.DOCKER_REPOSITORY }}:latest 40 # 运行最新latest版本镜像 41 docker run -d -p 8000:4000 ${{ secrets.DOCKER_REPOSITORY }}:latest 42
这里使用的是yml的语法,该语法对缩进要求极高
在事件钩子on里面也可以指定tag,比如: tags: [release-v*] 意思是tag为 release-v*版本时候就出发自动部署
镜像版本这里写死了latest,当然也可以根据上下文context指定,指定好了替换所有的latest即可
上面的8000:4000的端口映射改成实际需要即可,这里对应上Dockerfile的端口,以及项目实际运行的端口,几个地方保持一致
以后每次push到master分支以后会自动触发actions,想要查看持续部署的过程可以点击项目面板的actions
如图所示,绿色钩的就是成功的,红叉的就是失败了,可以选择对应项查看部署日志
如果出错了,在日志里面可以查看到错误信息,对应修改就好了
关于Github Actions的详细说明可以参考官方文档