三、Serverless Framework 部署项目实战
3.1 Serverless Framework 简介及应用场景
- Serverless Framework 是 Serverless 公司推出的一个开源的 Serverless 应用开发框架
- Serverless Framework 是 由 Serverless Framework Plugin 和 Serverless Framework Components 组成
- Serverless Framework Plugin 实际上是一个函数的管理工具,使用这个工具,可以很轻 松的部署函数、删除函数、触发函数、查看函数信息、查看函数日志、回滚函数、查看函数 数据等
Serverless Framework Components 可以看作是一个组件集,这里面包括了很多的 Components,有基础的 Components,例如 cos、scf、apigateway 等,也有一些拓展的 Components,例如在 cos 上拓展出来的 website,可以直接部署静态网站等,还有一些框 架级的,例如 Koa,Express 等
- Serverless Framework 官网: https://www.serverless.com/
- Serverless Framework 中文网站: https://www.serverless.com/cn
- Github 地址: https://github.com/serverless/serverless
Serverless Framework 应用场景
上面既然介绍了云函数和 serverless
的区别,现在我们介绍下什么场景下需要使用 serverless
,而不是使用云函数,其实在实际开发过程中,我们都是使用 serverless
而不去使用云函数,毕竟云函数的使用场景受限,或者说比较基础。打一个简单的比方,在写 js
操作 dom
的时候,你会选择用原生 js
还是会使用 jquery
一样的比喻
基于云函数的命令行开发工具
通过 Serverless Framework
,开发者可以在命令行完成函数的开发、部署、调试。还可以结合前端服务、 API 网关、数据库等其它云上资源,实现全栈应用的快速部署。
传统应用框架的快速迁移
Serverless Framework
提供了一套通用的框架迁移方案,通过使用 Serverless Framework
提供的框架组件( Egg/Koa/Express
等, 更多的框架支持可以参考 ),原有应用仅需几行代码简单改造, 即可快速迁移到函数平台。同时支持命令行与控制台的开发方式。
Serverless Framework 支持的平台
https://github.com/serverless/serverless/tree/master/docs/providers
3.2 Serverless Components 支持组件列表
基础组件
- @serverless/tencent-postgresql - 腾讯云 PG DB Serverless 数据库组件
- @serverless/tencent-apigateway - 腾讯云 API 网关组件
- @serverless/tencent-cos - 腾讯云对象存储组件
- @serverless/tencent-scf - 腾讯云云函数组件
- @serverless/tencent-cdn - 腾讯云 CDN 组件
- @serverless/tencent-vpc - 腾讯云 VPC 私有网络组件
高阶组件
- @serverless/tencent-nextjs - 快速部署基于 Next.js 框架到腾讯云函数的组件
- @serverless/tencent-nuxtjs - 快速部署基于 Nuxt.js 框架到腾讯云函数的组件
- @serverless/tencent-express - 快速部署基于 Express.js 的后端服务到腾讯云函数的组件
- @serverless/tencent-egg - 快速部署基于 Egg.js 的后端服务到腾讯云函数的组件
- @serverless/tencent-koa - 快速部署基于 Koa.js 的后端服务到腾讯云函数的组件
- @serverless/tencent-flask - 腾讯云 Python Flask RESTful API 组件
- @serverless/tencent-django - 腾讯云 Python Django RESTful API 组件
- @serverless/tencent-laravel - 腾讯云 PHP Laravel RESTful API 组件
- @serverless/tencent-thinkphp - 腾讯云 ThinkPHP RESTful API 组件
- @serverless/tencent-website - 快速部署静态网站到腾讯云的组件
3.3 sls 部署 egg 项目
egg 框架中默认已经配置好了静态资源,我们可以直接访问。要注意的是 serverless 服务器 上面只有根目录的 tmp 目录有写入权限,所以需要配置 egg 日志存储的目录。默认创建好 项目以后有如下配置。
// config/config.default.js module.exports = (appInfo) => { // return { ..., rundir: '/tmp', logger: { dir: '/tmp' }, } }
控制台创建部署-模板部署
- 登录控制台 https://console.cloud.tencent.com/sls
- 单击新建应用,选择 Web 应用>Egg 框架,如下图所示:
- 单击“下一步”,完成基础配置选择。
- 上传方式,选择示例代码直接部署,单击完成,即可开始应用的部署。
- 部署完成后,您可在应用详情页面,查看示例应用的基本信息,并通过 API 网关生成的访问路径 URL 进行访问,查看您部署的 Egg 项目。
控制台创建部署-自定义部署(推荐)
如果除了代码部署外,您还需要更多能力或资源创建,如自动创建层托管依赖、一键实现静态资源分离、支持代码仓库直接拉取等,可以通过应用控制台,完成 Web 应用的创建工作
初始化项目
mkdir egg-example && cd egg-example npm init egg --type=simple npm i
部署上云
接下来执行以下步骤,对本地已创建完成的项目进行简单修改,使其可以通过 Web Function 快速部署,对于 Egg 框架,具体改造说明如下:
- 修改监听地址与端口为
0.0.0.0:9000
。 - 修改写入路径,serverless 环境下只有
/tmp
目录可读写。 - 新增
scf_bootstrap
启动文件。
1. (可选) 配置 scf_bootstrap 启动文件
您也可以在控制台完成该模块配置。
在项目根目录下新建 scf_bootstrap
启动文件,在该文件添加如下内容(用于配置环境变量和启动服务,此处仅为示例,具体操作请以您实际业务场景来调整):
#!/var/lang/node12/bin/node 'use strict'; /** * docker 中 node 路径:/var/lang/node12/bin/node * 由于 serverless 函数只有 /tmp 读写权限,所以在启动时需要修改两个环境变量 * NODE_LOG_DIR 是为了改写 egg-scripts 默认 node 写入路径(~/logs)-> /tmp * EGG_APP_CONFIG 是为了修改 egg 应有的默认当前目录 -> /tmp */ process.env.EGG_SERVER_ENV = 'prod'; process.env.NODE_ENV = 'production'; process.env.NODE_LOG_DIR = '/tmp'; process.env.EGG_APP_CONFIG = '{"rundir":"/tmp","logger":{"dir":"/tmp"}}'; const { Application } = require('egg'); // 如果通过层部署 node_modules 就需要修改 eggPath Object.defineProperty(Application.prototype, Symbol.for('egg#eggPath'), { value: '/opt', }); const app = new Application({ mode: 'single', env: 'prod', }); app.listen(9000, '0.0.0.0', () => { console.log('Server start on http://0.0.0.0:9000'); });
新建完成后,还需执行以下命令修改文件可执行权限,默认需要 777 或 755 权限才可正常启动。示例如下:
chmod 777 scf_bootstrap
2. 控制台上传
您可以在控制台完成启动文件 scf_bootstrap 内容配置,配置完成后,控制台将为您自动生成 启动文件,和项目代码一起打包部署
启动文件以项目内文件为准,如果您的项目里已经包含 scf_bootstrap
文件,将不会覆盖该内容。
查看函数,修改代码查看日志等
高级配置管理
您可在“高级配置”里进行更多应用管理操作,如创建层、绑定自定义域名、配置环境变量等。
HTTP 组件方式部署(推荐)
目前推荐使用 web 函数,也就是 HTTP 组件
,现在所有的 serverless web 应用都是基于 component: http
组件的。
通过 Serverless Framework
的 HTTP 组件
,完成 Web 应用的本地部署
前提条件
已开通服务并完成 Serverless Framework 的 权限配置
# 初始化 egg 项目 serverless init eggjs-starter(可以替换成 sls registry 已有的模板) --name egg-example
# 编写完善配置文件 serverless.yml # https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md app: egg-example-fa63d20e9 # 应用名称 component: http # http 组件 name: egg-demo # 实例名称 inputs: region: ap-guangzhou # 云函数所在区域 src: # 部署当前目录下的文件代码,并打包成 zip 上传到 bucket 上 src: ./ # 当前目录 exclude: # 被排除的文件或目录 - .env - 'node_modules/**' # 忽略 node_modules,在控制台 WEBIDE 开启安装依赖 # src: # 在指定存储桶 bucket 中已经存在了 object 代码,直接部署 # bucket: bucket01 # bucket name,当前会默认在 bucket name 后增加 appid 后缀, 本例中为 bucket01-appid # object: cos.zip # bucket key 指定存储桶内的文件 faas: # 函数配置相关 runtime: Nodejs12.16 # 运行时 # 支持的框架查看 https://cloud.tencent.com/document/product/1154/59447#framework framework: egg # #选择框架,此处以 egg 为例 name: ${name} # 云函数名称,通过变量形式获取 name 的值 timeout: 60 # 超时时间,单位秒 memorySize: 512 # 内存大小,默认 512 MB # layers: # - name: layerName # layer 名称 # version: 1 # 版本 environments: # 配置环境变量,同时也可以直接在 scf 控制台配置 - key: NODE_ENV value: production # vpc: # 私有网络配置 # vpcId: 'vpc-xxx' # 私有网络的 Id # subnetId: 'subnet-xxx' # 子网 ID # tags: # - key: tagKey # value: tagValue apigw: # http 组件会默认帮忙创建一个 API 网关服务 isDisabled: false # 是否禁用自动创建 API 网关功能 # id: service-xx # api 网关服务 ID,不填则自动新建网关 name: serverless # api 网关服务名称 api: # 创建的 API 相关配置 cors: true # 允许跨域 timeout: 30 # API 超时时间 name: apiName # API 名称 qualifier: $DEFAULT # API 关联的版本 protocols: - http - https environment: test # tags: # - key: tagKey # value: tagValue # customDomains: # 自定义域名绑定 # - domain: abc.com # 待绑定的自定义的域名 # certId: abcdefg # 待绑定自定义域名的证书唯一 ID # # 如要设置自定义路径映射,(customMap = true isDefaultMapping = false) 必须两者同时出现 其余情况都是默认路径 # customMap: true # isDefaultMapping: false # # 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 # pathMap: # - path: / # environment: release # protocols: # 绑定自定义域名的协议类型,默认与服务的前端协议一致。 # - http # 支持 http 协议 # - https # 支持 https 协议 # app: # 应用授权配置 # id: app-xxx # name: app_demo # description: app description
全部配置详细查看 https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md
部署
创建完成后,在根目录下执行 sls deploy
进行部署,组件会根据选择的框架类型,自动生成 scf_bootstrap
启动文件进行部署
我们也可以在项目跟目录自己创建启动文件 scf_bootstrap
,然后 chmod 777 scf_bootstrap
// scf_bootstrap #!/var/lang/node12/bin/node /** * docker 中 node 路径:/var/lang/node12/bin/node * 由于 serverless 函数只有 /tmp 读写权限,所以在启动时需要修改两个环境变量 * NODE_LOG_DIR 是为了改写 egg-scripts 默认 node 写入路径(~/logs)-> /tmp * EGG_APP_CONFIG 是为了修改 egg 应有的默认当前目录 -> /tmp */ process.env.EGG_SERVER_ENV = 'prod'; process.env.NODE_ENV = 'production'; process.env.NODE_LOG_DIR = '/tmp'; process.env.EGG_APP_CONFIG = '{"rundir":"/tmp","logger":{"dir":"/tmp"}}'; const { Application } = require('egg'); // 如果通过层部署 node_modules 就需要修改 eggPath Object.defineProperty(Application.prototype, Symbol.for('egg#eggPath'), { value: '/opt', }); const app = new Application({ mode: 'single', env: 'prod', }); app.listen(9000, '0.0.0.0', () => { console.log('Server start on http://0.0.0.0:9000'); });
# 微信扫码即可 # 微信扫码授权部署有过期时间,如果想要持久授权,请参考账号配置(https://cloud.tencent.com/document/product/1154/45874#account) # 当前默认支持 CLI 扫描二维码登录,如您希望配置持久的环境变量/密钥信息,也可以本地创建 .env 文件: # 在 .env 文件中配置腾讯云的 SecretId 和 SecretKey 信息并保存。 # API 密钥管理 https://console.cloud.tencent.com/cam/capi # .env #TENCENT_SECRET_ID=123 #TENCENT_SECRET_KEY=123 sls deploy
注意:由于启动文件逻辑与用户业务逻辑强关联,默认生成的启动文件可能导致框架无法正常启动,建议您根据实际业务需求,手动配置启动文件, 详情参考各框架的部署指引文档 。
如果部署过程遇到问题不好排除,如以下问题:
来到控制台创建项目
在控制台安装依赖包
我们在 sls deploy
忽略了 node_modules
,因此需要在控制台安装依赖
访问应用
到控制台查看
删除应用
sls remove
使用 Layer 来减小项目文件大小
随着项目复杂度的增加, deploy
上传会变慢。所以,让我们再优化一下,在项目根目录创建 layer/serverless.yml
# layer/serverless.yml # https://cloud.tencent.com/document/product/1154/51133 # https://github.com/serverless-components/tencent-layer/blob/master/docs/configure.md #应用组织信息(可选) app: egg-demo stage: dev #组件信息 component: layer name: egg-demo-layer # 层名称 必须 # 组件参数配置,根据每个组件,实现具体的资源信息配置 inputs: name: ${name} # 名称跟上面一致即可 region: ap-guangzhou # 地区 必须 src: ../node_modules #需要上传的目标文件路径 必须 # src: # 代码路径。与 object 不能同时存在。 # src: ./node_modules # targetDir: /node_modules # exclude: # 被排除的文件或目录 不包含的文件或路径, 遵守 glob 语法 # - .env # - node_modules # src: # bucket 名称。如果配置了 src,表示部署 src 的代码并压缩成 zip 后上传到 bucket-appid 对应的存储桶中;如果配置了 object,表示获取 bucket-appid 对应存储桶中 object 对应的代码进行部署。 # bucket: layers # object: sls-layer-test-1584524206.zip # 部署的代码在存储桶中的路径。 # exclude: # 被排除的文件或目录 # - .env # - node_modules runtimes: # 层支持的运行环境 - Nodejs12.16 description: layer description # 否 描述
创建后可见层对应信息
我们也可以在控制台新建层绑定到对应的函数即可
控制台上传层有大小限制
文件夹支持 250M
修改以上项目下的 serverless.yml 加入层配置
回到项目根目录,调整一下根目录的 serverless.yml
# 编写完善配置文件 serverless.yml # https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md app: egg-example-fa63d20e9 # 应用名称 component: http # http 组件 name: egg-demo # 实例名称 inputs: region: ap-guangzhou # 云函数所在区域 src: # 部署当前目录下的文件代码,并打包成 zip 上传到 bucket 上 src: ./ # 当前目录 exclude: # 被排除的文件或目录 - .env - "node_modules/**" # deploy 时排除 node_modules [需要注意] 使用 layer 的 node_modules faas: # 函数配置相关 runtime: Nodejs12.16 # 运行时 # 支持的框架查看 https://cloud.tencent.com/document/product/1154/59447#framework framework: egg # #选择框架,此处以 egg 为例 name: ${name} # 云函数名称,通过变量形式获取 name 的值 timeout: 60 # 超时时间,单位秒 memorySize: 512 # 内存大小,默认 512 MB # 加入层配置 引用格式请参考 变量引用说明 https://github.com/AprilJC/Serverless-Framework-Docs/blob/main/docs/%E5%87%BD%E6%95%B0%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91/%E6%9E%84%E5%BB%BA%E5%BA%94%E7%94%A8.md layers: - name: ${output:${stage}:${app}:${name}-layer.name} # 配置对应的 layer version: ${output:${stage}:${app}:${name}-layer.version} # 配置对应的 layer 版本 environments: # 配置环境变量,同时也可以直接在 scf 控制台配置 - key: NODE_ENV value: production tags: # 标签 - key: tagKey value: tagValue apigw: # http 组件会默认帮忙创建一个 API 网关服务 isDisabled: false # 是否禁用自动创建 API 网关功能 # id: service-xxx # api 网关服务 ID,不填则自动新建网关 name: serverless # api 网关服务名称 api: # 创建的 API 相关配置 cors: true # 允许跨域 timeout: 30 # API 超时时间 name: apiName # API 名称 qualifier: $DEFAULT # API 关联的版本 protocols: - http - https environment: test
排除 node_modules
exclude: # 被排除的文件或目录 - .env - node_modules/** # deploy 时排除 node_modules [需要注意] 使用 layer 的 node_modules
配置层
layers: - name: ${output:${stage}:${app}:${name}-layer.name} # 配置对应的 layer version: ${output:${stage}:${app}:${name}-layer.version} # 配置对应的 layer 版本
通过配置层 layer,代码和 node_modules
分离, sls deploy
更快
接着执行命令 sls deploy --target=./layer
部署层,然后再次部署 sls deploy
看看速度应该更快了
每次 node_modules
改变都需要
- 执行
sls deploy --target=./layer
部署层, 更新node_modules
层 - 执行
sls deploy
重新部署
layer 的加载与访问
layer 会在函数运行时,将内容解压到 /opt
目录下,如果存在多个 layer
,那么会按时间循序进行解压。如果需要访问 layer
内的文件,可以直接通过 /opt/xxx
访问。如果是访问 node_module
则可以直接 import
,因为 scf
的 NODE_PATH
环境变量默认已包含 /opt/node_modules
路径。
使用 serverless fromwork 的高阶 egg 组件方式部署(不推荐)
目前推荐使用 web 函数,也就是 HTTP 组件
,现在所有的 serverless web 应用都是基于 component: http
组件的。
- 在项目根目录下创建
serverless.yml
文件
npm i serverless -g
# https://github.com/serverless-components/tencent-egg/blob/master/docs/configure.md # serverless.yml component: egg # (必选) 组件名称,在该实例中为 egg name: egg-demo # 必选) 组件实例名称. # org: orgDemo # (可选) 用于记录组织信息,默认值为您的腾讯云账户 appid,必须为字符串 app: egg-demo # (可选) 用于记录组织信息. 默认与 name 相同,必须为字符串 stage: dev # (可选) 用于区分环境信息,默认值是 dev inputs: region: ap-guangzhou # 云函数所在区域 functionName: egg-demo # 云函数名称 # serviceName: egg-demo # api 网关服务名称 runtime: Nodejs12.16 # 运行环境 # serviceId: service-np1uloxw # api 网关服务 ID # entryFile: sls.js # 自定义 server 的入口文件名,默认为 sls.js,如果不想修改文件名为 sls.js 可以自定义 # src: ./ # 第一种为 string 时,会打包 src 对应目录下的代码上传到默认 cos 上。 src: # 第二种,部署 src 下的文件代码,并打包成 zip 上传到 bucket 上 src: ./ # 本地需要打包的文件目录 # bucket: bucket01 # bucket name,当前会默认在 bucket name 后增加 appid 后缀, 本例中为 bucket01-appid exclude: # 被排除的文件或目录 - .env - "node_modules/**" # src: # 第三种,在指定存储桶 bucket 中已经存在了 object 代码,直接部署 # bucket: bucket01 # bucket name,当前会默认在 bucket name 后增加 appid 后缀, 本例中为 bucket01-appid # object: cos.zip # bucket key 指定存储桶内的文件 # layers: # - name: ${output:${stage}:${app}:egg-demo-layer.name} # 配置对应的 layer # version: ${output:${stage}:${app}:egg-demo-layer.version} # 配置对应的 layer 版本 functionConf: # 函数配置相关 timeout: 60 # 超时时间,单位秒 eip: false # 是否固定出口 IP memorySize: 512 # 内存大小,单位 MB environment: # 环境变量 variables: # 环境变量数组 NODE_ENV: production # vpcConfig: # 私有网络配置 # vpcId: '' # 私有网络的 Id # subnetId: '' # 子网 ID apigatewayConf: # api 网关配置 isDisabled: false # 是否禁用自动创建 API 网关功能 enableCORS: true # 允许跨域 # customDomains: # 自定义域名绑定 # - domain: abc.com # 待绑定的自定义的域名 # certificateId: abcdefg # 待绑定自定义域名的证书唯一 ID # # 如要设置自定义路径映射,请设置为 false # isDefaultMapping: false # # 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 # pathMappingSet: # - path: / # environment: release # protocols: # 绑定自定义域名的协议类型,默认与服务的前端协议一致。 # - http # 支持 http 协议 # - https # 支持 https 协议 protocols: - http - https environment: release # 网关环境 serviceTimeout: 60 # 网关超时 # usagePlan: # 用户使用计划 # usagePlanId: 1111 # usagePlanName: slscmp # usagePlanDesc: sls create # maxRequestNum: 1000 # auth: # 密钥 # secretName: secret # secretIds: # - xxx
- 将代码推送到云端
sls deploy # sls deploy --debug 可以查看日志
- 扫描登录部署会在项目下创建一个
.env
的serverless
的登录信息
- 部署成功,打开地址访问,此时会报错,我们没有把 node_modules 一起上传
浏览器打开提示缺少模块
我们在控制台上点击
打开自动安装依赖后重新部署即可看到 node_modules
,这时再次访问浏览器地址
3.4 sls 部署 nestjs 项目
模板部署 – 部署 Nest.js 示例代码
- 登录 Serverless 应用控制台 。
- 单击新建应用,选择 Web 应用>Nest.js 框架,如下图所示:
- 单击“下一步”,完成基础配置选择
- 上传方式,选择示例代码直接部署,单击完成,即可开始应用的部署。
- 部署完成后,您可在应用详情页面,查看示例应用的基本信息,并通过 API 网关生成的访问路径 URL 进行访问,查看您部署的 Nest.js 项目
自定义模板部署 nest(推荐)
初始化您的 Nest.js 项目
npm i -g @nestjs/cli nest new nest-app
在根目录下,执行以下命令在本地直接启动服务。
cd nest-app && npm run start
打开浏览器访问 http://localhost:3000,即可在本地完成 Nest.js 示例项目的访问。
部署上云
接下来执行以下步骤,对已初始化的项目进行简单修改,使其可以通过 Web Function 快速部署,此处项目改造通常分为以下两步:
- 新增
scf_bootstrap
启动文件。 - 修改监听地址与端口为
0.0.0.0:9000
。
- 修改启动文件
main.ts
,监听端口改为9000
:
- 在项目根目录下新建
scf_bootstrap
启动文件,在该文件添加如下内容(用于启动服务):
您也可以在控制台完成该模块配置。
# scf_bootstrap #!/bin/bash SERVERLESS=1 /var/lang/node12/bin/node ./dist/main.js
新建完成后,还需执行以下命令修改文件可执行权限,默认需要 777 或 755 权限才可正常启动。示例如下:
chmod 777 scf_bootstrap
本地配置完成后,执行启动文件,确保您的服务可以本地正常启动,接下来,登录 Serverless 应用控制台,选择 Web 应用>Nest.js 框架,上传方式可以选择本地上传或代码仓库拉取
注意:启动文件以项目内文件为准,如果您的项目里已经包含 scf_bootstrap 文件,将不会覆盖该内容。
使用 http 组件(推荐)
目前推荐使用 web 函数,也就是 HTTP 组件
,现在所有的 serverless web 应用都是基于 component: http
组件的。
详情查看: https://github.com/serverless-components/tencent-http
# 编写完善配置文件 serverless.yml # https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md app: nest-app # 应用名称 component: http # http 组件 name: nest-demo # 实例名称 inputs: region: ap-guangzhou # 云函数所在区域 src: # 部署当前目录下的文件代码,并打包成 zip 上传到 bucket 上 src: ./ # 当前目录 exclude: # 被排除的文件或目录 - .env - 'node_modules/**' # 忽略 node_modules,在控制台安装 # src: # 在指定存储桶 bucket 中已经存在了 object 代码,直接部署 # bucket: bucket01 # bucket name,当前会默认在 bucket name 后增加 appid 后缀, 本例中为 bucket01-appid # object: cos.zip # bucket key 指定存储桶内的文件 faas: # 函数配置相关 runtime: Nodejs12.16 # 运行时 # 支持的框架查看 https://cloud.tencent.com/document/product/1154/59447#framework framework: nestjs # #选择框架,此处以 egg 为例 name: ${name} # 云函数名称,通过变量形式获取 name 的值 timeout: 60 # 超时时间,单位秒 memorySize: 512 # 内存大小,默认 512 MB # layers: # - name: layerName # layer 名称 # version: 1 # 版本 environments: # 配置环境变量,同时也可以直接在 scf 控制台配置 - key: NODE_ENV value: production # vpc: # 私有网络配置 # vpcId: 'vpc-xxx' # 私有网络的 Id # subnetId: 'subnet-xxx' # 子网 ID # tags: # - key: tagKey # value: tagValue apigw: # http 组件会默认帮忙创建一个 API 网关服务 isDisabled: false # 是否禁用自动创建 API 网关功能 # id: service-xx # api 网关服务 ID,不填则自动新建网关 name: serverless # api 网关服务名称 api: # 创建的 API 相关配置 cors: true # 允许跨域 timeout: 30 # API 超时时间 name: apiName # API 名称 qualifier: $DEFAULT # API 关联的版本 protocols: - http - https environment: test # tags: # - key: tagKey # value: tagValue # customDomains: # 自定义域名绑定 # - domain: abc.com # 待绑定的自定义的域名 # certId: abcdefg # 待绑定自定义域名的证书唯一 ID # # 如要设置自定义路径映射,(customMap = true isDefaultMapping = false) 必须两者同时出现 其余情况都是默认路径 # customMap: true # isDefaultMapping: false # # 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 # pathMap: # - path: / # environment: release # protocols: # 绑定自定义域名的协议类型,默认与服务的前端协议一致。 # - http # 支持 http 协议 # - https # 支持 https 协议 # app: # 应用授权配置 # id: app-xxx # name: app_demo # description: app description
在项目根目录下新建 scf_bootstrap
启动文件,在该文件添加如下内容(用于启动服务):
#!/bin/bash SERVERLESS=1 /var/lang/node12/bin/node ./dist/main.js
忽略 node_modules
文件上传
# serverless.yml exclude: # 被排除的文件或目录 - .env - node_modules/**
执行 sls deploy
( sls deploy --debug
查看部署日志)
查看部署信息
sls info
实时开发并上传
每次改动文件,都实时部署
sls dev
删除部署项目
sls remove
使用 Layer 来减小项目文件大小
随着项目复杂度的增加, deploy
上传会变慢。所以,让我们再优化一下,在项目根目录创建 layer/serverless.yml
# layer/serverless.yml # https://cloud.tencent.com/document/product/1154/51133 # https://github.com/serverless-components/tencent-layer/blob/master/docs/configure.md app: nestjs-demo stage: dev component: layer # 组件 name: nestjs-demo-layer # 层名称 必须 # 组件参数配置,根据每个组件,实现具体的资源信息配置 inputs: name: nestjs-demo-layer region: ap-guangzhou src: src: ../node_modules targetDir: /node_modules runtimes: # 层支持的运行环境 - Nodejs12.16 description: layer description # 否 描述
修改以上项目下的 serverless.yml 加入层配置
回到项目根目录,调整一下根目录的 serverless.yml
下的 layers
# 编写完善配置文件 serverless.yml # https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md app: nestjs-demo # 应用名称 stage: dev component: http # http 组件 name: http-nestjs # 实例名称 inputs: src: # 部署当前目录下的文件代码,并打包成 zip 上传到 bucket 上 dist: ./ # build 后的包 hook: npm run build # 先构建在上传 exclude: # 排除的文件 - .env - node_modules/** # deploy 时排除 node_modules [需要注意] 使用 layer 的 node_modules src: ./ # 当前目录 faas: # 函数配置相关 runtime: Nodejs12.16 # 运行时 framework: nestjs # #选择框架,此处以 nestjs 为例 name: '${name}' # 云函数名称,通过变量形式获取 name 的值 eip: false timeout: 60 # 超时时间,单位秒 memorySize: 512 # 内存大小,默认 512 MB tags: [] environments: [] layers: # 配置对应的 layer - name: ${output:${stage}:${app}:nestjs-demo-layer.name} # 配置对应的 layer version: ${output:${stage}:${app}:nestjs-demo-layer.version} # 配置对应的 layer 版本 apigw: protocols: - http - https timeout: 60 environment: release customDomains: [] region: ap-guangzhou # 云函数所在区域 isAutoCiDeploy: false
排除 node_modules
exclude: # 被排除的文件或目录 - .env - node_modules/** # deploy 时排除 node_modules [需要注意] 使用 layer 的 node_modules
配置层
layers: # 配置对应的 layer - name: ${output:${stage}:${app}:nestjs-demo-layer.name} # 配置对应的 layer version: ${output:${stage}:${app}:nestjs-demo-layer.version} # 配置对应的 layer 版本
通过配置层 layer,代码和 node_modules
分离, sls deploy
更快
接着执行命令 sls deploy --target=./layer
部署层,然后再次部署 sls deploy
看看速度应该更快了
每次 node_modules
改变都需要
- 执行
sls deploy --target=./layer
先部署层, 更新node_modules
层 - 执行
sls deploy
重新部署
layer 的加载与访问
layer 会在函数运行时,将内容解压到 /opt
目录下,如果存在多个 layer
,那么会按时间循序进行解压。如果需要访问 layer
内的文件,可以直接通过 /opt/xxx
访问。如果是访问 node_module
则可以直接 import
,因为 scf
的 NODE_PATH
环境变量默认已包含 /opt/node_modules
路径。
使用 serverless framework 的高阶 nestjs 组件部署(不推荐)
目前推荐使用 web 函数,也就是 HTTP 组件
,现在所有的 serverless web 应用都是基于 component: http
组件的。
初始化项目
npm i -g @nestjs/cli nest new nest-app
在根目录下,执行以下命令在本地直接启动服务。
cd nest-app && npm run start
编写项目根目录下 serverless.yml 文件
全部配置详情
https://github.com/serverless-components/tencent-nestjs/blob/master/docs/configure.md
# serverless.yml component: nestjs # (必选) 组件名称,在该实例中为 nestjs name: nest-demo # 必选) 组件实例名称. # org: orgDemo # (可选) 用于记录组织信息,默认值为您的腾讯云账户 appid,必须为字符串 app: app-nest-demo # (可选) 用于记录组织信息. 默认与 name 相同,必须为字符串 stage: dev # (可选) 用于区分环境信息,默认值是 dev inputs: region: ap-guangzhou # 云函数所在区域 functionName: nest-demo # 云函数名称 serviceName: nest-demo # api 网关服务名称 runtime: Nodejs12.16 # 运行环境 # serviceId: service-jfdasew2112 # api 网关服务 ID 不填默认创建 # entryFile: sls.js # 自定义 server 的入口文件名,默认为 sls.js,如果不想修改文件名为 sls.js 可以自定义 # src: ./ # 第一种为 string 时,会打包 src 对应目录下的代码上传到默认 cos 上。 src: # 第二种,部署 src 下的文件代码,并打包成 zip 上传到 bucket 上 src: ./ # 本地需要打包的文件目录 # bucket: bucket01 # bucket name,当前会默认在 bucket name 后增加 appid 后缀, 本例中为 bucket01-appid exclude: # 被排除的文件或目录 - .env #- "node_modules/**" # src: # 第三种,在指定存储桶 bucket 中已经存在了 object 代码,直接部署 # bucket: bucket01 # bucket name,当前会默认在 bucket name 后增加 appid 后缀, 本例中为 bucket01-appid # object: cos.zip # bucket key 指定存储桶内的文件 # layers: # - name: ${output:${stage}:${app}:${name}-layer.name} # 配置对应的 layer # version: ${output:${stage}:${app}:${name}-layer.version} # 配置对应的 layer 版本 functionConf: # 函数配置相关 timeout: 60 # 超时时间,单位秒 eip: false # 是否固定出口 IP memorySize: 512 # 内存大小,单位 MB environment: # 环境变量 variables: # 环境变量数组 NODE_ENV: production # vpcConfig: # 私有网络配置 # vpcId: '' # 私有网络的 Id # subnetId: '' # 子网 ID apigatewayConf: # api 网关配置 isDisabled: false # 是否禁用自动创建 API 网关功能 enableCORS: true # 允许跨域 # customDomains: # 自定义域名绑定 # - domain: abc.com # 待绑定的自定义的域名 # certificateId: abcdefg # 待绑定自定义域名的证书唯一 ID # # 如要设置自定义路径映射,请设置为 false # isDefaultMapping: false # # 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 # pathMappingSet: # - path: / # environment: release # protocols: # 绑定自定义域名的协议类型,默认与服务的前端协议一致。 # - http # 支持 http 协议 # - https # 支持 https 协议 protocols: - http - https environment: test # 网关环境 serviceTimeout: 60 # 网关超时 # usagePlan: # 用户使用计划 # usagePlanId: 1111 # usagePlanName: slscmp # usagePlanDesc: sls create # maxRequestNum: 1000 # auth: # 密钥 # secretName: secret # secretIds: # - xxx
3.5 sls 部署 koa 项目
控制台部署
- 登录 Serverless 应用控制台 。
- 单击新建应用,选择 Web 应用>Koa 框架,如下图所示:
- 单击“下一步”,完成基础配置选择。
- 上传方式,选择示例代码直接部署,单击完成,即可开始应用的部署。
- 部署完成后,您可在应用详情页面,查看示例应用的基本信息,并通过 API 网关生成的访问路径 URL 进行访问,查看您部署的 Koa 项目
自定义模板部署
全局安装 koa-generator
脚手架.
npm install -g koa-generator
创建项目
# 使用 ejs 引擎 koa2 -e koa-demo
cd koa-demo // 进入项目根目录 npm install // 安装项目依赖
npm start
部署上云
接下来执行以下步骤,对已初始化的项目进行简单修改,使其可以通过 Web Function 快速部署,此处项目改造通常分为以下两步:
- 修改监听地址与端口为
0.0.0.0:9000
。
具体步骤如下:
在 Koa 示例项目中,修改监听端口到 9000
使用 HTTP 组件部署
编写 serverless.yml
# 文档 https://github.com/serverless-components/tencent-http/blob/master/docs/configure.md # https://cloud.tencent.com/document/product/1154/59447 # org: '1258157827' app: koa-demo stage: dev component: http # http 组件 name: koa-demo inputs: src: src: ./ exclude: # 排除文件,在控制台 WEBIDE 开启自动安装依赖 - .env - node_modules region: ap-guangzhou isAutoCiDeploy: false faas: runtime: Nodejs12.16 eip: false timeout: 30 memorySize: 512 tags: [] framework: koa # koa 框架 environments: [] # layers: # - name: '${output:${stage}:${app}:koa-demo-layer.name}' # version: '${output:${stage}:${app}:koa-demo-layer.version}' apigw: timeout: 60 protocols: - http - https environment: release customDomains: []
项目根目录新增 scf_bootstrap 启动文件
touch scf_bootstrap # 还需执行以下命令修改文件可执行权限,默认需要 777 或 755 权限才可正常启动 chmod 777 scf_bootstrap
scf_bootstrap
#!/bin/bash /var/lang/node12/bin/node bin/www # 修改入口为 bin/www,并且修改 bin/www 下端口为 9000
部署
sls deploy
查看部署信息
sls info
移除
sls remove
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论