引入 deployctl,Deno Deploy 的命令行界面
许多后端工程师更喜欢通过命令行界面管理基础设施和部署,尤其是在构建CI/CD脚本时,所有设置和配置都可以通过标志和代码表示。在Deno Deploy上管理项目也不例外——借助 deployctl
,您现在无需离开终端即可管理部署的整个生命周期。
本篇博文将介绍 deployctl
的一些关键功能,并向您展示如何在更复杂的场景中使用 deployctl
。
⚠️ 体验将 JavaScript 和 TypeScript 部署到云端的最快方式。 立即注册免费的 Deno Deploy 账户。
云部署的最简之路
使用 deployctl
部署代码,您唯一需要的是 Deno 和一个 GitHub 账户。如果您还没有免费的 Deno Deploy 账户,请不用担心,首次部署时会自动创建一个。让我们使用以下命令安装 deployctl
$ deno install -A jsr:@deno/deployctl
就这样!您可以立即开始部署代码。如果您想验证 deployctl
是否已正确安装,可以运行 deployctl --version
命令。
$ deployctl 1.12.0
为了演示使用 deployctl
部署代码有多么简单,我们将在本地使用 Hono 和 Deno 创建一个 hello-world API 服务器。
$ deno run -A npm:create-hono
在模板选择步骤中,选择“Deno”。
$ create-hono version 0.3.2
✔ Target directory … my-new-app
? Which template do you want to use? › - Use arrow-keys. Return to submit.
aws-lambda
bun
cloudflare-pages
cloudflare-workers
❯ deno
fastly
lambda-edge
netlify
nextjs
↓ nodejs
完成后,您应该在 main.ts
文件中拥有一个非常简单的Web服务器。
import { Hono } from "https://deno.land/x/hono@v4.0.10/mod.ts";
const app = new Hono();
app.get("/", (c) => {
return c.text("Hello Hono!");
});
Deno.serve(app.fetch);
让我们使用 deployctl deploy
将其部署到 Deno Deploy。
$ deployctl deploy
ℹ Using config file '/private/tmp/my-new-app/deno.json'
⚠ No project name or ID provided with either the --project arg or a config file.
✔ Guessed project name 'my-new-app'.
ℹ You can always change the project name with 'deployctl projects rename new-name' or in https://dash.deno.com/projects/my-new-app/settings
⚠ No entrypoint provided with either the --entrypoint arg or a config file. I've guessed 'main.ts' for you.
ℹ Is this wrong? Please let us know in https://github.com/denoland/deployctl/issues/new
✔ Deploying to project my-new-app.
ℹ The project does not have a deployment yet. Automatically pushing initial deployment to production (use --prod for further updates).
✔ Entrypoint: /private/tmp/my-new-app/main.ts
ℹ Uploading all files from the current dir (/private/tmp/my-new-app)
✔ Found 4 assets.
✔ Uploaded 4 new assets.
✔ Production deployment complete.
✔ Updated config file '/private/tmp/my-new-app/deno.json'.
View at:
- https://my-new-app-614p8p26b2sg.deno.dev
- https://my-new-app.deno.dev
如果这是您第一次使用 deployctl
,浏览器将提示您注册 Deno Deploy 账户和/或通过您的 GitHub 账户授权 deployctl
访问您的 Deno Deploy 账户。部署完成后,访问其中一个 URL 即可看到您的新 Hono 服务器。
是不是很简单?几分钟内,您就在全球的数据中心上创建并部署了一个 API,并获得了访问它的 URL。
管理您的项目
首次部署时,deployctl deploy
会尝试为您的项目及其入口点确定一个名称。如果项目尚不存在,它将自动创建。如果您对自动选择的名称不满意,始终可以使用 deployctl projects rename <new-name>
进行更改。
$ deployctl projects rename my-new-api
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Project 'my-new-app' (488faa31-f687-4c9a-a082-d73cb0336b41) found
✔ Project 'my-new-app' renamed to 'my-new-api'
💡️ 专业提示!
您始终可以使用
--project
和--entrypoint
标志指定项目和入口点。
首次成功部署后,您会注意到 deno.json
现在包含一个新的 deploy
键,其中包含一些配置详细信息。
{
"tasks": {
"start": "deno run --allow-net main.ts"
},
"deploy": {
"project": "488faa31-f687-4c9a-a082-d73cb0336b41",
"exclude": [
"**/node_modules"
],
"include": [],
"entrypoint": "main.ts"
}
}
从现在开始,deployctl
将使用此配置,除非您使用命令行标志覆盖它。
接下来,让我们看看可以使用 deployctl projects show
获取有关我们新项目的哪些信息。
$ deployctl projects show
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Project '488faa31-f687-4c9a-a082-d73cb0336b41' found
my-new-api
----------
Organization: Blog Post (ba7ef0e0-0a75-43f6-8aa1-db0897d693ba)
Domain(s): https://my-new-api.deno.dev
Dash URL: https://dash.deno.com/projects/488faa31-f687-4c9a-a082-d73cb0336b41
Databases: [*] cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7
Deployments: 119n5q18cjrf*
在这里,我们可以看到项目创建的组织,以及 KV 数据库 ID (cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7
)。如果我们想远程连接到它,可以使用此ID。
我们还可以看到刚刚创建的部署。让我们使用 deployctl deployments show
命令查看其详细信息。
$ deployctl deployments show
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ The production deployment of the project 'my-new-api' is '119n5q18cjrf'
✔ The details of the deployment '119n5q18cjrf' are ready:
119n5q18cjrf
------------
Status: Production
Date: 1 hour, 4 minutes, 41 seconds ago (13/3/2024 13:36:49 CET)
Project: my-new-api (488faa31-f687-4c9a-a082-d73cb0336b41)
Organization: Blog Post (ba7ef0e0-0a75-43f6-8aa1-db0897d693ba)
Domain(s): https://my-new-api.deno.dev
https://my-new-app-119n5q18cjrf.deno.dev
Database: Production (cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7)
Entrypoint: main.ts
Env Vars: HOME
再次部署
让我们对项目进行快速更新并再次部署。我们将把服务器的响应从“Hello Hono”更改为“Hello Deno”,并记录部署时间。
import { Hono } from "https://deno.land/x/hono@v4.1.0/mod.ts";
console.log(
"Deployed at",
new Date(Deno.env.get("DEPLOYMENT_TS")).toLocaleString(),
);
const app = new Hono();
app.get("/", (c) => {
return c.text("Hello Deno!");
});
Deno.serve(app.fetch);
为了记录部署时间,我们获取环境变量 DEPLOYMENT_TS
。此变量可以在部署时通过 --env
标志设置。
$ deployctl deploy --env DEPLOYMENT_TS=$(date -Iseconds)
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Deploying to project my-new-api.
✔ Entrypoint: /private/tmp/my-new-app/main.ts
ℹ Uploading all files from the current dir (/private/tmp/my-new-app)
✔ Found 5 assets.
✔ Uploaded 4 new assets.
✔ Preview deployment complete.
ℹ Some of the config used differ from the config found in '/private/tmp/my-new-app/deno.json'. Use --save-config to overwrite it.
View at:
- https://my-new-api-bdhq0vjwfrdq.deno.dev
我们可以使用 deployctl deployments show --last
获取上次部署的详细信息。
$ deployctl deployments show --last
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ The last deployment of the project '488faa31-f687-4c9a-a082-d73cb0336b41' is 'bdhq0vjwfrdq'
✔ The details of the deployment 'bdhq0vjwfrdq' are ready:
bdhq0vjwfrdq
------------
Status: Preview
Date: 9 minutes, 43 seconds ago (13/3/2024 15:04:23 CET)
Project: my-new-api (488faa31-f687-4c9a-a082-d73cb0336b41)
Organization: Blog Post (ba7ef0e0-0a75-43f6-8aa1-db0897d693ba)
Domain(s): https://my-new-api-bdhq0vjwfrdq.deno.dev
Database: Production (cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7)
Entrypoint: main.ts
Env Vars: DEPLOYMENT_TS
HOME
请注意,此部署处于“预览”状态,并且只有一个 URL。除了第一次部署外,默认情况下,部署都会以预览模式创建,这意味着它们只能通过其预览域名访问。生产域名 (https://my-new-api.deno.dev) 仍然指向我们之前创建的部署。
💡️ 专业提示!
如果您将 deployctl 命令的输出通过管道传递,您将获得 JSON 格式的数据。例如,您可以使用
deployctl deployments show --last | jq -r '.build.deployment.domainMappings.[0].domain'
以编程方式获取部署的域名 👇️$ curl https://$(deployctl deployments show --last | jq -r '.build.deployment.domainMappings.[0].domain') Hello Deno!
如果我们查询新部署的 URL,我们将得到新的响应。现在让我们检查部署时间是否正确记录。
可观测性
要查看部署的日志,我们将使用 deployctl logs
。由于我们正在查看预览部署,我们需要告诉 deployctl
我们要查询哪个特定部署的日志。
deployctl logs --deployment=bdhq0vjwfrdq
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ The last deployment of the project '488faa31-f687-4c9a-a082-d73cb0336b41' is 'bdhq0vjwfrdq'
✔ The details of the deployment 'bdhq0vjwfrdq' are ready:
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Project: my-new-api
2024-03-13T20:01:10.796523742Z gcp-europe-west3 Deployed at 3/13/2024, 2:04:14 PM
2024-03-13T20:01:10.799512774Z gcp-europe-west3 Listening on https://:80/
2024-03-13T20:01:10.801337034Z gcp-europe-west3 isolate start time: 287.60 ms (user time: 784.10 µs)
完美!我们对环境变量的日志记录运行良好。现在让我们检查一下部署的资源消耗是否正常。为此,我们可以使用 deployctl top
。
$ deployctl top
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Connected to the stats stream of project '488faa31-f687-4c9a-a082-d73cb0336b41'
┌────────┬────────────────┬────────────────┬─────────┬──────┬─────────┬──────────┬─────────────┬────────────┬─────────┬─────────┬───────────┬───────────┐
│ (idx) │ deployment │ region │ Req/min │ CPU% │ CPU/req │ RSS/5min │ Ingress/min │ Egress/min │ KVr/min │ KVw/min │ QSenq/min │ QSdeq/min │
├────────┼────────────────┼────────────────┼─────────┼──────┼─────────┼──────────┼─────────────┼────────────┼─────────┼─────────┼───────────┼───────────┤
│ 0167aa │ "bdhq0vjwfrdq" │ "europe-west3" │ 2 │ 0.11 │ 0.53 │ 50.926 │ 0.308 │ 0.166 │ 0 │ 0 │ 0 │ 0 │
│ e01a73 │ "119n5q18cjrf" │ "europe-west3" │ 2 │ 0.05 │ 0.42 │ 44.663 │ 0.325 │ 0.205 │ 0 │ 0 │ 0 │ 0 │
└────────┴────────────────┴────────────────┴─────────┴──────┴─────────┴──────────┴─────────────┴────────────┴─────────┴─────────┴───────────┴───────────┘
⠼ Streaming...
这是快速监控项目在所有区域的实时性能和资源利用率的方法。我们可以看到两个部署使用的 CPU 和内存大致相同,并且我们没有引入任何性能退化。这意味着我们已准备好发布新版本到生产环境。
部署到生产环境
既然我们已经验证了新部署,我们就可以将生产域名指向它了。为此,我们将使用 deployctl deployments redeploy --prod bdhq0vjwfrdq
。
$ deployctl deployments redeploy --prod bdhq0vjwfrdq
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Redeployment of deployment 'bdhq0vjwfrdq' is ready to begin:
ℹ The new deployment will be the new production deployment
ℹ The new deployment will use the production database 'cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7'
✔ Deployment 'bdhq0vjwfrdq' redeployed as '4pb76z3ra3a2' successfully
使用 Deno Deploy 时,一个重要的规则是:部署是不可变的。这不仅包括源代码,还包括环境变量、域名映射、KV 数据库等。要更改其中任何一项,我们都必须创建一个新部署。deployctl deployments redeploy
命令允许您重用任何现有部署的构建,以创建具有不同配置的新部署。
如果我们检查刚刚创建的部署的详细信息,我们将看到生产域名指向它。
$ deployctl deployments show 4pb76z3ra3a2
4pb76z3ra3a2
------------
Status: Production
Date: 22 minutes, 43 seconds ago (14/3/2024 7:46:07 CET)
Project: my-new-api (488faa31-f687-4c9a-a082-d73cb0336b41)
Organization: Blog Post (ba7ef0e0-0a75-43f6-8aa1-db0897d693ba)
Domain(s): https://my-new-api.deno.dev
https://my-new-api-4pb76z3ra3a2.deno.dev
Database: Production (cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7)
Entrypoint: main.ts
Env Vars: DEPLOYMENT_TS
HOME
到目前为止,我们已经在项目中创建了3个部署:最初的生产部署、包含新响应和日志的预览部署,以及将其重新部署为生产版本。我们可以使用 deployctl deployments list
查看所有这些部署。
$ deployctl deployments list
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Page 1 of the list of deployments of the project '488faa31-f687-4c9a-a082-d73cb0336b41' is ready
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Deployment │ Date │ Status │ Database │ Domain │ Entrypoint │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 4pb76z3ra3a2 │ 14/3/2024 7:46:07 CET (19 minutes) │ Production │ Production │ https://my-project-4pb76z3ra3a2.deno.dev │ main.ts │
│ bdhq0vjwfrdq │ 13/3/2024 15:04:23 CET (17 hours) │ Preview │ Production │ https://my-project-bdhq0vjwfrdq.deno.dev │ main.ts │
│ 119n5q18cjrf │ 13/3/2024 13:36:49 CET (18 hours) │ Preview │ Production │ https://my-project-119n5q18cjrf.deno.dev │ main.ts │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
删除部署和项目
在任何给定时间,只有一个部署可以接收来自生产域名的流量。但是,所有部署仍然可以通过其预览域名访问。为此,您可以使用 deployctl deployments delete
删除它们。
$ deployctl deployments delete 119n5q18cjrf
ℹ Using config file '/private/tmp/my-new-app/deno.json'
? Are you sure you want to delete the deployment '119n5q18cjrf'? [y/N] y
✔ Deployment '119n5q18cjrf' deleted successfully
如果您已完成项目并希望将其完全删除,也可以使用 deployctl 的 deployctl projects delete
命令。
$ deployctl projects delete
ℹ Using config file '/private/tmp/my-new-app/deno.json'
✔ Project 'my-new-api' (488faa31-f687-4c9a-a082-d73cb0336b41) found
? Are you sure you want to delete the project 'my-new-api'? [y/N] y
✔ Project '488faa31-f687-4c9a-a082-d73cb0336b41' deleted successfully
您将需要确认删除,之后您的项目以及所有部署和数据库将从 Deno Deploy 中完全移除。
接下来是什么?
Deno Deploy 是一种在云端部署和托管 JavaScript 和 TypeScript 的简单快速方式,其命令行工具 deployctl
使其变得更加灵活和易于访问。我们将继续为其添加功能,以便您能够管理您的订阅、KV 实例等。要查看 deployctl
的其他功能,包括运行中项目的运行时统计信息,请查阅通过 deployctl -h
命令获取的帮助信息。
您希望在
deployctl
中看到哪些功能?请在 GitHub 上告诉我们。