从前端到全栈:搭建Gitlab并实现自动化部署全栈项目

引言

  • 前情提要:上一篇文章介绍了用Jenkins部署一个Node.js + MySQL 后端和两个 Vue.js 前端项目。
  • 使用Gitlab CI/CD: 如果你的公司使用gitlab托管项目,那使用Gitlab自带的ci/cd方案是个自然而然的选择,这篇文章我们来尝试使用它部署我们的全栈项目。

方案设计

1,搭建gitlab服务,把咱们的项目托管到我们自己的gitlab服务上。

2,运行并注册一个gitlab-runner。它负责执行我们的构建部署任务。

3,3个构建任务构建5个容器,如下图展示。

注:gitlab-runner中使用宿主机的dokcer服务,在runner中执行docker命令,就会在宿主机docker服务上生效。

4,容器启动后协同工作。工作方式如下所示。

Gitlab的搭建与配置

1,通过docker运行gitlab容器。我这里配置的网址是116.198.34.49:8080,通过此网址可以访问gitlab服务了。(116.198.34.49是我购买的京东云服务器的ip)

sql 复制代码
docker run --detach \
  --hostname 116.198.34.49 \
  --publish 8080:80 \
  --name gitlab \
  --restart always \
  --volume /srv/gitlab/config:/etc/gitlab \
  --volume /srv/gitlab/logs:/var/log/gitlab \
  --volume /srv/gitlab/data:/var/opt/gitlab \
  gitlab/gitlab-ee:latest

user = User.find_by(username: 'root')
user.pass123word = 'c31415926'
user.pass123word_confirmation = 'c31415926'
user.save!

2,启动gitlab容器后,需要设置root用户密码

ini 复制代码
// 在容器中执行脚本
user = User.find_by(username: 'root')
user.pass123word = '你的密码'
user.pass123word_confirmation = '你的密码'
user.save!

3,访问网址116.198.34.49:8080,输入root用户名和密码。可以看到我们成功搭建的gitlab!

4,如同我们平时使用公司的gitlab,注册一个用户。在这个用户上新建我们的3个项目,分别是cms-web-vue(vuejs项目)、cms-front-vue(vuejs项目)、cms-server-node(nodejs项目)。下面看到的是我将自己的项目托管到了自己搭建的gitlab上。

gitlab-runner的运行与注册

运行:

ruby 复制代码
// 运行一个容器来托管 GitLab Runner。你需要提供注册令牌和 GitLab 实例的 URL。
docker run -d --name gitlab-runner --restart always \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

注册:

arduino 复制代码
进入 Runner 容器:
docker exec -it gitlab-runner bash
注册 Runner:
gitlab-runner register

系统会提示你输入一些信息:

  • GitLab 实例 URL :输入你的 GitLab 实例的 URL,我的是http://116.198.34.49:8080/
  • 注册令牌:输入项目或实例的注册令牌。这个令牌可以在 GitLab 项目的设置页面下的 CI/CD 部分找到,或者在管理设置中找到(如果你是管理员并希望注册共享 Runner)。
  • Runner 描述 :输入一个描述,用于识别这个 Runner,例如docker-runner
  • Runner 标签 :输入标签,用于标记 Runner 的用途或能力,例如docker。可以输入多个标签,用逗号分隔。
  • 执行器类型 :选择执行器类型。对于 Docker 容器,选择docker作为执行器。

3个构建任务的编写

以上配置好了gitlab和gitlab-runner。接下来编写每个项目的.gitlab-ci.yml文件。

cms-web-vue/.gitlab-ci.yml

yaml 复制代码
stages:
  - build
  - deploy

build:
  stage: build
  script:
    - docker build -t cms-frontend-web:latest .

deploy:
  stage: deploy
  script:
    # 停止并删除旧容器(如果存在)
    - |
      if [ $(docker ps -aq -f name=cms-frontend-web) ]; then
        docker stop cms-frontend-web
        docker rm cms-frontend-web
      else
        echo "No existing container to stop or remove."
      fi
    # 运行新的 Docker 容器
    - docker run -d --name cms-frontend-web --network my-custom-network cms-frontend-web:latest

每次推送代码到 GitLab 仓库时,自动构建一个新的 Docker 镜像cms-frontend-web,然后用它来替换现有的运行中的容器。

cms-front-vue/.gitlab-ci.yml

yaml 复制代码
stages:
  - build
  - deploy

build:
  stage: build
  script:
    - docker build -t cms-frontend-manage:latest .

deploy:
  stage: deploy
  script:
    # 停止并删除旧容器(如果存在)
    - |
      if [ $(docker ps -aq -f name=cms-frontend-manage) ]; then
        docker stop cms-frontend-manage
        docker rm cms-frontend-manage
      else
        echo "No existing container to stop or remove."
      fi
    # 运行新的 Docker 容器
    - docker run -d --name cms-frontend-manage --network my-custom-network cms-frontend-manage:latest

与cms-frontend-web项目类似,不多赘述。

cms-server-node/.gitlab-ci.yml

bash 复制代码
stages:
  - prepare
  - build_nginx
  - build_mysql
  - build_image
  - run_container

prepare:
  stage: prepare
  script:
    # 创建目标目录
    - mkdir -p /etc/gitlab-runner/$CI_PROJECT_DIR
    # 拷贝 nginx.conf 到目标目录
    - cp $CI_PROJECT_DIR/nginx.conf /etc/gitlab-runner/$CI_PROJECT_DIR/nginx.conf
    # 拷贝 backup.sql 到目标目录
    - cp $CI_PROJECT_DIR/db/backup.sql /etc/gitlab-runner/$CI_PROJECT_DIR/backup.sql

build_and_run_nginx:
  stage: build_nginx
  script:
    - if [ $(docker ps -a -q -f name=my-nginx) ]; then docker stop my-nginx && docker rm my-nginx; fi
    - docker run -d --name my-nginx -p 80:80 -v /srv/gitlab-runner/config/$CI_PROJECT_DIR/nginx.conf:/etc/nginx/nginx.conf:ro --network my-custom-network nginx:latest

build_and_run_mysql:
  stage: build_mysql
  script:
    - if [ $(docker ps -a -q -f name=my-mysql) ]; then docker stop my-mysql && docker rm my-mysql; fi
    - docker run -d --name my-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=12345678 -e MYSQL_DATABASE=cms -e MYSQL_USER=admin -e MYSQL_PASSWORD=12345678 -v mysql-data:/var/lib/mysql -v /srv/gitlab-runner/config/$CI_PROJECT_DIR/backup.sql:/docker-entrypoint-initdb.d/backup.sql:ro --network my-custom-network mysql:8.0

build_docker_image:
  stage: build_image
  script:
    - docker build -t cms-server-node:latest .

run_docker_container:
  stage: run_container
  script:
    - docker stop cms-server-node || true
    - docker rm cms-server-node || true
    - docker run -d --name cms-server-node --network my-custom-network cms-server-node:latest

脚本各阶段详细说明

Prepare:

  • 创建目标目录
    • 创建一个目录/etc/gitlab-runner/$CI_PROJECT_DIR,用于存放配置文件。
  • 拷贝配置文件
    • nginx.confbackup.sql文件从项目目录拷贝到目标目录中。这些文件将用于配置 Nginx 和初始化 MySQL 数据库。

Build and Run Nginx

  • 检查并清理旧容器
    • 如果名为my-nginx的容器存在,则停止并删除它。
  • 运行新容器
    • 启动一个新的 Nginx 容器,绑定到端口 80,并将nginx.conf挂载到容器中。
    • 容器连接到my-custom-network网络,以便与其他服务通信。

Build and Run MySQL

  • 检查并清理旧容器
    • 如果名为my-mysql的容器存在,则停止并删除它。
  • 运行新容器
    • 启动一个新的 MySQL 容器,绑定到端口 3306。
    • 设置 MySQL 的根密码、数据库名称、用户和用户密码。
    • backup.sql文件挂载到容器中,以便在启动时初始化数据库。
    • 使用 Docker 卷mysql-data持久化数据库数据。
    • 容器连接到my-custom-network网络。

Build Docker Image

  • 构建自定义 Docker 镜像
    • 使用当前目录中的 Dockerfile 构建一个名为cms-server-node:latest的 Docker 镜像。

Run Docker Container

  • 检查并清理旧容器
    • 停止并删除名为cms-server-node的容器(如果存在)。
  • 运行新容器
    • 启动一个新的容器,使用刚刚构建的cms-server-node:latest镜像。
    • 容器连接到my-custom-network网络。

gitlab ci/cd不需要像Jenkins还要配置webpack,直接在项目的build选项卡下可以看到,代码推送即触发构建部署。如下图:

总结

在这篇文章中,我们实践了使用 GitLab 搭建环境,并利用其自带的 CI/CD 功能来实现全栈项目的部署。在这段时间中,我们尝试了通过 Docker 部署前后端项目,并使用 Jenkins 和 GitLab CI 进行持续集成。关于全栈项目部署的探索,我计划暂时告一段落。接下来,我将尝试更多有关前端全栈的工程化探索。

相关推荐
zeijiershuai1 分钟前
Vue框架
前端·javascript·vue.js
hasnum3 分钟前
探索 GitLab-Connect:一个连接 GitLab 的轻量级工具
gitlab
写完这行代码打球去3 分钟前
没有与此调用匹配的重载
前端·javascript·vue.js
华科云商xiao徐4 分钟前
使用CPR库编写的爬虫程序
前端
狂炫一碗大米饭6 分钟前
Event Loop事件循环机制,那是什么事件?又是怎么循环呢?
前端·javascript·面试
IT、木易8 分钟前
大白话Vue Router 中路由守卫(全局守卫、路由独享守卫、组件内守卫)的种类及应用场景
前端·javascript·vue.js
顾林海8 分钟前
JavaScript 变量与常量全面解析
前端·javascript
程序员小续8 分钟前
React 组件库:跨版本兼容的解决方案!
前端·react.js·面试
乐坏小陈10 分钟前
2025 年你希望用到的现代 JavaScript 模式 【转载】
前端·javascript
生在地上要上天10 分钟前
从600行"状态地狱"到可维护策略模式:一次列表操作限制重构实践
前端