跳至主要内容
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 和/或授权 deployctl 通过您的 GitHub 账户访问您的 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),如果我们想 从 Deno Deploy 外部远程连接到它,可以使用该 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/[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)

完美!我们对环境变量的日志记录工作得很好。现在让我们检查一下,关于我们部署的资源消耗是否没有任何异常。为此,我们可以使用 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 时要记住的一条重要规则是,部署是不可变的。这不仅包括源代码,还包括环境变量、域映射、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 上告诉我们