关于husky+自写node程序,完成git commit后,自动部署docker刷新后台程序

163 阅读2分钟

背景:我这边尝试使用husky+自动node实现提交的同时,自动把本地代码复制粘贴到项目目录中。 使用了docker+pm2+fs-extra+child_process 其他部分代码与上一篇文章对应,是同一个项目中的

创建dockerfile

本来使用了最新的node:latest(17.几的测试版),然后yarn报错,这边降了版本

FROM node:16

RUN yarn global add tyarn \
    && tyarn global add pm2

WORKDIR /home/project

EXPOSE 3000

CMD ["pm2-runtime","ecosystem.config.js"]

PM2使用pm2-runtime因为docker中会监听前台任务,如果什么都没就会退出。而默认的pm2命令在后台运行,docker无法监听到。

.husky>pre-commit

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# npm test
npm run move:prod

package.json

"scripts": {
    "start": "nodemon ./index.js",
    "prepare": "husky install",
    "move:prod": "node ./bin/moveFile.js"
},

ecosystem.config.js

console.log("读取配置文件", __dirname)

module.exports = {
  apps: [
    {
      name: "back",
      script: "index.js",
      out_file: "./logs/back.log",
      error_file: "./logs/err.log",
      watch: true,
      ignore_watch: [
        "node_modules",
        "logs",
        "uploads",
        ".git",
        "static",
        "test"
      ],
      "watch_options": {
        "usePolling": true
      }
    }
  ],
  // 这一块内容可能没有成功执行,以后再进行二次调试,目前看不出什么问题(因为没有日志输出,但程序正常,无法判断是否有问题)
  deploy: {
    production: {
      'post-deploy': "tyarn && pm2 startOrRestart ecosystem.config.js"
    }
  }
}

bin/moveFile.js

// @ts-nocheck
const { execSync, exec } = require('child_process')
const { emptyDir, copy } = require('fs-extra')
const { readdir } = require('fs/promises')
const path = require('path')

// 文件路径
// 打包路径
const source = path.resolve(__dirname, '../')
const target = path.resolve(__dirname, '../../docker-data/back/project')
const history = path.resolve(__dirname, '../../docker-data/back/history')

const ignoreCopy = ['node_modules', '.git', '.husky', 'bin']

async function main() {
    try {
        // 启停docker,否则复制粘贴文件出问题
        execSync("docker stop visual_back")

        await copyDir(target, history)

        await copyDir(source, target)
        execSync("docker start visual_back")
    } catch (e) {
        throw new Error(e)
    }
}

async function copyDir(source, target) {
    // 遍历文件,然后选择性复制
    let files = await readdir(source)
    let promiseList = []
    for (let file of files) {
        // 如果不在忽略列表
        if (!ignoreCopy.includes(file)) {
            // 需要放置到的后端
            let targetTemp = path.resolve(target, file)
            // 源文件
            let sourceTemp = path.resolve(source, file)
            // 放入Promise集合
            promiseList.push(copy(sourceTemp, targetTemp))
        }
    }

    await Promise.all(promiseList)

    console.log(source + "-->" + target + '。文件处理完成')
}

main()

这边在移动文件的时候,必须先停止docker相应的容器,不然会报错。 关于文件删除后,对应的迁移文件夹是不会删除文件的,这一点需要特别注意。 其实有一个办法,先删除所有ignoreCopy和ignoreDelete(这个未实现)除外的所有文件,再进行拷贝。不过懒得写了,而且自己搭着玩并不重要