Vesper@之一

#

🚀docker-compose自动化部署实践

相信有很多小伙伴有对 Docker 和 docker-compose 的部署有点疑惑,本文会以我自己的一个项目部署案例来讲述。

这是我们的粗略架构:

image

here we go!🚀

💡ps:以下是基于 docker-compose 哟,如果你没有 dockerdocker-compose 的前置知识,请适当了解一下再看,不过相信我,就算你不熟悉,只要你会安装 dockerdocker-compose 就可以,这部分不会请自行google

我用DevOps平台是 gitee

Docker镜像源是 阿里云

记得在开始之前提前安装好你的 dockerdocker-compose,甚至是你的 git 仓库,也请别忘记要打通 gitee 的话,记得去绑定远程实例哟~

正文开始👉


这里给出项目的目录结构:

image

1. 首先在我们的后端项目根目录下创建 Dockerfile📌

配置好我们的 Dockerfile, 以便后续构建 image,配置比较简单我就不多赘述了。 💡ps:注意是在子项目kch-backend根目录里配置哦

FROM node:18

WORKDIR /app

COPY . .

USER root
RUN npm install -g pnpm
RUN pnpm install
RUN npm run build

EXPOSE 3000

CMD ["pnpm", "-F", "kch-backend", "start:prod"]

然后在 Monorepo 的根目录下创建 docker-compose.yml 文件,做如下配置:

version: '3'
services:
  # 给你后端程序定义一个 service name 这个非常重要,后面我会说为什么
  cqbackend1:
    image: registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-backend:latest
    ports:
      - '3000:3000'
    depends_on:
      - db
  # 给你后端程序定义一个 service name 这个非常重要,后面我会说为什么
  cqbackend2:
    image: registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-backend:latest
    ports:
      - '3001:3001'
    depends_on:
      - db
  # 给你后端程序定义一个 service name 这个非常重要,后面我会说为什么
  cqbackend3:
    image: registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-backend:latest
    ports:
      - '3002:3002'
    depends_on:
      - db
  # 给你后端程序定义一个 service name 这个非常重要,后面我会说为什么
  cqbackend4:
    image: registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-backend:latest
    ports:
      - '3003:3003'
    depends_on:
      - db
  # 需要用到 nginx 做负载均衡
  nginx:
    image: nginx
    ports:
      - '81:81'
    # 将当前目录的 nginx.conf 配置文件绑定到镜像中的 /etc/nginx/nginx.conf 上
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    # 等所有项目都部署好了,再进行 nginx 部署
    depends_on:
      - cqapigateway
  cqapigateway:
    image: registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-apigateway:latest
    ports:
      - '80:80'
    depends_on:
      - cqbackend1
      - cqbackend2
      - cqbackend3
      - cqbackend4
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: kch_database
    volumes:
      - db-data:/var/lib/mysql
volumes:
  db-data:

因为用到了 nginx.conf 所以我们还需要在根目录下做如下 nginx 配置,这里各位请按需配置,我只给出的是默认配置:

http {
  upstream app_servers {
    # 之前我说 service name 很重要,就是这里需要通过 name 来访问端口
    server cqbackend1:3000;
    # 之前我说 service name 很重要,就是这里需要通过 name 来访问端口
    server cqbackend1:3001;
    # 之前我说 service name 很重要,就是这里需要通过 name 来访问端口
    server cqbackend2:3002;
    # 之前我说 service name 很重要,就是这里需要通过 name 来访问端口
    server cqbackend3:3003;
  }

  server {
    listen 81;
    server_name rysyclub.com;

    location / {
      proxy_pass http://app_servers;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
    }
  }
}

💡ps:注意之前我说 service name 很重要,就是这里需要通过 name 来访问端口,而不是localhost,这是因为 docker 有内建的 network 环境(这不是指你的服务器上的网络哟!),所以你要么配置网络link,要么部署在同一个网络下,事实上同一个 docker-compose.yml 文件中的 services 会部署在同一个 default 网络下,但是依然需要通过 service name 才能访问,否则会被拒绝访问,这个问题曾困扰我24小时,这就是不好好看文档的后果。😂(事实上不仅仅是 nginx 需要这样配置,你的服务器上的服务间不同端口需要互通也是同理,只要他们都是用 docker)比如我的 apigateway 服务内部是通过 http://nginx:81 访问 Nginx 的。

okk~ 剩下的工作,你只需要配置好你的 gitee 流水线就可以了,这里给出一个简单的示例:

总体来说就是等待 cqbackendapigateway 镜像打包完成之后再进行主机部署

image

💡ps:如果你想用于生产环境,建议你用 pipeline 测试你的程序,通过之后再进行主机部署

这是在流水线中 主机部署 里需要的 bash

# 进入到你的工作目录
cd ~/gitee_go/cq-backend
# 同步一下远程仓库的分支,这里我是同步的 feature,但通常是 release 分支才对
git fetch origin feature
# 拉取该分支下根目录的 docker-compose.yml
git checkout origin/feature -- docker-compose.yml
# 拉取该分支下根目录的 docker-compose.yml
git checkout origin/feature -- nginx.conf
# 先停掉当前的容器
docker-compose stop
# 删除 image,以便重新拉取最新的 image
docker rmi -f registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-apigateway:latest
# 删除 image,以便重新拉取最新的 image
docker rmi -f registry.cn-chengdu.aliyuncs.com/gitee-docker/cq-backend:latest
# 后台启动~
docker-compose up -d --remove-orphans

💡ps:请注意,以上 git 部分要生效需要你提前在你的工作目录中(cd ~/gitee_go/cq-backend)创建 git 仓库,checkout 2个部署文件就可以了,这样你的 git 仓库就只有这俩文件,而不是整个 monorepo

建议你ssh到你的实例上去用 docker ps 验证一下,如果输出如下,那便没啥问题了:

image

💡ps:这是一个入门示例,请别直接用到生产环境,你还需要做更多的容错和 backup 的方案,至少你的 CI 需要更多的测试相关 pipeline , CD 上你需要对每一个服务进行较为完善的监控,做好预警等措施,并且你的数据库也应该有备份机制等。


😊okk~ 这就是我的入门实践了,希望能帮助到你,赶紧去部署你的应用吧~