从前端到全栈:搭建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 进行持续集成。关于全栈项目部署的探索,我计划暂时告一段落。接下来,我将尝试更多有关前端全栈的工程化探索。

相关推荐
LXY2023050439 分钟前
css三角图标
前端·javascript·css
spring_007_9991 小时前
在uniapp中修改打包路径
前端·uni-app
cheese-liang1 小时前
Excel中Address函数的用法
前端·excel
prince_zxill1 小时前
JavaScript 中的 CSS 与页面响应式设计
前端·javascript·css·前端框架·html
林涧泣2 小时前
【Uniapp-Vue3】获取用户状态栏高度和胶囊按钮高度
前端·vue.js·uni-app
领秀58583 小时前
我问了DeepSeek和ChatGPT关于vue中包含几种watch的问题,它们是这么回答的……
前端·javascript·vue.js
三原3 小时前
vue3实现可以拖动的弹窗组件, 做这个组件可以学习到什么?
前端·javascript·vue.js
16年上任的CTO3 小时前
vue2-mixin的定义与和使用
前端·javascript·vue.js·mixin
呦呦鹿鸣Rzh3 小时前
HTML-表格,表单标签
java·前端·html