前后端分离的架构下,前后端分别的CI/CD全流程-后端-1

274 阅读6分钟

首先是技术栈选择。 后端框架我选择了nodejs的koa框架,数据库使用了mysql(其实再加上一个redis也是同理)

搭建koa项目

确认了技术栈后我们先起个项目,起个koa的项目很简单,这里就不介绍流程了

项目搭建完后我们需要在项目根目录下写一个Dockerfile文件,用来构建koa项目的镜像。

# 制定node镜像的版本
FROM node:16.9.1
# 移动当前目录下面的文件到app目录下
ADD . /app/
# 进入到app目录下面,类似cd
WORKDIR /app
# 设置淘宝镜像 && 安装依赖 && build代码
RUN npm config set registry http://registry.npm.taobao.org && npm install && npm run build
# 对外暴露的端口,这里的3000需要和inde.js监听的端口一致
EXPOSE 3000
# 程序启动脚本,意思为 执行 npm start
CMD ["npm", "start"]

这一步完成后我们就可以在根目录下docker build . 打包这个koa项目镜像测试一下

  • 首先我们docker images一下,看一下目前docker镜像都有哪些
  • 然后在根目录下docker build .
  • image-20220202155130851.png
  • build完后我们可以再次docker images看一下
  • image-20220202155807307.png
  • 可以看到我们已经构建了一个没有命名没有版本的镜像
  • 接下来我们可以给我们的镜像命名(方便后续docker命令,就可以不用每次复制镜像id号了), docker tag 镜像id 自定义名称:自定义版本号
  • image-20220202160056880.png
  • 可以看到这样我们就构建了一个名叫server 版本号为1的镜像
  • 然后我们就可以run一下我们构建好的镜像测试一下
  • docker run --name 自定义名称 -d(代表后台运行) -it(以交互模式运行容器并为容器重新分配一个伪输入终端) -p(将容器内的xxx端口映射至宿主机的xxx端口) 3000:3000 server:1(使用server镜像的1版本)
  • 执行完后我们就可以在宿主机查看一下该端口号是否已经被占用,mac linux可以使用lsof(linux没有lsof的话可以装一个 yum/apt-get update 然后 yum/apt-get install lsof) lsof -i:3000
  • image-20220202161251769.png
  • 可以看到我们宿主机上的3000端口号已经被docker容器占用
  • 现在我们可以进入容器内看一下项目文件是否被正确打包进去
  • docker exec(docker exec的意思是在运行的容器中执行命令) -it(即使没有附加也保持STDIN 打开,分配一个伪终端) server(容器名称) /bin/bash(以/bin/bash的指令模式执行shell命令)
  • image-20220202161828198.png
  • 可以看到我们的项目确实被正确打包到了容器内的app目录下

测试到我们的dockerfile文件构建出来的镜像没有问题,接下来我们就可以使用docker-compose来同时启动我们的koa项目和mysql

在这一步前需要在koa项目中连接好数据库

image-20220202162212981.png

host先设置为db或其他自定义的名字就可以,我这里是做了一个监测当前环境是否是容器的判断,如果我的koa项目没有在docker容器下运行则使用本地的mysql

设置好后我们在项目根目录下创建一个docker-compose.yml文件

version: "3"
services:
  server:
    build:
      dockerfile: Dockerfile
      context: .
    image: server
    volumes: # 这个磁盘挂载不用写,这是我项目中做图片上传后映射到服务器上用的
      - ../img:/app/img
    ports:
      - "3000:3000"
    links: # 重点为这里,我们把mysql重命名为db或者其他名字,就是我们koa项目里host里填写的名字
      - mysql:db
    depends_on: # 这里为设置server容器的依赖
      - mysql
  mysql:
    image: mysql/mysql-server:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "数据库root用户的密码"
      MYSQL_USER: "要登录的数据库的账号,这里我们使用root登录就可以"
      MYSQL_PASS: "root用户的密码"
    expose: # 将本容器内的3306端口暴露
      - "3306"
    privileged: true
    volumes: # 磁盘挂载
      - ./db:/var/lib/mysql # 这里注意,在根目录目录下创建一个db空文件夹,每次docker-compose运行时,如果你需要重新初始化mysql的话需要把db文件夹目录下的文件都清空,否则mysql不会初始化
      - ./init:/docker-entrypoint-initdb.d/ # mysql初始化时会执行这个文件夹下的init.sql
    ports:
      - "3307:3306" # 这里把3306映射到3307是因为,我把两个容器cicd到远程服务器后,我本地机器想连接远程服务器的话可以通过3307连接,就不需要把本地的数据库停掉了。否则每次连接远程服务器的数据库还需要把本地mysql停掉
    command: [
        'mysqld',
        '--innodb-buffer-pool-size=80M',
        '--character-set-server=utf8mb4',
        '--collation-server=utf8mb4_unicode_ci',
        '--default-time-zone=+8:00',
        '--lower-case-table-names=1',
        '--max_allowed_packet=100M',
        '--default-authentication-plugin=mysql_native_password'
    ]
​

可能有同学会比较好奇,为什么我们设置了一个expose暴露3306端口,又设置一个ports暴露端口,有什么区别吗。 这里我们简单讲一下两者的区别

  • prots

    • ports暴露容器端口到主机的任意端口或指定端口,用法:
    • ports:
        - "80:80"         # 绑定容器的80端口到主机的80端口
        - "9000:80"       # 绑定容器的80端口到主机的9000端口
        - "443"           # 绑定容器的443端口到主机的任意端口,容器启动时随机分配绑定的主机端口号
      
    • 不管是否指定主机端口,使用ports都会将端口暴露给主机和其他容器
  • expose

    • expose暴露容器给link到当前容器的容器,或者暴露给同一个networks的容器,用法:
    • expose:
        - "3000"
        - "8000"
      
    • 以上指令将当前容器的端口30008000暴露给其他容器
    • ports的区别是, expose不会将端口暴露给主机,主机无法访问expose的端口。

init.sql

use mysql;
update user set host = '%' where user = 'root';
select host, user from user;
CREATE DATABASE `koa` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 创建要用的库
flush privileges;
use koa;
CREATE TABLE `user_info` ( # 创建表 内容按自己需要的写
                             `id` int NOT NULL AUTO_INCREMENT,
                             `create_time` timestamp NOT NULL,
                             `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
                             `username` varchar(255) NOT NULL,
                             `password` varchar(255) NOT NULL,
                             `nickname` varchar(255) DEFAULT NULL,
                             `sex` varchar(255) DEFAULT NULL,
                             `signature` varchar(255) DEFAULT NULL,
                             PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb3;
​
# 插入一条数据,可以不写
INSERT INTO `user_info` (`id`, `create_time`, `update_time`, `username`, `password`, `nickname`, `sex`, `signature`) VALUES (10, '2022-01-14 21:32:37', '2022-01-14 21:32:58', '123', '123', NULL, NULL, NULL);
​

然后我们就可以测试一下了

  • 在根目录下运行 docker-compose pull 先下载容器依赖的镜像
  • 然后docker-compose up --force-recreate -d
  • 耐心等待,完成后我们可以docker ps查看一下在运行中的docker容器
  • image-20220202164747621.png
  • 之后我们就可以用insomnia(或者其他api测试工具如postman)测试一下我们的koa项目是否能正常使用

接下来我们就可以准备用jenkins来做CI/CD了!