前端项目使用gitlab-cicd+docker实现自动化部署

GitLab CI/CD 是一个强大的工具,可以实现项目的自动化部署流程,从代码提交到部署只需几个步骤。本文将带你配置 GitLab CI/CD 完成一个前端项目的自动化部署。

前言

为什么使用cicd+docker?

目前我们公司开发环境使用的shell脚本部署,一是要登录服务器,二是要去手动执行脚本,要是部分同事不懂运行脚本的话还得教他,费时费力;但是搭建好了cicd之后只需要提交合并代码就会完成自动化部署不需要人工介入、使用docker是因为可以环境互不干扰(例如node14,node15,node16等不同版本都可以在一台服务器运行)

前置准备

GitLab 仓库 :确保代码已经推送到 GitLab 仓库。
部署服务器 :一台可以通过 SSH 访问的服务器,用于部署你的前端项目。
工具准备 :GitLab Runner、docker
项目文件:.gitlab-ci.yml、Makefile、dockerfile


持续集成 (CI)

持续集成是一种开发实践,开发人员将代码频繁地合并到共享的代码仓库中,通常每天多次。每次代码合并后,都会触发自动化的构建和测试流程。

  • 频繁集成:开发人员定期将新代码合并到主分支。
  • 自动化测试:每次合并都会运行测试,确保新代码不会破坏已有功能。
  • 快速反馈:测试失败或构建失败时立即通知开发者。
  • 发现问题更快,因为每次小的更改都会被立即验证。
  • 减少了"大规模集成"带来的风险和时间消耗。

持续交付 (CD - Continuous Delivery)

持续交付是在持续集成的基础上,进一步自动化了将软件交付到生产环境之前的所有流程。代码在通过构建和测试后,自动部署到一个可运行的环境(通常是预发布环境),但部署到生产仍需要手动触发。

  • 自动化部署:代码经过验证后可以自动部署到预发布环境。
  • 人为审核:生产环境的部署通常需要手动批准。
  • 可随时交付:开发团队确保软件在任何时间点都可以部署到生产。
  • 缩短了发布周期。
  • 提高了软件交付的可靠性和稳定性。
  • 可轻松在不同环境(如开发、测试、预生产)中验证软件。

持续部署 (CD - Continuous Deployment)

持续部署是持续交付的进一步延伸,完全自动化了整个交付过程。通过所有测试的代码会自动部署到生产环境,无需人工干预。

  • 全自动化:不需要人为批准,代码直接进入生产环境。
  • 高测试要求:需要非常可靠的自动化测试体系。
  • 快速交付:代码从开发到上线的周期极短。
  • 开发团队可以快速将新功能交付到用户手中。
  • 减少人为操作导致的错误。
  • 提高了产品的敏捷性。

GitLab Runner 是什么?

GitLab Runner 是一个开源的应用程序,用于执行 GitLab CI/CD 中定义的任务(也称为作业)。它是 GitLab CI/CD 的核心组件之一,用于从 GitLab 获取作业、执行作业,并将结果反馈给 GitLab。

GitLab Runner 的功能

执行 CI/CD 流水线作业 :从 .gitlab-ci.yml 文件中获取任务配置并执行。
支持多种执行器 :支持不同的环境运行作业,如 Docker、Shell、Kubernetes 等。
跨平台支持 :可以安装在多种操作系统上,包括 Linux、Windows 和 macOS。
分布式运行 :可以在多个 Runner 上并行执行流水线任务。
负载均衡:当有多个 Runner 注册到 GitLab 项目时,任务会自动分配。

GitLab Runner 安装

GitLab Runner 教程


部署

.gitlab-ci.yml教程

要使用 GitLab CI/CD,您需要:

  • 托管在 Git 仓库中的应用程序代码。
  • 仓库根目录中名为 .gitlab-ci.yml 的文件,其中包含 CI/CD 配置。

这是我自己项目中的.gitlab-ci.yml

yml 复制代码
stages:
  - build # 编译
  # - deploy-dev            # 开发环境
  - deploy-test # 测试环境
  - deploy-online # 上线 - 推送镜像

build-job:
  stage: build
  tags:
    - docker_test
  variables:
    GIT_CLEAN_FLAGS: -ffdx -e node_modules/
  script:
    - echo "Compiling the code..."
    # - make build
    - echo "Compile complete."
  only:
    - test
    # - dev

build-online-job:
  stage: build
  tags:
    - docker_online
  variables:
    GIT_CLEAN_FLAGS: -ffdx -e node_modules/
  script:
    - echo "Compiling the code..."
    # - make build ENV=prod
    - echo "Compile complete."
  only:
    - main

# deploy-dev-job:
#   stage: deploy-dev
#   # environment: production
#   tags:
#     - docker_dev
#   variables:
#     GIT_CLEAN_FLAGS: -ffdx -e dist/ -e node_modules/
#   script:
#     - echo "Deploying application..."
#     - make docker-deploy ENV=dev
#     - echo "Application successfully deployed."
#   only:
#     - dev

deploy-test-job:
  stage: deploy-test
  # environment: production
  tags:
    - docker_test
  variables:
    GIT_CLEAN_FLAGS: -ffdx -e dist/ -e node_modules/
  script:
    - echo "Deploying application..."
    - make docker-deploy ENV=test
    - echo "Application successfully deployed."
  only:
    - test

deploy-online-job:
  stage: deploy-online
  tags:
    - docker_online
  variables:
    GIT_CLEAN_FLAGS: -ffdx -e dist/ -e node_modules/
  script:
    - echo "Compiling the code..."
    - make deploy-online ENV=prod
    - echo "Compile complete."
  only:
    - main

Makefile 是什么?

Makefile 是一种自动化构建工具的配置文件,用于定义如何编译和链接程序以及执行其他任务。它主要用于管理项目中的构建过程,例如将源代码编译为二进制文件。make 工具通过读取 Makefile 来执行任务。

尽管最初是为 C/C++ 项目设计的,Makefile 也可以用于任意任务的自动化,如压缩文件、运行测试、生成文档等。

Makefile教程

这是我自己项目中的Makefile

sh 复制代码
REGISTRY?=www.github.com/xxx
APP=demo
BACKEND_PORT:= 9300
PORT:= 8300
# 获取最近的 Git 标签作为版本号
RAW_VERSION := $(shell git describe --tags --always 2>/dev/null || echo dev)
VERSION := $(shell echo $(RAW_VERSION) | awk -F '-' '{print $$1}')
# 读取 VERSION 文件中的版本号
# version := $(shell cat VERSION 2>/dev/null || echo last)
# 打印版本号
print_version:
    @echo "The version is: $(VERSION)"
HOST := http://xxx.xxx.com
ifeq ($(ENV), dev)
    HOST = xxx.xxx.com
endif
ifeq ($(ENV), test)
    HOST = xxx.xxx.com
endif
ifeq ($(ENV), prod)
    HOST = xxx.xxx.com
endif

IMAGES := ${REGISTRY}/${APP}:${VERSION}
.PHONY: build
## 构建应用
build: clean
	@echo "Building..."
	npm i; npm run build

# 验证环境变量
check-environment:
ifndef ENV
 	$(error ENV not set, allowed values - `staging` or `production`)
endif

.PHONY: docker-build
## 构建docker镜像
docker-build:
	docker build -f Dockerfile2 -t ${IMAGES} .

.PHONY: docker-deploy
## 部署docker容器 - 测试环境
docker-deploy: docker-build
	docker stop ${APP} || true; docker rm ${APP} || true; docker run -p ${PORT}:80 -d -e BACKENDURL="${HOST}:${BACKEND_PORT}/" --name ${APP} ${IMAGES}

.PHONY: deploy-online
## 部署docker容器 - 生产环境
deploy-online: docker-build
	docker stop ${APP} || true; docker rm ${APP} || true; docker run -p ${PORT}:80 -d -e BACKENDURL="${HOST}:${BACKEND_PORT}/" --name ${APP} ${IMAGES}

.PHONY: docker-push
## 推送docker镜像 - 测试环境
docker-push: check-environment
	docker build -f Dockerfile -t ${IMAGES} .
	## docker push ${IMAGES}

.PHONY: help
## 帮助命令
help:
	@echo "Usage: \n"
	@sed -n 's/^##//p' ${MAKEFILE_LIST} | column -t -s ':' |  sed -e 's/^/ /'

Dockerfile

Dockerfile 复制代码
# 编译打包
FROM node:18-alpine as builder
WORKDIR /app
COPY package.json .
ENV NODE_OPTIONS=--openssl-legacy-provider
# RUN npm install
RUN npm config set registry https://registry.npmmirror.com/ && npm install
COPY . .
RUN npm run build

# 运行应用
FROM nginx:latest
COPY --from=builder /app/dist /usr/share/nginx/html
COPY container/nginx.conf.template /etc/nginx/nginx.conf.template
COPY container/init.sh /init.sh
RUN chmod 777 init.sh
EXPOSE 80

CMD ["/bin/bash", "/init.sh"]

dockerfile中包含的文件

container/nginx.conf.template

php 复制代码
user root;
events {
  worker_connections 4096; ## Default: 1024
}

http {
  # 设置超时时间
  proxy_connect_timeout 60s;
  proxy_send_timeout 7200s;
  proxy_read_timeout 7200s;
  client_max_body_size 200M;
  include /etc/nginx/mime.types;
  sendfile on;

  server {
    listen 80;
    listen [::]:80;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers X-Requested-With,access-token,Access-Token,Refresh-Token,Accept,Content-Type,User-Agent;
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

    location / {
      root /usr/share/nginx/html;
      index index.html;
      try_files $uri $uri/ /index.html;
    }
    # sse推送的特定接口的配置
    location /api/admin/channelAccount/getMetrics {
      rewrite ^/api/(.*)$ /$1 break;  # 去除 /api 前缀
      proxy_pass $BACKENDURL; #后端实际服务器地址
      proxy_http_version 1.1;
      proxy_buffering off;
      proxy_cache off;
      chunked_transfer_encoding off;
    }
    location ^~/api/ {
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-NginX-Proxy true;
      proxy_pass $BACKENDURL; #后端实际服务器地址
      add_header Access-Control-Allow-Origin *;
      add_header Access-Control-Allow-Headers X-Requested-With,access-token,Access-Token,Refresh-Token,Accept,Content-Type,User-Agent;
      add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
    }
  }
}

container/init.sh

sh 复制代码
#!/bin/bash
BACKENDURL=$BACKENDURL
export "BACKENDURL"=$BACKENDURL
envsubst '$BACKENDURL' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf && nginx -g 'daemon off;'

gitlab创建runner

新建runner


服务器执行命令、执行器选择shell

sh 复制代码
gitlab-runner register  --url https://gitlab.xxx.com  --token glrt-t3_zBQiLoAqysRDEgfiexUZ --executor "shell"

完成

提交代码到test分支后就可以看到构建记录了

相关推荐
!!!52516 分钟前
华为云镜像加速器
docker·容器·华为云
css趣多多1 小时前
案例自定义tabBar
前端
姑苏洛言2 小时前
DeepSeek写微信转盘小程序需求文档,这不比产品经理强?
前端
林的快手3 小时前
CSS列表属性
前端·javascript·css·ajax·firefox·html5·safari
sszdzq3 小时前
Docker
运维·docker·容器
匹马夕阳3 小时前
ECharts极简入门
前端·信息可视化·echarts
dmy3 小时前
docker 快速构建开发环境
后端·docker·容器
API_technology3 小时前
电商API安全防护:JWT令牌与XSS防御实战
前端·安全·xss
yqcoder3 小时前
Express + MongoDB 实现在筛选时间段中用户名的模糊查询
java·前端·javascript
十八朵郁金香4 小时前
通俗易懂的DOM1级标准介绍
开发语言·前端·javascript