由于函数计算的运行环境(Linux debian9 或 debian10)与本地的开发环境可能存在比较大的不同,这就导致一部分本地安装/构建的依赖(比如第三方库)或代码包,在线上无法正常运行,所以,Serverless Devs 开发者工具在 build
命令中,通过本地的启动 Docker 容器的能力,在容器中进行项目的构建,以尽可能地保证构建出来的依赖/产物,在线上可以得到良好的使用。
⚠️ 注意:该命令对 Docker 有所依赖,所以在使用该命令时,需要先进行 Docker 安装,版本 >= 19.03。
目前支持的能力如下:
不同的运行时,在进行依赖安装/项目构建的时候,可能会有不同的依赖描述文件,其系统默认的对应关系如下:
⚠️ 注意:在部分语言完成项目构建之后,部署的时候可能会出现交互式操作,提醒用户是否要将安装的依赖路径加入到环境变量中,以便线上可以正确的加载到这些依赖内容。此时可以通过交互式的方法,根据提醒输入y
,也可以在部署时通过-y
命令,默认进行环境变量等内容的添加。
apt-get.list 是非 Custom Container 的 runtime 均可以使用,详情见 apt-get.list 文件, 是一个可选项,绝大部分场景不需要。
命令解析
当执行命令build -h
/build --help
时,可以获取帮助文档。
参数解析
参数全称 | 参数缩写 | 参数含义 |
---|
publish-layer | 无 | 将构建后的产物发布成一个 layer |
use-sandbox | 无 | 进入对应 runtime 的 sandbox 容器 |
custom-env | 无 | build 时注入的自定义环境变量 |
custom-args | 无 | 使用默认 build 行为时的附加参数, 比如指定 pypi 或者 npm 源, 需要配合 use-docker 或 use-buildkit 使用, 默认是 use-docker |
command | 无 | 使用自定义命令 |
script-file | 无 | 使用自定义脚本 |
dockerfile | f | 指定构建自定义镜像的文件, 构建 custom-container runtime 的镜像时使用 |
context | 无 | custom-container 构建镜像时上下文, 构建 custom-container runtime 的镜像时使用 |
当前命令还支持部分全局参数(例如-a/--access
, --debug
, --help
等),详情可参考 Serverless Devs 全局参数文档
操作案例
基础操作
以 Python 应用为例:在具有 requirements.txt
的 Python 项目下,可以通过s build
命令实现依赖安装:
Step1. 开发编辑源代码
Step2. s build
之后, 自动根据 requirements.txt
和 apt-get.list
下载对应的依赖到本地, 并且和源码一起组成交付物,同时会提示完成依赖包的环境变量配置:
Step3. 按照提示在 s.yaml 中完成依赖包的环境变量配置 s.yaml#L19-L22, 然后执行 s deploy
将整个交付物 zip 打包, 创建函数
最佳实践:
如果您觉的函数代码包过大, 影响您的部署效率, 您可以将您的构建的第三方包直接发布成一个层, 然后在 s.yaml 中引入这个层即可。只需执行 s build --publish-layer
, 您可以在输出日志看到如下提示:
该命令同时在您 yaml 指定的 code 目录下面自动增加了 .fcignore 文件,这样您的函数代码包就可以大大减小,提高部署效率,毕竟第三方依赖的构建变动是不频繁的。
Tips:
- 在 build 过程中注入自定义环境变量和使用指定的 pypi 源, 可以使用如下命令
s build --custom-env '{"myenv": "test"}' --custom-args='-i https://pypi.tuna.tsinghua.edu.cn/simple'
- 如果不想使用
s build
的默认行为
- 2.1 直接输入命令
s build --command="pip install -t . flask -i https://pypi.tuna.tsinghua.edu.cn/simple"
, command 工作的目录对应您 s.yaml 指定的 codeUri
- 2.2 直接输入命令
s build --script-file my_script.sh
, my_script.sh 工作的目录对应您 s.yaml 指定的 codeUri
Node.js 项目、PHP 项目与 Python 项目类似,都是在开发代码之后,可以通过s build
进行依赖安装,此时工具将会自动根据相关依赖文件(例如 Node.js 是 package.json
,PHP 是composer.json
)下载对应的依赖到本地, 并且和源码一起组成交付物,同时会提示完成依赖包的环境变量配置; 按照提示完成配置,接下来可以通过s deploy
进行项目部署,此时工具会将整个交付物 ZIP 打包, 创建函数,让函数可以直接 require
对应的代码依赖包。
Custom Container,则是需要先开通 ACR/CR 容器镜像服务,然后在s.yaml
的image
字段处填写好acr
镜像地址,通过s build --dockerfile ./Dockerfile
进行项目构建;接下来可以通过s deploy -y
将项目部署到线上,此时工具会自动先将构建完成的镜像推送到 ACR 服务,然后再进行函数的创建, 示例可参考 custom-container example
💡 在使用build
命令时,可以通过环境变量 FC_DOCKER_VERSION
控制镜像的版本,例如 export FC_DOCKER_VERSION=3.0.0(所有可用版本可查看 https://hub.docker.com/u/aliyunfc ), 对于 fc3 组件来说, 使用的 FC_DOCKER_VERSION 大于等于 3.0.0
💡 在代码包的场景中, 除了各自语言的库以外, 其实还有更加复杂的情况,例如,在函数计算的 Python Runtime 想使用 jq 这个工具, 此时还需要 apt-get.list 的支持。
高阶自定义操作 use-sandbox
为了满足用户自定义操作, Serverless Devs 开发者工具在 build
命令中,增加了 --use-sandbox
的命令, 只要输入:
Serverless Devs 开发者工具会根据您 s.yaml
中的 runtime, 自动拉起一个模拟线上 runtime 的真实容器, 并且将您 s.yaml 中的 codeUri
指定的目录挂载到容器的 /code
目录下面,之后您可以在容器里面执行 npm install
等满足您自己需求的命令。
在这里推荐使用内置 apt-get-install 工具解决您可能遇见的高阶难题,比如:
第三方 lib 依赖底层的 so 文件
比如在 nodejs14 runtime 部署 puppeteer 应用,但是 puppeteer 依赖的一些底层 so 库在 nodejs14 runtime 中不存在, 可以借助 apt-get-install 完成我们的目标:
如上所示,so 底层 lib 全部安装到 apt-archives 目录下面, 为了使函数能正确使用到这些 so 文件, 最后 deploy 的时候给函数增加下面两个环境变量即可:
apt-get.list
此文件顾名思义,就是声明可以使用 apt-get 命令安装函数计算 runtime 环境没有的系统包。
使用方式是在 code 目录的根目录下,创建一个 apt-get.list 的文件,文件内容如下所示。然后部署之前执行 s build
即可。