使用docker-compose和gitlab-runner 自动部署nestjs项目(不同分支部署不同环境)

392 阅读3分钟

前置说明

  1. dev分支对应dev环境main分支对应prod环境
  2. 因为我有俩服务器所以我是将dev和prod分别部署在两个服务器上
  3. 假设服务器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服务器的注册流程

  1. 在gitlab中进入项目页面然后选择Settings CI/CD
  2. 然后打开runners并点击new project runner
  3. 然后按照要求注册就会得到一串命令

image.png

image.png

image.png

image.png

6.服务器端配合注册runner

  1. 登录服务器后使用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
  1. 进入容器然后输入上面得到的命令
#进入容器
docker exec 容器id /bin/bash
#然后输入上面获取的命令

上面写的dd就对应gitlabci中tags当tags为dd时才会触发这个runner 这是新版的gitlabrunner注册方式。后面的就和gitlab-runner CI/CD +docker-compose自动化部署nestjs项目一样了

总结

  1. 不同分支触发不同runner通过only和tags字段来区分
  2. 在ci文件中通过variables这个字段来添加对应命令的环境变量
  3. 传递到dockerfile文件后判断执行对应的命令