引言
- 前情提要:上一篇文章介绍了用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.conf
和backup.sql
文件从项目目录拷贝到目标目录中。这些文件将用于配置 Nginx 和初始化 MySQL 数据库。
- 将
Build and Run Nginx
- 检查并清理旧容器:
-
- 如果名为
my-nginx
的容器存在,则停止并删除它。
- 如果名为
- 运行新容器:
-
- 启动一个新的 Nginx 容器,绑定到端口 80,并将
nginx.conf
挂载到容器中。 - 容器连接到
my-custom-network
网络,以便与其他服务通信。
- 启动一个新的 Nginx 容器,绑定到端口 80,并将
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 镜像。
- 使用当前目录中的 Dockerfile 构建一个名为
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 进行持续集成。关于全栈项目部署的探索,我计划暂时告一段落。接下来,我将尝试更多有关前端全栈的工程化探索。