Linux 环境下使用Docker实现自动化部署

125 阅读2分钟

记录一次将github上的服务端工程,自动部署到Linux服务器上。

使用技术:Linux,Docker,Webhooks

创建webhook

  1. 进入github-> xxx工程 -> 设置 -> Webhooks

webhooks.png 2. 添加webhooks

add-webhooks.png

创建服务器端监听程序

这里使用的node创建的一个本地服务

const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const { exec } = require('child_process');

const app = express();
const PORT = 10001; // 自定义端口

const deployPath = "/opt/webhook-listener/bin/deploy.sh";

// GitHub secret
const SECRET = 'abcd1234'; // 设置在 GitHub 的 secret

// 自定义 body parser 中间件用于验证签名前保留原始 body
app.use(bodyParser.json({
  verify: function (req, res, buf) {
    req.rawBody = buf;
  }
}));

// 验证 GitHub 发来的请求签名
function isSignatureValid(req) {
  const signature = req.headers['x-hub-signature-256'];
  console.log(signature);
  if (!signature) return false;

  const hmac = crypto.createHmac('sha256', SECRET);
  const digest = 'sha256=' + hmac.update(req.rawBody).digest('hex');
  console.log(digest);

  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

// webhook 路由
app.post('/webhook', (req, res) => {
  if (!isSignatureValid(req)) {
    console.log('❌ 无效的 GitHub 签名');
    return res.status(401).send('签名验证失败');
  }

  console.log('✅ 收到 GitHub Webhook 推送,开始部署...');

  // 执行你的部署脚本
  exec(deployPath, (error, stdout, stderr) => {
    if (error) {
      console.error(`❌ 部署失败:\n${stderr}`);
      return res.status(500).send('部署失败');
    }

    console.log(`✅ 部署成功:\n${stdout}`);
    res.send('部署成功');
  });
});

// 启动服务
app.listen(PORT, () => {
  console.log(`🚀 Webhook 服务监听端口: ${PORT}`);
});

创建本地执行脚本

在上面本地的node服务中有exec的执行脚本,deployPath 就是本地执行的脚本,也可以将该脚本直接写在 index.js

#!/bin/bash
set -e
APP_DIR="/opt/sharedKitchenBack/"
CI_DIR="/opt/sharedKitchenBack/ci"

echo "拉取最新代码"
cd "$APP_DIR"
git reset --hard
git clean -fd
git pull origin main
npm install
echo "重启 Docker 容器"
cd "$CI_DIR"
docker-compose pull
docker-compose down
docker-compose up -d --build
docker image prune -f
echo "部署完成"

添加DockerFile和docker-compose.yml 配置文件

在github上代码拉取下来后进行部署

FROM node:18
WORKDIR /app
COPY ../package*.json ./
RUN npm install
COPY ../ .
EXPOSE 3000
CMD ["node", "app.js"]
version: '3.8'

services:
  nodeapp:
    build:
      context: ..
      dockerfile: ci/Dockerfile
    container_name: nodeapp
    restart: always
    expose:
      - "3000"
    environment:
      - PORT=3000
      - NODE_ENV=production
      - MONGODB_URI=mongodb://mongo:27017/shared_kitchen
      - REDIS_URL=redis://redis:6379
    depends_on:
      - mongo
      - redis

  nginx:
    image: nginx:stable
    container_name: nginx_proxy
    restart: always
    ports:
      - "8080:8080"
    volumes:
      - ./nginx_default.conf:/etc/nginx/conf.d/default.conf:ro
    working_dir: /etc/nginx
    depends_on:
      - nodeapp

  mongo:
    image: mongo:6
    container_name: mongo
    restart: always
    ports:
      - "27017:27017"
    volumes:
      - mongodata:/data/db

  redis:
    image: redis:7
    container_name: redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - redisdata:/data

volumes:
  mongodata:
  redisdata: