前端部署相关
极简部署
手写一个简单的静态资源服务器
基于 docker/docker-compose 对极简项目的部署
基于Nginx镜像的部署
单页应用部署
单页应用的静态资源
所有的前端单页应用对于部署,最重要的就是构建静态资源,也就是npm run build
一个最简单的Dockerfile:
1 | FROM node:14-alpine |
这样其实就已经完成构建了,然而还可以针对以下两点进行优化:
- 构建镜像时间过长,优化构建时间
- 构建镜像文件过大,优化镜像体积
构建时间优化:构建缓存
一个前端项目的耗时时间主要集中在两个命令:
- npm i (yarn)
- npm run build
如果 package.json/package.lock.json 文件内容没有变更,实际上是无需再次 npm install 的
在 Dockerfile 中,对于 ADD 指令来说,如果添加的文件没有发生变化,则可以利用构建缓存:Docker构建缓存
也就是 Dockerfile 中,我们分离出 package.json 和 package.lock.json 文件
1 | FROM node:14-alpine as builder |
进行构建时,若利用了缓存,可以看到 CACHED 标记

另外还可以有一些小优化,如
npm cache的基础镜像或者 npm 私有仓库,减少npm install时间,减小构建时间npm install --production只装必要的包
构建体积优化:多阶段构建
我们的目标是提供静态服务(资源),最终的产物其实不需要依赖于 node.js 环境。node.js 环境在完成构建后即完成了它的使命,它的继续存在会造成极大的资源浪费。
我们可以使用多阶段构建进行优化,最终使用 nginx 提供静态资源服务
- 第一阶段 Node 镜像:使用 node 镜像对单页应用进行构建,生成静态资源
- 第二阶段 Nginx 镜像:使用 nginx 镜像对单页应用的静态资源进行服务化
1 | FROM node:14-alpine as builder |
Nginx相关配置
OSS对象存储
OSS(Object Storage Service) 是存文件的云硬盘/文件仓库,一般存:
- 图片、视频
- 前端静态资源(JS/CSS/字体)
- 备份文件、日志包
上文的方案是把js、css静态资源放在docker容器里,实际工程中的静态资源会上传至 OSS,并对 OSS 提供 CDN 服务。
将静态资源部署在OSS/CDN
OSS云服务
AccessKey
aliyun_access_key_id
aliyun_access_key_secret
在将静态资源上传至云服务时,我们需要 AccessKey/AccessSecret 获得权限用以上传。可参考文档创建AccessKey
Bucket
Bucket 是 OSS 中的存储空间。对于生产环境,可对每一个项目创建单独的 Bucket,而在测试环境,多个项目可共用 Bucket。
在创建 Bucket 时,需要注意以下事项。
权限设置为公共读 (Public Read)
跨域配置 CORS (manifest.json 需要配置 cors)
记住 Endpoint,比如 oss-cn-beijing.aliyuncs.com。将会在配置 PUBLIC_URL 中使用到
对于 Endpoint 的选择,可参考 访问域名和数据中心
PUBILC_URL
推送资源到OSS
静态资源上传时间及空间优化
服务编排
CI/CD
常见的部署方案
html通过Nginx/Node bff返回,JS/CSS通过CDN返回
Nginx + Docker + CDN
打包生成产物时JS/CSS拼接上CDN地址
Node Bff
常见几种:
SSR:Node 先拉后端数据,再 renderToString 输出完整 HTML
模板渲染:Node 用 ejs/nunjucks 拼模板返回 HTML
Hybrid:返回基础 HTML + 注入首屏数据,前端再 hydration
为什么这么做:
首屏更快可见(尤其弱网)
SEO 更友好(爬虫直接拿到内容)
可以按用户态个性化(登录态、地区、AB 实验)
如何选型
静态站:HTML 可放 Nginx/Docker 直出
动态站/SSR:HTML 由 Node BFF 返回,Nginx 在前面做反代与网关
最佳实践
1、JS、CSS等静态资源利用CDN
2、利用Docker构建缓存
3、利用Docker多阶段构建
4、Nginx相关最佳实践
详细见:Nginx最佳实践
5、按需上传静态资源文件到OSS/CDN
其他
1、项目部署后如何提升用户版本更新
FAQ
1、为什么不Node实现静态资源服务器
- 镜像体积过大
- 没有rewrite、redirect那些能力
- 没有缓存cache那些能力