夜猫子的知识栈 夜猫子的知识栈
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

夜猫子

前端练习生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《Web Api》
    • 《ES6教程》
    • 《Vue》
    • 《React》
    • 《TypeScript》
    • 《Git》
    • 《Uniapp》
    • 小程序笔记
    • 《Electron》
    • JS设计模式总结
  • 《前端架构》

    • 《微前端》
    • 《权限控制》
    • monorepo
  • 全栈项目

    • 任务管理日历
    • 无代码平台
    • 图书管理系统
  • HTML
  • CSS
  • Nodejs
  • Midway
  • Nest
  • MySql
  • 其他
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • Ajax
  • Vite
  • Vitest
  • Nuxt
  • UI库文章
  • Docker
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Node基础

  • 《MySQL》学习笔记

  • Midway

  • Nest

    • 开篇词
    • 学习理由
    • nest概念扫盲
    • 快速掌握 nestcli
    • 5种http数据传输方式
    • IoC 解决了什么痛点问题?
    • 如何调试 Nest 项目
    • Provider注入对象
    • 全局模块和生命周期
    • AOP 架构有什么好处?
    • 一网打尽 Nest 全部装饰器
    • Nest如何自定义装饰器
    • Metadata和Reflector
    • ExecutionContext切换上下文
    • Module和Provider的循环依赖处理
    • 如何创建动态模块
    • Nest和Express,fastify
    • Nest的Middleware
    • RxJS和Interceptor
    • 内置Pipe和自定义Pipe
    • ValidationPipe验证post请求参数
    • 如何自定义 Exception Filter
    • 图解串一串 Nest 核心概念
    • 接口如何实现多版本共存
    • Express如何使用multer实现文件上传
    • Nest使用multer实现文件上传
    • 图书管理系统
    • 大文件分片上传
    • 最完美的 OSS 上传方案
    • Nest里如何打印日志
    • 为什么Node里要用Winston打印日志
    • Nest 集成日志框架 Winston
    • 通过Desktop学Docker也太简单了
    • 你的第一个 Dockerfile
    • Nest 项目如何编写 Dockerfile
    • 提升 Dockerfile 水平的 5 个技巧
    • Docker 是怎么实现的
    • 为什么 Node 应用要用 PM2 来跑?
    • 快速入门 MySQL
    • SQL 查询语句的所有语法和函数
    • 一对一、join 查询、级联方式
    • 一对多、多对多关系的表设计
    • 子查询和 EXISTS
    • SQL 综合练习
    • MySQL 的事务和隔离级别
    • MySQL 的视图、存储过程和函数
    • Node 操作 MySQL 的两种方式
    • 快速掌握 TypeORM
    • TypeORM 一对一的映射和关联 CRUD
    • TypeORM 一对多的映射和关联 CRUD
    • TypeORM 多对多的映射和关联 CRUD
    • 在 Nest 里集成 TypeORM
    • TypeORM保存任意层级的关系
    • 生产环境为什么用TypeORM的migration迁移功能
    • Nest 项目里如何使用 TypeORM 迁移
    • 如何动态读取不同环境的配置?
    • 快速入门 Redis
    • 在 Nest 里操作 Redis
    • 为什么不用 cache-manager 操作 Redis
    • 两种登录状态保存方式:JWT、Session
    • Nest 里实现 Session 和 JWT
    • MySQL + TypeORM + JWT 实现登录注册
    • 基于 ACL 实现权限控制
    • 基于 RBAC 实现权限控制
    • access_token和refresh_token实现无感登录
    • 单token无限续期实现登录无感刷新
    • 使用 passport 做身份认证
    • passport 实现 GitHub 三方账号登录
    • passport 实现 Google 三方账号登录
    • 为什么要使用 Docker Compose ?
    • Docker 容器通信的最简单方式:桥接网络
    • Docker 支持重启策略,是否还需要 PM2
    • 快速掌握 Nginx 的 2 大核心用法
    • 基于 Nginx 实现灰度系统
    • 基于 Redis 实现分布式 session
    • Redis + 高德地图,实现附近的充电宝
    • 用 Swagger 自动生成 api 文档
    • 如何灵活创建 DTO
    • class- validator 的内置装饰器,如何自定义装饰器
    • 序列化 Entity,你不需要 VO 对象
    • 手写序列化 Entity 的拦截器
    • 使用 compodoc 生成文档
    • Node 如何发邮件?
    • 实现基于邮箱验证码的登录
    • 基于 sharp 实现 gif 压缩工具
    • 大文件如何实现流式下载?
    • Puppeteer 实现爬虫,爬取 BOSS 直聘全部前端岗位
    • 实现扫二维码登录
    • Nest 的 REPL 模式
    • 实现 Excel 导入导出
    • 如何用代码动态生成 PPT
    • 如何拿到服务器 CPU、内存、磁盘状态
    • Nest 如何实现国际化?
    • 会议室预订系统:需求分析和原型图
    • 会议室预订系统:技术方案和数据库设计
    • 会议室预订系统:用户管理模块--用户注册
    • 会议室预订系统:用户管理模块--配置抽离、登录认证鉴权
    • 会议室预订系统:用户管理模块-- interceptor、修改信息接口
    • 会议室预订系统:用户管理模块--用户列表和分页查询
    • 会议室预订系统:用户管理模块-- swagger 接口文档
    • 会议室预订系统:用户管理模块-- 用户端登录注册页面
    • 会议室预订系统:用户管理模块-- 用户端信息修改页面
    • 会议室预订系统:用户管理模块-- 头像上传
    • 会议室预订系统:用户管理模块-- 管理端用户列表页面
    • 会议室预订系统:用户管理模块-- 管理端信息修改页面
    • 会议室预订系统:会议室管理模块-后端开发
    • 会议室预订系统:会议室管理模块-管理端前端开发
    • 会议室预订系统:会议室管理模块-用户端前端开发
    • 会议室预订系统:预定管理模块-后端开发
    • 会议室预订系统:预定管理模块-管理端前端开发
    • 会议室预订系统:预定管理模块-用户端前端开发
    • 会议室预订系统:统计管理模块-后端开发
    • 会议室预订系统:统计管理模块-前端开发
    • 会议室预订系统:后端项目部署到阿里云
    • 会议室预订系统:前端项目部署到阿里云
      • 总结
    • 会议室预定系统:用 migration 初始化表和数据
    • 会议室预定系统:文件上传 OSS
    • 会议室预定系统:Google 账号登录后端开发
    • 会议室预定系统:Google 账号登录前端开发
    • 会议室预定系统:后端代码优化
    • 会议室预定系统:集成日志框架 winston
    • 会议室预定系统:前端代码优化
    • 会议室预定系统:全部功能测试
    • 会议室预定系统:项目总结
    • Nest 如何创建微服务?
    • Nest 的 Monorepo 和 Library
    • 用 Etcd 实现微服务配置中心和注册中心
    • Nest 集成 Etcd 做注册中心、配置中心
    • 用 Nacos 实现微服务配置中心和注册中心
    • 基于 gRPC 实现跨语言的微服务通信
    • 快速入门 ORM 框架 Prisma
    • Prisma 的全部命令
    • Prisma 的全部 schema 语法
    • Primsa Client 单表 CRUD 的全部 api
    • Prisma Client 多表 CRUD 的全部 api
    • 在 Nest 里集成 Prisma
    • 为什么前端监控系统要用 RabbitMQ?
    • 基于 Redis 实现关注关系
    • 基于 Redis 实现各种排行榜(周榜、月榜、年榜)
    • 考试系统:需求分析
    • 考试系统:技术方案和数据库设计
    • 考试系统:微服务、Lib 拆分
    • 考试系统;用户注册
    • 考试系统:用户登录、修改密码
    • 考试系统:考试微服务
    • 考试系统:登录、注册页面
    • 考试系统:修改密码、试卷列表页面
    • 考试系统:新增试卷、回收站
    • 考试系统:试卷编辑器
    • 考试系统:试卷回显、预览、保存
    • 考试系统:答卷微服务
    • 考试系统:答题页面
    • 考试系统:自动判卷
    • 考试系统:分析微服务、排行榜页面
    • 考试系统:整体测试
    • 考试系统:项目总结
    • 用 Node.js 手写 WebSocket 协议
    • Nest 开发 WebSocket 服务
    • 基于 Socket.io 的 room 实现群聊
    • 聊天室:需求分析和原型图
    • 聊天室:技术选型和数据库设计
    • 聊天室:用户注册
    • 聊天室:用户登录
    • 聊天室:修改密码、修改信息
    • 聊天室:好友列表、发送好友申请
    • 聊天室:创建聊天室、加入群聊
    • 聊天室:登录、注册页面开发
    • 聊天室:修改密码、信息页面开发
    • 聊天室:头像上传
    • 聊天室:好友∕群聊列表页面
    • 聊天室:添加好友弹窗、通知页面
    • 聊天室:聊天功能后端开发
    • 聊天室:聊天功能前端开发
    • 聊天室:一对一聊天
    • 聊天室:创建群聊、进入群聊
    • 聊天室:发送表情、图片、文件
    • 聊天室:收藏
    • 聊天室:全部功能测试
    • 聊天室:项目总结
    • MongoDB 快速入门
    • 使用 mongoose 操作 MongoDB 数据库
    • GraphQL 快速入门
    • Nest 开发 GraphQL 服务:实现 CRUD
    • GraphQL + Primsa + React 实现 TodoList
    • 如何调试 Nest 源码?
  • 其他

  • 服务端
  • Nest
神说要有光
2025-03-10
目录

会议室预订系统:前端项目部署到阿里云

上节把后端项目部署到了阿里云,可以在任意电脑上访问。

这节来部署下前端项目。

项目跑起来是这样的架构:

在之前 docker compose 的基础上加上 nginx 容器就好了。

我们进入 frontend-admin 项目,加一下 nginx 配置文件:

upstream nest-server {
    server 192.168.31.56:3005;
}

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;

    location ^~ /api {
        rewrite ^/api/(.*)$ /$1 break;
        proxy_pass http://nest-server;
    }

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

nginx 的两个核心功能就是静态资源托管、反向代理。

我们配置了 /api 下的请求走反向代理,转发请求到 nest 服务。

/ 下的静态资源请求返回 index.html。

这里的 ip 是我宿主机的,你可以换成你本地的。

用 nginx 做了反向代理之后,访问的 url 要改一下:

不再是直接访问 nest 服务了,而是通过 nginx 反向代理到 nest 服务。

然后加一下 Dockerfile

# build stage
FROM node:18 as build-stage

WORKDIR /app

COPY package.json ./

RUN npm config set registry https://registry.npmmirror.com/

RUN npm install

COPY . .

RUN npm run build

# production stage
FROM nginx:stable as production-stage

COPY --from=build-stage /app/build /usr/share/nginx/html

COPY --from=build-stage /app/nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

用多阶段构建,第一个阶段把代码复制到容器,执行 npm run build,第二个阶段把上个阶段的产物还有 nginx 配置文件复制过来,把 nginx 服务跑起来。

这里的 CMD 启动命令看别的 nginx 镜像的启动命令就行:

加一下 .dockerignore

node_modules/
.vscode/
.git/
build/
1
2
3
4

然后 build 下镜像:

docker build -t fe-container:first .
1

然后在 docker desktop 里搜索这个镜像,点击 run:

进入 backend 项目,把服务跑起来:

npm run start:dev
1

浏览器访问下:

界面正常渲染,访问接口的 url 也换成了 nginx 的:

接口也正常返回了数据。

说明 nginx 的反向代理和静态资源托管都成功了。

但是,当你切换到修改信息界面,会跳到 /login 的 url,这时候返回了 404:

因为我们用的是 browser 路由,也就是 /xxx 的方式,而不是 hash 路由,也就是 ?#/xxx 的方式。

需要在 nginx 里面支持下:

location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
}
1
2
3
4
5

加上这条 try_files,当访问 /login 的时候会先匹配 /login 然后是 /login/ 然后是 /index.html

这样就交给了前端页面来处理 /login 路由。

重新 build 一下:

把之前的 container 停止、删除,然后重新跑。

现在你就会发现所有的路由都能正常访问了:

当然,我们现在是单独跑的 nginx 的容器,而且反向代理 nest 服务时用的是 ip。

这样肯定是不好的。

我们希望可以把它也放到 docker-compose.yml 的配置文件里。

直接 docker compose up 一起跑。

我们知道,docker compose 跑的多个容器之间可以通过容器名相互访问。

改一下 nginx 配置,把 ip 换成 nest 服务的容器名:

重新 build:

然后在 backend 项目的 docker-compose.yml 里配置下:

version: '3.8'
services:
  fe-app:
    image: fe-container:first
    ports:
      - 80:80
    depends_on:
      - nest-app
    networks:
      - common-network
  nest-app:
    build:
      context: ./
      dockerfile: ./Dockerfile
    depends_on:
      - mysql-container
      - redis-container
    networks:
      - common-network
  mysql-container:
    image: mysql
    volumes:
      - /Users/guang/mysql-data:/var/lib/mysql
    environment:
      MYSQL_DATABASE: meeting_room_booking_system
      MYSQL_ROOT_PASSWORD: guang
    networks:
      - common-network
  redis-container:
    image: redis
    volumes:
      - /Users/guang/redis-data:/data
    networks:
      - common-network
networks:
  common-network:
    driver: bridge
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

把 env 里的 url 改回来:

然后跑一下(最好把本地的其他 mysql 和 redis 容器停掉再跑):

docker-compose up
1

跑起来之后,浏览器访问下:

这样,我们就通过 docker compose 一次性跑了 nest、nginx 还有 mysql 和 redis 服务。

但是 fe-container 这个镜像只存在于本地,在阿里云跑 docker compose 的话会找不到这个镜像。

所以我们需要这个镜像上传到阿里云的镜像仓库。

当然,这里直接在服务器上下载代码然后 build 镜像也可以,这里只是为了用一下阿里云的镜像仓库。

阿里云的容器镜像服务 (opens new window)个人用是免费的:

进入管理控制台:

点击创建镜像仓库。

它会让你先创建命名空间。

直接说明了如何登陆阿里云镜像仓库和 push 镜像上去:

我们在本地 build 下镜像。

复制下你买的服务器的公网 ip:

改一下项目里的 baseURL,改成服务器的 ip:

然后 build 出镜像:

docker build -t fe-container:first .
1

然后分别执行 docker login、docker tag、docker push 把镜像 push 到镜像仓库(直接复制命令就行):

上传之后,点击镜像版本就可以看到这个版本号的镜像:

然后改一下 backend 项目里的 docker-compose.yml 文件:

image 改成阿里云镜像仓库里的。

接下来我们在服务器上把它跑起来就行。

保存代码,然后 git push 到代码仓库:

然后登录服务器,把最新代码 clone 下来(如果你clone 过了,只要 git pull 就行)。

然后跑一下:

docker login --username=用户名 registry.cn-qingdao.aliyuncs.com
 
docker-compose up
1
2
3

之后在安全组添加 80 端口:

但是这时你用 ip 访问,会发现没返回东西:

为什么呢?

往上翻一下日志,可能会有这个报错:

说是 docker 镜像的 platform 不匹配。

因为我本地是 m1 芯片的 mac ,build 出来的镜像在 linux 上跑不了。

当然,你不一定遇到这个问题,如果没遇到这个问题下面的步骤可以跳过。

如果遇到这个问题,那就需要 build 的时候加上 platform 了:

docker build -t fe-container:first --platform linux/amd64 .
1

我重新 build 了一下镜像,指定了目标 platform。

然后重新 docker login、docker tag、docker push 来上传镜像:

上传之后在服务器把之前镜像删掉,重新跑:

docker-compose down --rmi all

docker login --username=用户名 registry.cn-qingdao.aliyuncs.com

docker-compose up
1
2
3
4
5

这时浏览器就可以看到页面正常渲染了:

如果你没遇到 platform 的问题,那直接就可以在浏览器看到结果。

请求的 url 也是对的:

只是现在没有数据,后面加一下初始数据就好了。

这样,我们前端部分也部署完成了。

代码在小册仓库:

backend (opens new window)。

frontend-admin (opens new window)。

# 总结

我们通过 nginx 部署了前端项目,用它来做静态资源托管和 nest 服务的反向代理。

通过 Dockerfile 的多阶段构建,第一个阶段 npm run build 出产物,第二个阶段把产物和 nginx 配置文件复制过去跑 nginx 服务。

之后用 docker build 构建出镜像,把它上传到阿里云镜像仓库。

在另一边的 docker compose 配置文件里添加这个 nginx 的容器配置。

这样服务端那边就可以用 docker compose up 一次性跑起 nginx、nest、mysql、redis 等容器,前后端服务一键启动。

这就是 docker compose 的作用。

过程中如果遇到 platform 不一致的问题,那就 build 的时候指定下 platform 再上传就好了。

这样,我们就通过 docker-compose 把前后端项目都部署到了阿里云:

编辑 (opens new window)
上次更新: 2025/10/27 10:53:52
会议室预订系统:后端项目部署到阿里云
会议室预定系统:用 migration 初始化表和数据

← 会议室预订系统:后端项目部署到阿里云 会议室预定系统:用 migration 初始化表和数据→

最近更新
01
H5调用微信jssdk
09-28
02
VueVirtualScroller
09-19
03
如何调试 Nest 项目
03-10
更多文章>
Copyright © 2019-2025 Study | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式