Github Action + docker 实现自动化部署

当一个项目开发完,需要部署到服务器时,如果直接在服务器上拉取代码、打包运行,就需要服务器环境与本地保持一致,不然就会出现本地能跑服务器跑不了的情况,想想就让人头疼。

使用docker部署就不需要再为环境考虑了,还支持版本管理,并且还有docker-compose等编排工具提供多容器的统一管理。使用docker部署仅需三步:

  1. 打包镜像
  2. 发布镜像
  3. 拉取镜像并执行

下面就以一个前端Vue项目为例,用 Github Actoin 来实现docker的自动部署流程。

编写Dockerfile

首先要为项目编写Dockerfile,前端通常使用nginx进行部署:

bash 复制代码
FROM node:18.20-alpine3.21 as build-stage

WORKDIR /app

COPY package.json .

# 配置npm和pnpm
RUN npm config set registry https://registry.npmmirror.com/
RUN npm install pnpm -g
RUN pnpm config set registry https://registry.npmmirror.com/
RUN pnpm install

COPY . .

RUN pnpm build

# production stage
FROM nginx:stable as production-stage

COPY --from=build-stage /app/dist /usr/share/nginx/html

EXPOSE 443

CMD ["nginx", "-g", "daemon off;"]

这里采用分阶段打包,只需要将dist打进镜像,放入到nginx的资源目录下,暴露443端口(如果不是https就配置80端口)并设置nginx启动指令。Dockerfile的编写很简单,直接交给GPT生成即可。

编写发布docker脚本(可选)

镜像仓库的地址可能会比较长,所以打包、发布的指令也会很长,写个shell脚本自动执行这两个步骤比较省事:

bash 复制代码
# 先构建镜像并打标签
docker build -t registry.xxx.com/xxx/xxx:latest . || {
  echo "Docker构建失败"
  exit 1
}

# 检查镜像是否存在
docker images | grep registry.xxx.com/xxx/xxx:latest || {
  echo "构建的镜像不存在"
  exit 1
}

# 推送镜像
docker push registry.xxx.com/xxx/xxx:latest || {
  echo "Docker推送失败"
  exit 1
}

仓库地址替换为最终要上传的镜像仓库地址,例如dockerhub或阿里云镜像仓库等。

编写workflow

要触发github action只需要在项目根目录下 .github/workflows 文件夹里添加对应的流程配置文件,这里我们添加一个deploy.yml配置:

yml 复制代码
name: Deploy Frontend to Server

on:
  push:
    branches:
      - release # 当代码推送到 release 分支时触发

jobs:
  build-and-push:
    name: Build and Push Docker Image
    runs-on: ubuntu-latest # 使用最新的 Ubuntu Runner
    steps:
      - name: Checkout code
        uses: actions/checkout@v4 # 检出你的代码

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3 # 设置 Docker Buildx 以便构建镜像

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: registry.xxx.com # 你的镜像仓库地址
          username: ${{ secrets.DOCKER_USERNAME }} # 从 GitHub Secrets 读取 Docker 用户名
          password: ${{ secrets.DOCKER_PASSWORD }} # 从 GitHub Secrets 读取 Docker 密码

      - name: Build and push Docker image using deploy.sh
        run: |
          chmod +x ./deploy.sh # 赋予 deploy.sh 执行权限
          ./deploy.sh # 执行构建和推送脚本
        shell: bash # 指定使用 bash shell

  deploy-remote:
    name: Deploy to Remote Server
    runs-on: ubuntu-latest
    needs: build-and-push # 依赖于 build-and-push 任务成功完成
    steps:
      - name: Deploy to Remote Server via SSH
        uses: appleboy/ssh-action@master # 使用社区提供的 SSH Action
        with:
          host: ${{ secrets.REMOTE_HOST }} # 从 GitHub Secrets 读取远程服务器 IP 或主机名
          username: ${{ secrets.REMOTE_USER }} # 从 GitHub Secrets 读取远程服务器登录用户名
          key: ${{ secrets.SSH_PRIVATE_KEY }} # 从 GitHub Secrets 读取 SSH 私钥
          script: |
            echo "Connecting to remote server..."
            # 进入 docker-compose.yml 文件所在的目录
            cd /root/deploy
            echo "Pulling latest image..."
            docker-compose pull frontend || { echo "Docker Compose pull failed"; exit 1; }
            echo "Starting container..."
            docker-compose up -d --no-deps frontend || { echo "Docker Compose up failed"; exit 1; }
            echo "Deployment successful!"

示例中使用docker-compose管理前后端docker服务,需要配置docker-compose.yml。也可以直接使用docker管理单个容器。

例如私钥、密码等重要信息不要明文写在配置中,github action提供secrets变量存储,将重要信息保存在这里,通过secrets访问:

ssl登录服务器有两种方式,可以通过密码登录,也可以通过密钥登录。推荐使用密钥登录,明文保存密码不太安全。

密钥登录需要通过ssh-keygen生成一个密钥对,公钥存放到服务 ~/.ssh/authorized_keys 文件中(一行一个密钥),没有这个文件就自己创建一个,私钥就存放在secrets中。这个配置是不是似曾相识,其实就是本地与github通讯配置的ssh key,所以这里可以复用已有的ssh key,将公钥 ~/.ssh/id_dsa.pub 内容复制到上面提到的authorized_keys文件中,私钥 ~/.ssh/id_dsa 内容复制粘贴到secrets.SSH_PRIVATE_KEY中即可。

到这里配置就结束了,提交点内容到release分支测试下,看对应的工作流是否跑通。

相关推荐
BillKu5 分钟前
Vue3 + Element Plus 中修改表格当前选中行的颜色
前端·vue.js·elementui
BillKu33 分钟前
Axios中POST、PUT、PATCH用法区别
前端·vue.js
好奇的菜鸟2 小时前
掌握 npm 核心操作:从安装到管理依赖的完整指南
前端·npm·node.js
肥肠可耐的西西公主3 小时前
前端(小程序)学习笔记(CLASS 2):WXML模板语法与WXSS模板样式
前端·学习·小程序
逆袭的菜鸟X4 小时前
RxJS 高阶映射操作符详解:map、mergeMap 和 switchMap
前端
bubiyoushang8884 小时前
HTML5的新语义化标签
前端·html·html5
会飞的鱼先生4 小时前
vue3自定义指令来实现 v-copy 功能
前端·javascript·vue.js
陈天伟教授5 小时前
Web前端开发 - 制作简单的焦点图效果
java·开发语言·前端·前端开发·visual studio
_殊途5 小时前
前端三件套之html详解
前端·html
不思念一个荒废的名字5 小时前
【黑马JavaWeb+AI知识梳理】后端Web基础03 - MySQL概述
前端·数据库·mysql