惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

AI
AI
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
MyScale Blog
MyScale Blog
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
阮一峰的网络日志
阮一峰的网络日志
D
Docker
Jina AI
Jina AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Register - Security
The Register - Security
J
Java Code Geeks
S
SegmentFault 最新的问题
月光博客
月光博客
G
Google Developers Blog
美团技术团队
Last Week in AI
Last Week in AI
L
LangChain Blog
Apple Machine Learning Research
Apple Machine Learning Research
T
The Blog of Author Tim Ferriss
腾讯CDC
Recent Announcements
Recent Announcements
Recorded Future
Recorded Future
The Cloudflare Blog
有赞技术团队
有赞技术团队
博客园_首页
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
B
Blog
I
InfoQ
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
MongoDB | Blog
MongoDB | Blog
爱范儿
爱范儿
D
DataBreaches.Net
F
Full Disclosure
M
MIT News - Artificial intelligence
博客园 - 司徒正美
H
Help Net Security

Deno

Deno 2.8 | Deno Claw Patrol: an open-source security firewall for agents | Deno Fresh 2.3: Zero JS by default, View Transitions, and Temporal support | Deno Deno 2.7: Temporal API, Windows ARM, and npm overrides | Deno Build a dinosaur runner game with Deno, pt. 6 | Deno Build a dinosaur runner game with Deno, pt. 5 | Deno Deno Deploy is Generally Available | Deno Introducing Deno Sandbox | Deno Build a dinosaur runner game with Deno, pt. 4 | Deno Build a dinosaur runner game with Deno, pt. 3 | Deno Build a dinosaur runner game with Deno, pt. 2 | Deno React / Next.js Denial-of-Service Vulnerability: Deno Deploy users protected | Deno Deno 2.6: dx is the new npx | Deno Build a dinosaur runner game with Deno, pt. 1 | Deno React Server Functions / Next.js Vulnerability: Deno Deploy users protected | Deno My highlights from the new Deno Deploy | Deno Deno's Other Open Source Projects | Deno How Deno protects against npm exploits | Deno Help Us Raise $200k to Free JavaScript from Oracle | Deno Deno 2.5: Permissions in the config file | Deno Fresh 2.0 Graduates to Beta, Adds Vite Support | Deno Deno 2.4: deno bundle is back | Deno JavaScript™ Trademark Update | Deno What's coming to JavaScript | Deno A brief history of JavaScript | Deno Reports of Deno's Demise Have Been Greatly Exaggerated | Deno An Update on Fresh | Deno How Plaid migrated 100 services to a new database platform 5x faster with Deno | Deno Deno 2.3: Improved deno compile, local npm packages, and more | Deno Add JSR packages with pnpm and Yarn | Deno Zero-config Debugging with Deno and OpenTelemetry | Deno Exploring Art with TypeScript, Jupyter, Polars, and Observable Plot | Deno Deno v Oracle Update 3: Fighting the JavaScript Trademark | Deno Build a custom RAG AI agent in TypeScript and Jupyter | Deno How to get deep traces in your Node.js backend with OTel and Deno | Deno toranoana.deno #20 登録受付中(2025年3月14日) | Deno Node just added TypeScript support. What does that mean for Deno? | Deno The Dino 🦕, the Llama 🦙, and the Whale 🐋 | Deno Publish a lint rule, get a prize | Deno Deno 2.2: OpenTelemetry, Lint Plugins, node:sqlite | Deno If you're not using npm specifiers, you're doing it wrong | Deno How Deno's documentation is evolving | Deno Oracle justified its JavaScript trademark with Node.js—now it wants that ignored | Deno Introducing the JSR open governance board | Deno Intro to Wasm in Deno | Deno Announcing OpenAI on JSR | Deno Deno in 2024 | Deno Goodbye WinterCG, welcome WinterTC | Deno Build a SolidJS app with Deno | Deno Run your Next.js SSR app on Deno Deploy | Deno Solve Advent of Code 2024 with Deno and Win Prizes! | Deno Deno v. Oracle: Canceling the JavaScript Trademark | Deno Deno 2.1: Wasm Imports and other enhancements | Deno Build a Typesafe API with tRPC and Deno | Deno Self-contained Executable Programs with Deno Compile | Deno Build a Database App with Drizzle ORM and Deno | Deno Introducing your new JavaScript package manager: Deno | Deno Announcing Growthbook on JSR | Deno Build an Astro site with Deno | Deno How to convert CommonJS to ESM | Deno Announcing Deno 2 | Deno The Final Touches: What’s New In v2.0.0-rc.10 | Deno Announcing Stable V8 Bindings for Rust | Deno Deno 2.0 Release Candidate | Deno Secure, efficient private npm registries with Cloudsmith and Deno | Deno Painting the Plane as We Fly It: Designing JSR | Deno Introducing Web Cache API support on Deno Deploy | Deno Deno 1.46: The Last 1.x Release | Deno Protect your cloud spend with new Deno Deploy spend limits | Deno What we got wrong about HTTP imports | Deno Benchmarking AWS Lambda Cold Starts Across JavaScript Runtimes | Deno Announcing Supabase on JSR | Deno Deno 1.45: Workspace and Monorepo Support | Deno Introducing KV Backup for Deno Subhosting | Deno A Gentle Intro to TypeScript | Deno Announcing Hono on JSR | Deno How We Made the Deno Language Server Ten Times Faster | Deno How the Guardian uses Deno to audit accessibility and performance across their 2.7 million articles | Deno Introducing More Flexible Domain Association for Deno Subhosting | Deno The stabilization process of the Standard Library has begun | Deno Deno 1.44: Private npm registries, improved Node.js compat, and performance boosts | Deno How we built a secure, performant, multi-tenant cloud platform to run untrusted code | Deno The Deno Standard Library is now available on JSR | Deno How to document your JavaScript package | Deno Your Low Code Solution Needs an Escape Hatch | Deno Deno 1.43: Improved Language Server performance | Deno How Slack used Deno to save months of engineering effort in launching their new platform | Deno JSR Is Not Another Package Manager | Deno Announcing the Hookdeck SDK on JSR | Deno Announcing the Neon Serverless Driver on JSR | Deno An intro to TSConfig for JavaScript Developers | Deno How we built JSR | Deno How Netlify used Deno Subhosting to build a successful edge functions product | Deno Introducing Simpler Project Creation in Deno Deploy | Deno Deno 1.42: Better dependency management with JSR | Deno Introducing JSR - the JavaScript Registry | Deno How to add Monaco to a Next.js app and securely run untrusted user code | Deno Survey Results and Roadmap | Deno Deno 1.41: smaller deno compile binaries | Deno Webhooks suck, but here are alternatives | Deno
Introducing deployctl, the command line interface for Deno Deploy | Deno
2024-03-16 · via Deno

Many backend engineers prefer to manage infrastructure and deployments through a command line interface, especially when building CI/CD scripts where settings and configurations can all be represented through flags and code. Managing your projects on Deno Deploy is no exception — with deployctl you can now manage the whole lifecycle of your deployments without ever leaving the terminal.

This blog post will go over some key features of deployctl and give you an idea of how you can use deployctl in more complex situations:

  • The simplest road to cloud deployments
  • Managing your project
  • Deploying again
  • Observability
  • Rollout to production
  • Deleting deployments and projects
  • What’s next?

⚠️ Experience the fastest way to deploy JavaScript and TypeScript to the cloud. Signup for a free Deno Deploy account today.

The simplest road to cloud deployments

The only thing you need to deploy your code with deployctl is Deno and a GitHub account. If you don’t have a free Deno Deploy account yet don’t worry, one will be created during the first deployment. Let’s install deployctl with the below command:

$ deno install -A jsr:@deno/deployctl

That’s all! You can start deploying your code right away. If you want, you can check that deployctl has been installed correctly by running deployctl --version:

To demonstrate how simple it is do deploy your code with deployctl, we’ll create a hello-world API server using Hono and Deno locally:

$ deno run -A npm:create-hono

In the template selection step, choose “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

When you’re done, you should have a very simple web server in main.ts:

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);

Let’s deploy this to Deno Deploy using deployctl 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

If this is your first time using deployctl, you’ll be prompted in your browser to sign up to Deno Deploy and/or to authorize the deployctl’s access to your Deno Deploy account via your GitHub account. Once the deployment is finished, navigating to one of the URLs will show you your new Hono server:

A new deployment appears

Easy, right? Within minutes, you’ve created and deployed an API on data-centers around the world and have a URL to access it.

Managing your project

On the first deployment, deployctl deploy will try to figure out a name for your project and its entrypoint. If the project does not exist yet, it will be created automatically. if you are not happy with the name chosen for you, you can always change it with 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'

💡️ Pro tip!

You can always specify the project and entrypoint with the --project and --entrypoint flags.

After the first successful deployment, you’ll notice that deno.json now has a new deploy key with some configuration details:

{
  "tasks": {
    "start": "deno run --allow-net main.ts"
  },
  "deploy": {
    "project": "488faa31-f687-4c9a-a082-d73cb0336b41",
    "exclude": [
      "**/node_modules"
    ],
    "include": [],
    "entrypoint": "main.ts"
  }
}

From now on, deployctl will use this configuration unless you overrule it using the command line flags.

Next, let’s see what info we can get about our new project with 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*

Here we’re able to see the organization where the project was created, as well as the KV database ID (cb313b3b-07fa-4af1-a4bc-aa8dfebc3bc7) , which we can use if we want to remotely connect to it.

We can also see the deployment we just created. Let’s drill down to it with 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

Deploying again

Let’s make a quick update to our project and deploy it again. We’ll change the server’s response from “Hello Hono” to “Hello Deno”, and log the time it was deployed:

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);

To log the deployment time, we get the environment variable DEPLOYMENT_TS. This variable can be set during deployment with the --env flag:

$ 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

We can get the details of the last deployment with 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

Notice that this deployment is in “Preview” status, and has only one URL. Except for the first one, by default deployments are created in preview mode, which means they are only available at their preview domain. The production domain (https://my-new-api.deno.dev) still routes to the deployment we have created previously.

💡️ Pro tip!

If you pipe the output of deployctl commands, you get the data in JSON format. For example, you can get the domain of a deployment programmatically with 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!

If we query the URL of the new deployment, we’ll get the new response. Let’s now check if the deployment time is being logged correctly.

Observability

To see the logs of our deployment, we’ll use deployctl logs. As we are reviewing a preview deployment, we need to tell deployctl which specific deployment we want to query the logs of:

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://localhost:80/
2024-03-13T20:01:10.801337034Z   gcp-europe-west3 isolate start time: 287.60 ms (user time: 784.10 µs)

Perfect! Our log of the env variable worked beautifully. Let’s check now that nothing weird is going on with respect to the resource consumption of our deployment. For that, we can use 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...

This is a quick way to monitor the real-time performance and resource utilization of your project across all the regions. We can see both deployments are using roughly the same CPU and memory and we have not introduced any regression. That means we are ready to release a new version to production.

Rollout to production

Now that we have validated the new deployment, we are ready to point the production domain to it. To do that, we are going to use 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

One important rule to remember when using Deno Deploy is that deployments are immutable. This includes not just the source code, but also the env vars, domain mappings, the KV database, etc. To change any of these, we have to create a new deployment. The command deployctl deployments redeploy allows you to reuse the build of any existing deployment to create a new deployment with a different configuration.

If we check the details of the deployment we have just created, we’ll see the production domain pointing to it:

$ 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

We have created 3 deployments in our project so far: our initial production deployment, the preview deployment with the new response and log, and its redeployment as production. We can see all of them with 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    │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Deleting deployments and projects

Only one deployment can get traffic from the production domain at a given time. However, all of the deployments are still accessible on their preview domain. To prevent that you can delete them with 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

If you are done with your project and want to remove it altogether, you can also do this with deployctl using 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

You’ll have to confirm the deletion, after which your project and all deployments and database will be completely removed from Deno Deploy.

What’s next?

Deno Deploy, a simple and fast way to deploy and host JavaScript and TypeScript in the cloud, is even more flexible and accessible with its command line tool, deployctl. We’ll continue to add features to it so you’ll be able to manage your subscription, KV instances, and more. To see some of the other features of deployctl, including some runtime stats from your running project, review the help available via deployctl -h.

Are there any features you want to see in deployctl ? Let us know on GitHub.