跳过至主要内容
Deno 2 终于来了 🎉️
了解更多
deployctl, Deno Deploy's command line interface

介绍 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 --version 检查 deployctl 是否已正确安装。

$ 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/[email protected]/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 服务器。

A new deployment appears

很简单,对吧?几分钟内,您便创建并部署了一个在全球数据中心运行的 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),如果我们想要 远程连接到它,可以使用它。

我们还可以看到刚刚创建的部署。让我们使用 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/[email protected]/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://127.0.0.1:80/
2024-03-13T20:01:10.801337034Z   gcp-europe-west3 isolate start time: 287.60 ms (user time: 784.10 µs)

完美!我们的 env 变量日志效果很好。现在让我们检查部署的资源消耗方面是否一切正常。为此,我们可以使用 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"20.110.5350.9260.3080.1660000 │
│ e01a73 │ "119n5q18cjrf""europe-west3"20.050.4244.6630.3250.2050000 │
└────────┴────────────────┴────────────────┴─────────┴──────┴─────────┴──────────┴─────────────┴────────────┴─────────┴─────────┴───────────┴───────────┘
⠼ 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 时要记住的一条重要规则是 **部署是不可变的**。这不仅包括源代码,还包括 env 变量、域映射、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 上告诉我们.