【CI/CD】docker + Nginx自动化构建部署

CI/CD是什么

CI/CD 是持续集成(Continuous Integration)和持续部署(Continuous Deployment)或持续交付(Continuous Delivery)的缩写,它们是现代软件开发中用于自动化软件交付过程的实践。

1、持续集成(CI):指的是开发人员频繁(通常是每天多次)将代码变更合并到共享仓库中的实践。每次代码提交后,自动执行构建和测试,以尽早发现并解决集成错误,提高软件质量。

2、持续交付(CD - Continuous Delivery):在持续集成的基础上,自动将代码变更部署到更接近生产环境的测试环境中,以便进行更深入的测试和验证。持续交付确保软件可以随时被部署到生产环境中,但最终的部署动作可能需要手动触发。

3、持续部署(CD - Continuous Deployment):是持续交付的进一步实践,它指的是每当代码变更通过所有的测试阶段后,自动部署到生产环境中。这意味着软件的新版本可以快速且频繁地部署到生产环境中。

CI/CD 的目标是通过自动化测试和部署流程,减少软件开发和发布过程中的手动错误,提高开发效率和软件质量。这通常需要使用专门的工具和平台,如 Jenkins、Travis CI、CircleCI、GitLab CI/CD 和 GitHub Actions 等。

也就是说,我们可以通过我们的git版本控制平台如GitLab CI/CD、GitHub Actions、Gitea Actions等自动化执行某些操作(打包测试、部署、数据库版本控制的验证等),设置触发时机,每次PR时都会触发,便于提前暴露问题,提高效率等

怎么做

这里以GitHub Actions为例,其他的也都类似 GitHub Actions官网

GitHub Actions 的工作流配置文件使用 YAML(.yml 或 .yaml)格式。这些文件位于 GitHub 仓库的 .github/workflows 目录下。在这些 YAML 文件中,你可以定义事件触发器、作业、步骤以及每个步骤使用的动作。

运行器

附位置 =》 运行器

触发

仅列举常用的 附位置 =》 触发工作流

触发方式 说明
pull_request 创建合并请求时,此合并中的所有修改提交都会触发,不包括合并其他分支到主分支
push 每次提交修改到远程分支时触发,包括合并其他分支到主分支

区别

其实二者的触发方式差不多,只不过范围不同,所以使用push时谨慎触发的条件

可以通过限制分支branch、标签tags、更改的文件路径path等

bash 复制代码
name: CI
on:
  push:
     ## 以下两个条件是或的关系 
    branches: 
      - master ## 只push到master分支时触发
    tags:
      - v**  ## 标签为以v打头的push触发
    path:
      - src/main/**  ## push的更改文件路径包含src/main下的文件时触发

格式

创建目录文件 .github/workflows/build.yaml,设置工作流触发时机为pull_request即创建合并请求后执行

bash 复制代码
name: CI  ## 工作流名称
## 工作流的触发时机
on: pull_request  ## 仅在PR(合并请求)触发    

## 作业(任务)
jobs:
  continuous_build: ## 作业名称
    runs-on: ubuntu-latest   ## 运行器环境

    steps: ## 作业步骤
      - name: test
      	run: echo "this is a test step" 

注意github actions 工作流中不允许使用中文

情景示例

此情景只适用于测试环境,所以只打包构建到自己的docker hub中。不可用于生产环境,生产环境的配置更复杂,感兴趣的可以了解CI/CD + k8s + rancher

1、在 合并请求 的生命周期,通过自动化工作流提前做一些测试

目标

在创建合并请求后,在合并之前,每次更改推送都自动执行打包测试(还可以执行 npm run test)

在这之前,由于Gihub Actions具有隔离性,运行在虚拟环境中,每次运行都是在一个干净的环境中开始。所以我们需要在其工作流中做像拉取新项目时的操作如重新npm i

创建目录文件 .github/workflows/build.yaml,设置工作流触发时机为pull_request

bash 复制代码
name: CI  
on: [pull_request]  

jobs:
  continuous_build: 
    runs-on: ubuntu-latest   

    steps:
      - name:  test
        run:  echo "this is a test step"
      
      - name: checkout  ## 检出代码
        uses: actions/checkout@v3 ## GitHub 提供用于在工作流中检出仓库

      - name: get-hash ## 计算hash,便于缓存
        uses: seepine/hash-files@v1
        id: get-hash
        with: 
          patterns: |-
            package.json
            package-lock.json

      - name: set cache ## 设置缓存
        id: npm-cache
        uses: actions/cache@v3
        with:
          key: coal-manage-${{ steps.get-hash.outputs.hash }} ## 使用项目名称 + 上一步骤的hash
          path: ${{ github.workspace }}/node_modules    ## 上下文表达式,获取执行的工作目录

      - name: install ## 安装依赖
        if: steps.npm-cache.outputs.cache-hit != 'true' ## 判断缓存
        run: npm i --registry=http://registry.npmmirror.com 
        
      - name: build
        run: npm run build

2、在合并分支到主分支时,通过自动化流程做一些部署

目标

每次合并到主分支或者每次打tag标签发布版本时,通过工作流帮我们打包项目并构建成docker 镜像推送到个人都docker hub中,我们可以直接在本地通过手敲或shell脚本部署。

ps:我也有尝试过直接通过工作流打包然后启动,但是直接访问运行的容器会有一些限制,因为 GitHub Actions 的运行器(runner)是在 GitHub 的虚拟环境中,而不是在本地网络或公开的服务器上。所以需要借助工具或者通过k8s部署,这里暂时不考虑

  • 准备docker/Dockerfile
bash 复制代码
FROM nginx:alpine

COPY dist/ /usr/share/nginx/html/

COPY nginx/nginx.conf /etc/nginx/nginx.conf

EXPOSE 9999
  • 准备docker/nginx.conf配置
bash 复制代码
worker_processes	1;

events {
	worker_connections	1024;
}

http {
	include		/etc/nginx/mime.types;
	default_type	application/octet-stream;

	sendfile	on;

	keepalive_timeout	65;

	server {
		listen	80;
		server_name	localhost;

		location / {
			root	/usr/share/nginx/html;
			index	index.html index.htm;
		}

		error_page	500 502 503 504 /50x.html;
		location = /50x.html {
			root	html;
		}

	}
}
  • 在 Docker Hub 创建访问令牌:

    1) 登录到 Docker Hub

    • 进入 Account Settings(账户设置)

    • 选择 Security(安全)选项卡

    • 创建一个新的 Access Token(访问令牌,需要读写操作)。

    • 记下生成的令牌,因为你将需要它来在 GitHub 中配置凭据。

    2) 在 GitHub 仓库中设置 Secrets

    • 转到你的 GitHub 仓库页面。
    • 选择 Settings(设置)> Secrets(密钥)> Actions(操作)。
    • 点击 New repository secret(新建仓库密钥)按钮。
    • 创建两个密钥:一个用于 Docker Hub 的用户名(例如,DOCKER_USERNAME),另一个用于上一步中生成的访问令牌(例如,DOCKER_PASSWORD)。
  • 创建目录文件 .github/workflows/deploy.yaml,设置触发时机为push master,即当代码被合并到远程仓库时到推送操作执行。

bash 复制代码
name: CI  
on: 
  push:
    branches:
      - main


jobs:
  continuous_build: 
    runs-on: ubuntu-latest   

    steps:
      
      - name: checkout
        uses: actions/checkout@v3 

      - name: get-hash
        uses: seepine/hash-files@v1
        id: get-hash
        with: 
          patterns: |-
            package.json
            package-lock.json

      - name: set cache
        id: npm-cache
        uses: actions/cache@v3
        with:
          key: coal-trade-web-manage-${{ steps.get-hash.outputs.hash }}
          path: ${{ github.workspace }}/node_modules   

      - name: install
        if: steps.npm-cache.outputs.cache-hit != 'true'
        run: npm i --registry=http://registry.npmmirror.com 
      
      - name: build
        run: npm run build
      
      - name: login to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: build and push docker image
        uses: docker/build-push-action@v4
        with:
          context: . ## 执行上下文
          file: docker/Dockerfile  ## Dockerfile路径
          push: true  ## 是否推送
          tags: ${{ secrets.DOCKER_USERNAME }}/my-dockerfile-nginx:${{ github.ref_name }}   ## 标签 docker hub username/镜像名称:版本号(git tag打的标签,不打就是分支名)

合并到主分支、每次打tag标签推送都会执行,执行成功后会显示✅

  • 可以登录自己的docker hub查看

  • 登录docker hub将镜像拉取到本地,直接运行即可

bash 复制代码
docker login
# 根据提示输入用户名、密码

docker pull  <username>/<image name>:<tag>

启动成功返回容器id

bash 复制代码
# 本地9090端口(访问端口)映射 容器内的端口
docker run --name <container name> -p 9090:80 -d <username>/<image name>:<tag>

直接访问本地虚拟机ip+端口

相关推荐
BUTCHER56 小时前
Docker镜像使用
java·docker·容器
小趴菜吖6 小时前
使用macvlan实现容器的跨主机通信
docker
无敌糖果6 小时前
K8S的Helm包管理器
docker·容器·kubernetes·helm·helm安装包
筱小虾米6 小时前
Docker配置国内镜像源
运维·docker·容器
开挖掘机上班9 小时前
基于Alpine构建MySQL镜像
mysql·docker·容器
todoitbo9 小时前
docker搭建freeswitch实现点对点视频,多人视频
docker·容器·音视频·freeswitch·视频聊天
William一直在路上11 小时前
回顾一下Docker的基本操作
docker·容器·eureka
赵成ccc12 小时前
如何进行 Docker 数据目录迁移
docker·容器·eureka
康闯12 小时前
Docker 部署emberstack/sftp 镜像
java·docker·容器
小阿技术12 小时前
本地电脑安装Dify|内网穿透到公网
人工智能·计算机视觉·docker·目标跟踪·flask·dify