前置说明
- dev分支对应dev环境main分支对应prod环境
- 因为我有俩服务器所以我是将dev和prod分别部署在两个服务器上
- 假设服务器A的域名为1.1.1.1。服务器B的域名为2.2.2.2
1.编写.gitlab-ci.yml文件
image: docker:latest
services:
- docker:dind
stages:
- build
build_summer:
stage: build
variables:
RUNNING: dev
script:
- docker-compose up -d --build
environment:
name: dev
url: http://liosummer.cn
tags:
- dd
only:
- dev
interruptible: true
build_blog:
stage: build
variables:
RUNNING: prod
script:
- docker-compose up -d --build
environment:
name: main
url: http://lioblog.cn
tags:
- dd2
only:
- main
interruptible: true
文件说明:
我只定义了一个job但是触发条件对应不同的分支和不同的runner这两个任务的区别就只有RUNNING环境不同 主要都是会触发docker-compose up -d --build并自动将RUNNING带入docker-compose
2.编写docker-compose.yml文件
version: "3.0"
services:
mysql02:
container_name: mysql02
image: mysql:8.0 # 使用官方镜像
ports:
- 3306:3306 # 本机端口:容器端口
restart: on-failure
environment:
MYSQL_DATABASE: dd
MYSQL_ROOT_PASSWORD: 123456
MYSQL_USER: lio
MYSQL_PASSWORD: 123456
MYSQL_ROOT_HOST: '%'
volumes:
- /home/mysql/db:/var/lib/mysql # 用来存放了数据库表文件
networks:
- mysql02_bridge
dd_server:
# nestjs服务
container_name: dd_server
build:
# 根据Dockerfile构建镜像
context: .
dockerfile: Dockerfile
args:
RUNNING: ${RUNNING}
environment:
- RUNNING=${RUNNING}
ports:
- 3700:3700
- 4000:4000
restart: on-failure # 设置自动重启,这一步必须设置,主要是存在mysql还没有启动完成就启动了node服务
networks:
- mysql02_bridge
depends_on:
# node服务依赖于mysql和redis
- mysql02
# 声明一下网桥 mysql02_bridge。
# 重要:将所有服务都挂载在同一网桥即可通过容器名来互相通信了
# 如nestjs连接mysql可以通过容器名来互相通信
networks:
mysql02_bridge:
文件说明
启动了两个容器一个是mysql的一个是后端服务的,因为我的服务使用了socket所以暴露两个端口(3700,4000)并在dd_server中将RUNNING变量传入Dockerfile
3.编写Dockerfile文件
FROM node:18.16.0
ARG RUNNING
# 设置时区
ENV TZ=Asia/Shanghai DEBIAN_FRONTEND=noninteractive
ENV RUNNING $RUNNING
# 创建工作目录
RUN mkdir /app
# 指定工作目录
WORKDIR /app
# 复制当前所有代码到/app工作目录
COPY . .
#install
RUN yarn
# 打包
RUN yarn build
RUN echo $RUNNING
# 运行
CMD if [ -z "$RUNNING" ] ; then echo '未传递环境变量'; else yarn run:$RUNNING; fi
#暴露端口3700(与服务启动端口一致)
EXPOSE 3700
EXPOSE 4000
文件说明
这里就是普通的一些命令先拷贝文件到/app(工作目录)然后install。build 然后根据RUNNING来跑不同的运行命令
4.修改package.json文件启动命令
"run:dev":"cross-env NODE_ENV=dev node dist/main.js",
"run:prod":"cross-env NODE_ENV=prod node dist/main.js",
文件说明
这两个命令就是最后的运行命令
5.注册runner
这里两个服务器的注册流程基本相同就只演示A服务器的注册流程
- 在gitlab中进入项目页面然后选择Settings CI/CD
- 然后打开runners并点击new project runner
- 然后按照要求注册就会得到一串命令
6.服务器端配合注册runner
- 登录服务器后使用docker部署一个runner容器
docker run -d -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock -v /builds:/builds gitlab/gitlab-runner:alpine
- 进入容器然后输入上面得到的命令
#进入容器
docker exec 容器id /bin/bash
#然后输入上面获取的命令
上面写的dd就对应gitlabci中tags当tags为dd时才会触发这个runner 这是新版的gitlabrunner注册方式。后面的就和gitlab-runner CI/CD +docker-compose自动化部署nestjs项目一样了
总结
- 不同分支触发不同runner通过only和tags字段来区分
- 在ci文件中通过
variables这个字段来添加对应命令的环境变量 - 传递到dockerfile文件后判断执行对应的命令