云引擎网站托管指南
网站托管是云引擎的一个子模块,允许你用各种程序语言开发 Web 程序,提供云函数和 Hook,还可以提供静态文件的托管和自定义的路由、绑定你自己的域名。 你可以用它为你的移动应用提供一个介绍和下载页、开发一个管理员控制台或完整的网站,或者运行一些必须在服务器端运行的自定义逻辑。
云引擎支持 Node.js、Python、PHP、Java、.NET、Go,你可以选择自己熟悉的技术栈进行开发。
从示例项目开始
我们为云引擎支持的各种语言准备了示例项目,建议从示例项目着手开始开发。
要理解如何从示例项目开始开发云引擎项目,本地调试,部署到云端,请先阅读云引擎快速入门。
本地运行和调试
在确保所有的依赖都正确安装之后,就可以在项目根目录用我们的命令行工具来启动本地调试了:
tds up
更多有关命令行工具和本地调试的内容请看云引擎命令行工具使用指南。
部署到云端
在你的项目根目录运行:
tds deploy
如果生产环境是标准实例,需要加上 --prod 1
参数,指定部署到生产环境:
tds deploy --prod 1
你可以在控制台绑定云引擎域名,绑定域名后,即可通过绑定域名访问你的应用。
例如,假定你在控制台绑定了 web.example.com
这个域名,即可通过 https://web.example.com
访问你的应用(生产环境)。
注意,DNS 可能需要等待几个小时后才能生效。
项目骨架
- JavaScript
- Python
- PHP
- Java
- C#
- Go
以示例项目为例,在根目录我们看到有一个 package.json
文件,注意:所有 Node.js 的项目必须包含 package.json
才会正确地被云引擎识别为 Node.js 项目。
package.json
Node.js 的 package.json
中可以指定 很多选项,它通常看起来是这样:
{
"name": "node-js-getting-started",
"scripts": {
"start": "node server.js"
},
"engines": {
"node": "12.x"
},
"dependencies": {
"express": "4.16.4",
"leanengine": "^3.3.2",
"leancloud-storage": "^3.11.0"
}
}
其中云引擎会尊重的选项包括:
scripts.start
启动项目时使用的命令;默认为node server.js
,如果你希望为 Node.js 附加启动选项(如--es_staging
)或使用其他的文件作为入口点,可以修改该选项。scripts.postinstall
会在项目构建结 束时运行一次;可以将构建命令(如gulp build
)写在这里。engines.node
指定所需的 Node.js 版本;出于兼容性考虑默认版本仍为比较旧的0.12
,因此建议大家自行指定一个更高的版本,建议使用12.x
版本进行开发,你也可以设置为*
表示总是使用最新版本的 Node.js。dependencies
项目所依赖的包;使用 Node.js 10 以上的版本时,云引擎会在部署时用npm ci
为你安装这里列出的所有依赖。devDependencies
项目开发时所依赖的包;使用 Node.js 10 以上的版本时,云引擎会安装这里的依赖。
建议你参考我们的 项目模板 来编写自己的 package.json
。
我们也对 package-lock.json
和 yarn.lock
提供了支持。
参照示例项目,你的项目需要遵循一定格式才会被云引擎识别并运行。
使用 WSGI 规范来运行项目,项目根目录下必须有 wsgi.py
与 requirements.txt
文件,可选文件 .python-version
、runtime.txt
。云引擎运行时会首先加载 wsgi.py
这个模块,并将此模块的全局变量 application
作为 WSGI 函数进行调用。因此请保证 wsgi.py
文件中包含一个 application
的全局变量/函数/类,并且符合 WSGI 规范。
例如,一个最简单的基于 Flask 框架的项目只需两个文件(requirements.txt
除外,不考虑本地调试功能):
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "hi"
# wsgi.py
from app import app
application = app
更多关于 WSGI 函数 的内容,请参考 PEP333。
兼容 Python WSGI 规范的框架都可以在云引擎运行。目前比较流行的 Python Web 框架对此都有支持,比如 Flask、Django、Tornado。我们提供了 Flask 和 Django 两个框架的示例项目作为参考,你也可以直接把它们当作一个应用项目的初始化模版:
添加第三方依赖模块
requirements.txt
中填写项目依赖的第三方模块,每行一个,如:
# 井号至行尾为注释
leancloud>=2.9.1,<3.0.0
Flask>=1.0.0 # 可以指定版本号/范围
git+https://github.com/foo/bar.git@master#egg=bar # 可以使用 Git/SVN 等版本管理工具的远程地址
详细格式请参考 pip 19.0.1 Documentation > User Guide > Requirements Files。
应用部署到云引擎之后,会自动按照 requirements.txt
中的内容进行依赖安装。在本地运行和调试项目的时候,可以在项目目录下使用如下命令安装依赖:
pip install -r requirements.txt
另外当你部署应用的时候,建议将依赖的包的版本都按照 foo==1.0.0
这种格式来明确指定版本号(或版本的范围),防止因为依赖的模块升级且不再兼容老的 API 时,再次部署会导致应用运行失败。
指定 Python 版本
你可以选择运行代码的 Python 版本,选择方法与 pyenv
相同,即在项目根目录的 .python-version
中写入需要的 Python 版本即可,比如 3.6.1
。这样将代码部署到云引擎之后,系统会自动选择对应的 Python 版本。
如果在本地开发时已使用了 pyenv
,pyenv
也会根据此文件来自动使用对应的 Python 运行项目。我们建议本地开发使用 pyenv
,以保证本地环境与线上相同。pyenv
的安装方法请参考 pyenv
的 GitHub 仓库。
你的项目需要遵循一定格式才会被云引擎识别并运行。
LeanEngine PHP 项目必须有 $PROJECT_DIR/public/index.php
文件,该文件为整个项目的启动文件。
云引擎默认提供 PHP 5.6 的运行环境,如需指定 PHP 版本,请在 composer.json
中添加:
"require": {
"php": "7.4.x"
}
LeanEngine PHP 不依赖第三方框架,你可以使用你最熟悉的框架进行开发,或者不使用任何框架。但是请保证通过执行 public/index.php
能够启动你的项目。
在项目中存在 composer.lock
文件时,云引擎会优先根据 composer.lock 安装依赖。
云引擎目前支持 Java 8、11、12、13、14 运行环境和 war 包运行,你的项目需要遵循一定格式才会被云引擎识别并运行。
云引擎 Java 运行环境使用 Maven 进行构建,所以 LeanEngine Java 项目必须有 $PROJECT_DIR/pom.xml
文件,该文件为整个项目的配置文件。构建完成后云引擎会尝试到 $PROJECT_DIR/target
目录下寻找可以使用的包:
- WAR:如果项目打包成 WAR 文件,则云引擎会将其放入 Servlet 容器(当前是 Jetty 9.x)来运行。
- JAR:如果项目打包成 JAR 文件,则云引擎会通过
java -jar <packageName>.jar
来运行。
我们建议使用示例项目做为起步,因为一些细节的开发环境的配置会让开发调试方便很多:
java-war-getting-started
:使用 Servlet,集成 LeanEngine Java SDK 的一个简单项目,打包成 WAR 文件。spring-boot-getting-started
:使用 Spring Boot 作为项目框架,集成 LeanEngine Java SDK 的一个简单的项目,打包成 JAR 文件。
Java 运行环境对内存的使用较多,所以建议:
- 以 示例项目 起步的应用,建议使用 512 MB 或以上规格的实例。
- 使用 Spring Boot 的应用,建议使用 1 GB 或以上规格的实例。
- 本地启动并模拟完成主要业务流程操作,待应用充分初始化后,根据 Java 进程内存占用量选择相应的实例规格,需要注意保留一定的余量用以应对请求高峰。
如果云引擎实例规格选择不当,可能造成应用启动时因为内存溢出(OOM)导致部署失败,或运行期内存溢出导致应用频繁重启。
Java 云引擎默认使用 Java 11 运行环境,如果希望使用其他版本的 Java,可以在项目根目录创建一个名为 system.properties
的文件,指定 java.runtime.version
:
java.runtime.version=14
打包成 WAR 文件的项目
首先确认项目 pom.xml
中配置了 Jetty plugin,并且 web server 的端口通过环境变量 LEANCLOUD_APP_PORT
获取 ,具体配置可以参考我们的 示例代码。
然后使用 Maven 安装依赖并打包:
mvn package
然后使用命令行工具本地启动应用:
tds up
更多有关命令行工具和本地调试的内容请参考云引擎命令行工具使用指南。
除了使用命令行工具本地启动应用外,还可以手动设置相应环境变量后,直接启动应用,详见云引擎 FAQ。
为了更为简洁的支持 .NET Core 的 Web 项目,云引擎要求您的源代码目录如下:
├── app.sln
├── web
| ├── StartUp.cs
| ├── Program.cs
| ├── web.csproj
| └── wwwroot
| ├── css
| ├── lib
| └── js
└── global.json
示例项目 dotNET-getting-started
是推荐的模板。
其中根目录必须拥有一个 app.sln
解决方案文件 和一个 web/
文件夹,这是必须的(这一硬性规定会将在未来取消,取消之后开发者自定义自己的项目结构)。
你的 Go 程序需要使用 Go Modules 才能被云引擎识别。
云引擎默认提供 Go 1.14.0 的运行环境。
你可以使用你最熟悉的框架或不使用任何框架来开发 Go 程序,但需要将 Go SDK 中提供的云引擎中间件正确地接入你的程序中。
使用数据存储服务
在云引擎中你可以使用云服务提供的数据存储作为应用的后端数据库,以及使用其他云服务提供的功能。 SDK 可以让你更加方便地使用这些功能。
建 议使用云引擎模板项目。 模板项目已经集成了 SDK,也包含了初始化 SDK 的逻辑,可以直接使用。
建议在客户端(浏览器端、移动端)登录用户,调用 SDK 的接口获取 session token。 对于需要后端以当前用户的身份完成的操作,客户端通过 HTTP Header 等方式将 session token 发送给后端。
参见数据存储指南。
健康监测
你的应用在启动时,云引擎的管理程序会每秒去检查你的应用是否启动成功,如果超过启动时间限制仍未启动成功,即认为启动失败。 在之后应用正常运行的过程中,也会有定期的「健康监测」,以确保你的应用正常运行,如果健康监测失败,云引擎管理程序会自动重启你的应用。
健康检查的 URL 包括你的应用首页(/
)和 SDK 负责处理的 /__engine/1/ping
,只要 两者之一 返回了 HTTP 200
的响应,就视作成功。
因此请确保你的应用使用了 SDK,或你的应用 首页能够正常地返回 HTTP 200
响应。
部署与发布
命令行部署
在你的项目根目录运行:
tds deploy
即可部署至预备环境。
之后运行 tds publish
可以将预备环境的代码发布到生产环境。
注意,免费版只有一个环境,tds deploy
会直接部署到生产环境。
使用命令行工具可以非常方便地部署、发布应用,查看应用状态,查看日志,甚至支持多应用部署。 具体使用请参考《命令行工具指南》。
依赖缓存
云引擎实现了一个缓存机制来加快构建的速度,所谓构建就是指你的应用在云引擎上安装依赖的过程,在每次构建时,如果依赖没有新增或者删减,那么就直接使用上次安装的依赖,只将新的应用代码替换上去。
例如 Node.js 项目连续两次部署,package.json
并没有修改,那么就会直接使用已经缓存的依赖。
依赖缓存也会因为很多原因失效,因此不保证每次构建都可以利用上缓存。
如果你遇到了与依赖安装有关的问题,可以在控制 台部署时勾选「下载最新依赖」,或通过命令行工具部署时添加 --no-cache
选项。
tds deploy --no-cache
Git 部署
除此之外,还可以使用 git 仓库部署。你需要将项目提交到一个 git 仓库,我们并不提供源码的版本管理功能,而是借助于 git 这个优秀的分布式版本管理工具。我们推荐你使用 GitHub、Coding 或者 码云 这样第三方的源码托管网站,也可以使用你自己搭建的 git 仓库(比如 GitLab)。
你需 要先在这些平台上创建一个项目(如果已有代码,请不需要选择「Initialize this repository with a README」),在网站的个人设置中填写本地机器的 SSH 公钥(以 GitHub 为例,在 Settings > SSH and GPG keys 中点击 New SSH key),然后在项目目录执行:
git remote add origin git@github.com:<username>/<repoName>.git
git push -u origin master
然后到云引擎的设置界面填写你的 Git 仓库地址,如果是公开仓库建议填写 HTTPS 地址,例如 https://github.com/<username>/<repoName>.git
。
如果是私有仓库需要填写 SSH 地址(git@github.com:<username>/<repoName>.git
),还需要你将云引擎分配给你的公钥填写到第三方托管平台的 Deploy keys 中,以 GitHub 为例,在项目的 Settings > Deploy keys 中点击 Add deploy key。
设置好之后,今后需要部署代码时就可以在云引擎的部署界面直接点击「部署」了,默认会部署 master
分支的代码,你也可以在部署时填写分支、标签或具体的 Commit。
如果仓库使用了 submodule,云引擎也会自动拉取 submodule。
如果希望 push 到项目的 Git 仓库的特定分支后自动触发云引擎部署,可以在应用的 云服务控制台 > 云引擎 > 部署 > git 部署 > 自动部署 查看 deploy token 和 webhook 地址。 控制台显示的 deploy token 可以用来构造 HTTP 请求触发部署。 在控制台填写项目仓库的分支名称,并选择云引擎的运行环境后,控制台会生成相应的 webhook 地址。 该地址收到任意 POST 请求后,会部署指定分支的代码到指定的运行环境。
例如,在 GitHub 代码仓库的 Settings > Webhooks > Payload URL 填写生成的 webhook 后(其他选项均使用默认值,不用修改),下次 push 到项目仓库的 任意 分支,云引擎会自动根据 指定 分支更新代码,重新部署。之所以 push 到任意分支都会触发重新部署,是因为 GitHub 的 webhook 触发事件设置粒度较粗,不能指定仅在 push 到特定分支时触发 webhook。另一方面,云引擎也没有适配具体的托管平台,不会根据 GitHub 提交的 POST 内容中的分支信息决定是否重新部署。 不过,你可以使用 GitHub Action 更精细地控制部署时机,具体可以参考控制台显示的示例。
预备环境和生产环境
默认情况,云引擎只有一个「生产环境」。在生产环境中有一个「体验实例」来运行应用。
当生产环境的体验实例升级到「标准实例」后会有一个额外的「预备环境」。两个环境所访问的都是同样的数据,你可以用预备环境测试你的云引擎代码,每次修改先部署到预备环境,测试通过后再发布到生产环境;如果你希望有一个独立数据源的测试环境,建议单独创建一个应用。
在云引擎托管的网站需要绑定域名才能访问。
以 stg-
开头的域名会自动绑定到预备环境。
如果访问云引擎遇到「Application not Found」的错误,通常是因为对应的环境还没有部署代码。例如应用可能没有预备环境,或应用尚未发布代码到生产环境。
有些时候你可能需要知道当前云引擎运行在什么环境(开发环境、预备环境或生产环境),从而做不同的处理。
Node.js 项目可以通过检查环境变量 NODE_ENV
的值来判断:值为 development
意味着当前环境为「开发环境」,是由命令行工具启动的;值为 production
意味着当前环境为「生产环境」,是线上正式运行的环境;值为 staging
意味着当前环境为「预备环境」。
其他语言的项目可以通过检查环境变量 LEANCLOUD_APP_ENV
的值来判断:值为 development
意味着当前环境为「开发环境」,是由命令行工具启动的;值为 production
意味着当前环境为「生产环境」,是线上正式运行的环境;值为 stage
意味着当前环境为「预备环境」。
部署历史
在