diff --git a/sidebars/subhosting.js b/sidebars/subhosting.js
index 651e7fc55..62f3b3e22 100644
--- a/sidebars/subhosting.js
+++ b/sidebars/subhosting.js
@@ -1,20 +1,48 @@
const sidebars = {
- subhosting: [
+ subhosting: [],
+
+ subhostGuideHome: [
{
type: "html",
value: "
Getting Started
",
className: "section-header",
},
- "manual/index",
- "manual/getting_started",
- "manual/projects_and_deployments",
- "manual/events",
+ {
+ type: "doc",
+ label: "About Subhosting",
+ id: "manual/index",
+ },
+ {
+ type: "doc",
+ label: "Quick Start",
+ id: "manual/quick_start",
+ },
+ {
+ type: "doc",
+ label: "Planning your implementation",
+ id: "manual/planning_your_implementation",
+ },
+ {
+ type: "doc",
+ label: "Pricing and Limits",
+ id: "manual/pricing_and_limits",
+ },
{
type: "html",
value: "REST API
",
className: "section-header",
},
- "api/index",
+ {
+ type: "doc",
+ label: "Resources",
+ id: "api/index",
+ },
+ {
+ type: "doc",
+ label: "Authentication",
+ id: "api/authentication",
+ },
+ "manual/events",
{
type: "link",
label: "API Reference Docs",
diff --git a/subhosting/api/authentication.md b/subhosting/api/authentication.md
new file mode 100644
index 000000000..9e4a32e61
--- /dev/null
+++ b/subhosting/api/authentication.md
@@ -0,0 +1,44 @@
+# Authentication
+
+Developers can provision projects, domains, KV databases, and other resources
+using the Subhosting REST API.
+
+## Endpoint and authentication
+
+The base URL for the Subhosting REST API v1 is below.
+
+```console
+https://api.deno.com/v1/
+```
+
+The v1 API uses
+[HTTP bearer token](https://swagger.io/docs/specification/authentication/bearer-authentication/)
+authentication. You can create an access token to use the API in the dashboard
+[here](https://dash.deno.com/account#access-tokens). Most API requests will also
+require your organization ID. You can retrieve yours from the Deno Deploy
+dashboard for your organization.
+
+![Find your org ID here](./images/org-id.png)
+
+Using both your organization ID and your access token, you can test your API
+access by listing all the projects associated with your organization. Here is an
+example Deno script you can use to access the API.
+
+```typescript
+// Replace these with your own!
+const organizationId = "a75a9caa-b8ac-47b3-a423-3f2077c58731";
+const token = "ddo_u7mo08lBNHm8GMGLhtrEVfcgBsCuSp36dumX";
+
+const res = await fetch(
+ `https://api.deno.com/v1/organizations/${organizationId}/projects`,
+ {
+ method: "GET",
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ },
+);
+
+const response = await res.json();
+console.log(response);
+```
diff --git a/subhosting/manual/subhosting-org-structure.svg b/subhosting/api/images/subhosting-org-structure.svg
similarity index 100%
rename from subhosting/manual/subhosting-org-structure.svg
rename to subhosting/api/images/subhosting-org-structure.svg
diff --git a/subhosting/api/index.md b/subhosting/api/index.md
index 529f80c4b..dddf14add 100644
--- a/subhosting/api/index.md
+++ b/subhosting/api/index.md
@@ -1,47 +1,128 @@
-# Subhosting REST API
+# Subhosting Resources
-Developers can provision projects, domains, KV databases, and other resources
-using the Subhosting REST API.
+To build Subhosting with Deno Deploy, it helps to understand some key resources
+within the system. These resources are also represented in the
+[REST API](../api/index.md).
-## Endpoint and authentication
+![overview of subhosting resources](./images/subhosting-org-structure.svg)
-The base URL for the Subhosting REST API v1 is below.
+
-```console
-https://api.deno.com/v1/
-```
+## Organizations
+
+[**Organizations**](https://apidocs.deno.com/#get-/organizations/-organizationId-)
+are a container for all data related to a subhosting implementation. Your
+organization will have a name and an ID. Each organization has an analytics
+endpoint which can be used to get metrics (such as request count and bandwidth
+used) from across the organization.
+
+Other Deploy users can be invited to collaborate on an organization, and
+[access tokens](https://dash.deno.com/account#access-tokens) can give developers
+with organization access the ability to modify resources within the org via API.
+New organizations can be created in the
+[Deploy dashboard](https://dash.deno.com/orgs/new).
+
+
+
+## Projects
+
+[**Projects**](https://apidocs.deno.com/#get-/organizations/-organizationId-/projects)
+act as organizational containers for deployments. A project contains its
+deployments and the analytics and usage information for those deployments.
+
+Projects are free and can be set up as required.
+
+To track usage by individual users for billing there is an API endpoint that
+reports analytics (bandwidth usage, request count, etc), per project, with 15
+minute granularity.
+
+> All deployments (whether within a same project or between different projects)
+> share nothing by default. Projects are a way to organize your deployments and
+> do not cost anything. However analytics are reported on a per-project basis,
+> if you have multiple tenants we recommend setting up a project for each.
+> Particularly if you expect to bill your users for their usage.
+
+
+
+## Deployments
+
+[**Deployments**](https://apidocs.deno.com/#get-/projects/-projectId-/deployments):
+a deployment is a set of configuration, runnable code, and supporting static
+files that can run on an isolate in Deno Deploy. Deployments have an entry file
+that can launch a server, can have a [Deno KV](/deploy/kv/manual) database
+associated with them, and can be set up to run on custom domains.
+
+A deployment is an immutable object that consists of:
+
+- Source code to run
+- Static assets
+- Environment variables
+- Database bindings
+- Other settings
+
+We provide endpoints for querying or streaming build logs and querying or
+streaming execution logs.
+
+If you need to block or unblock a deployment you can do so by deleting the
+deployment that you need to block or by unassigning its domains. This will make
+the deployment unreachable.
+
+The Subhosting system is built so that the behavior or load on one deployment
+does not affect other deployments. This also applies to different deployments
+within one organization. Capacity is auto-scaled on demand. If you want to limit
+resources to a particular deployment or application you can use the analytics
+API to provide you with detailed metrics (request count, bandwidth, etc) at
+project level granularity. You can use this to decide whether to shut off
+deployments and make them unreachable.
+
+> NB. **Deployments are immutable**, however, you can create a new deployment
+> and then remap its domain to the new deployment. The redeploy endpoint can
+> create a new deployment from an existing one with different settings.
+
+
+
+## Custom domains
+
+[**Custom domains**](https://apidocs.deno.com/#get-/organizations/-organizationId-/domains)
+can be dynamically mapped to deployments, giving them a unique URL (eg
+`mycompany.com`).
+
+Before a domain can be used you need to
+[verify ownership and provision
+or upload TLS certificates](https://github.com/denoland/deploy-api/blob/main/samples.ipynb).
+
+If you are on the [Builder tier](https://deno.com/deploy/pricing?subhosting) you
+can use wildcard domains. Once you have a wildcard domain registered, you can
+use it in two ways:
+
+- Send all requests for `*.mycompany.com` to a specific deployment
+- (Coming soon) Assign different subdomains (e.g. `foo.mycompany.com` and
+ `bar.mycompany.com`) to separate deployments.
+
+### Staging vs Production Environments
+
+The Deno Deploy end-user platform automatically creates preview deployments when
+a developer opens a github pull request, and commits to the “main” branch are
+automatically turned into production deployments. Although subhosting does not
+provide github integration out of the box, it has all the primitives you need to
+define your own semantics for creating preview and production deployments.
+
+
+
+## Connecting a KV Database
+
+A (KV) database stores key-value pairs You can make a database accessible to a
+deployment when you make the deployment. KV databases can be used by multiple
+deployments at the same time.
+
+To use KV with Subhosting:
+
+- [Create a database using the API](https://docs.deno.com/deploy/kv/manual)
+- When you create a deployment using the Subhosting API, specify the database
+ you created.
+
+> NB. Deno Cron and Queues do not currently work for Subhosting.
-The v1 API uses
-[HTTP bearer token](https://swagger.io/docs/specification/authentication/bearer-authentication/)
-authentication. You can create an access token to use the API in the dashboard
-[here](https://dash.deno.com/account#access-tokens). Most API requests will also
-require your organization ID. You can retrieve yours from the Deno Deploy
-dashboard for your organization.
-
-![Find your org ID here](./images/org-id.png)
-
-Using both your organization ID and your access token, you can test your API
-access by listing all the projects associated with your organization. Here is an
-example Deno script you can use to access the API.
-
-```typescript
-// Replace these with your own!
-const organizationId = "a75a9caa-b8ac-47b3-a423-3f2077c58731";
-const token = "ddo_u7mo08lBNHm8GMGLhtrEVfcgBsCuSp36dumX";
-
-const res = await fetch(
- `https://api.deno.com/v1/organizations/${organizationId}/projects`,
- {
- method: "GET",
- headers: {
- Authorization: `Bearer ${token}`,
- },
- },
-);
-
-const response = await res.json();
-console.log(response);
-```
## OpenAPI specification and tooling
diff --git a/subhosting/manual/acceptable_use_policy.md b/subhosting/manual/acceptable_use_policy.md
new file mode 100644
index 000000000..bb2dbf173
--- /dev/null
+++ b/subhosting/manual/acceptable_use_policy.md
@@ -0,0 +1,30 @@
+# Acceptable use policy
+
+The Deno Subhosting service includes resources (CPU time, request counts) that
+are subject to this Acceptable Use policy. This document can give a rough
+estimate to what we consider as "Acceptable Use", and what we do not.
+
+### Examples of Acceptable Use
+
+- ✅ Server-side rendered websites
+- ✅ Jamstack sites and apps
+- ✅ Single page applications
+- ✅ APIs that query a DB or external API
+- ✅ A personal blog
+- ✅ A company website
+- ✅ An e-commerce site
+
+### Not Acceptable Use
+
+- ❌ Crypto mining
+- ❌ Highly CPU-intensive load (e.g. machine learning)
+- ❌ Media hosting for external sites
+- ❌ Scrapers
+- ❌ Proxy or VPN
+
+## Guidelines
+
+We expect most projects to fall well within the usage limits. We will notify you
+if your projects usage significantly deviates from the norm. We will reach out
+to you where possible before taking any action to address unreasonable burdens
+on our infrastructure.
diff --git a/subhosting/manual/domains.md b/subhosting/manual/domains.md
deleted file mode 100644
index de1ad08d7..000000000
--- a/subhosting/manual/domains.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Working with custom domains
-
-TODO - talk about provisioning domains and associating them with deployments.
-
-For now, reference:
-https://github.com/denoland/deploy-api/blob/main/samples.ipynb
diff --git a/subhosting/manual/index.md b/subhosting/manual/index.md
index f51aea61e..2c80761df 100644
--- a/subhosting/manual/index.md
+++ b/subhosting/manual/index.md
@@ -1,105 +1,65 @@
# About Subhosting
-A powerful use case for Deno Deploy is using our isolate cloud to run untrusted
-code on behalf of your end users. There are a number of scenarios where you
-might be interested in doing this:
-
-- You are a SaaS provider that wants to empower your customers to extend your
- platform with custom code
-- You are an infrastructure provider that would like to enable your customers to
- run Deno-powered edge functions
-- You are building a browser-based editor for user code (possibly for
- education), and you'd like a place to execute that code in a controlled and
- secure way
-
-In cases like these, you might consider using Deno Deploy's full-featured
-[REST API](../api/index.md) to implement
-[**subhosting**](https://deno.com/subhosting). "Subhosting" is what we call the
-scenario where you use Deno Deploy to run your users' untrusted code in a secure
-and scalable environment designed for
-[multitenancy](https://www.ibm.com/topics/multi-tenant).
-
-## Quick start example
-
-Looking for the smallest possible example that shows how to deploy code to
-Deno's isolate cloud? We've got you covered below. Once you've skimmed over it,
-you can read on for more details about subhosting.
-
-```ts
-// 1.) Get API access info ready
-const accessToken = Deno.env.get("DEPLOY_ACCESS_TOKEN");
-const orgId = Deno.env.get("DEPLOY_ORG_ID");
-const API = "https://api.deno.com/v1";
-const headers = {
- Authorization: `Bearer ${accessToken}`,
- "Content-Type": "application/json",
-};
-
-// 2.) Create a new project
-const pr = await fetch(`${API}/organizations/${orgId}/projects`, {
- method: "POST",
- headers,
- body: JSON.stringify({
- name: null, // randomly generates project name
- }),
-});
-const project = await pr.json();
-
-// 3.) Deploy a "hello world" server to the new project
-const dr = await fetch(`${API}/projects/${project.id}/deployments`, {
- method: "POST",
- headers,
- body: JSON.stringify({
- entryPointUrl: "main.ts",
- assets: {
- "main.ts": {
- "kind": "file",
- "content": `Deno.serve(() => new Response("Hello, World!"));`,
- "encoding": "utf-8",
- },
- },
- envVars: {},
- }),
-});
-console.log(dr.status);
-```
-
-## How subhosting works
-
-To build subhosting with Deno Deploy, it helps to understand some key resources
-within the system. These resources are also represented in the
-[REST API](../api/index.md).
-
-![overview of subhosting resources](./subhosting-org-structure.svg)
-
-- [**Organizations**](https://apidocs.deno.com/#get-/organizations/-organizationId-):
- Organizations are a container for all data related to a subhosting
- implementation. Other Deploy users can be invited to collaborate on an
- organization, and [access tokens](https://dash.deno.com/account#access-tokens)
- can give developers with organization access the ability to modify resources
- within the org via API. New organizations can be created in the
- [Deploy dashboard](https://dash.deno.com/orgs/new).
-- [**Projects**](https://apidocs.deno.com/#get-/organizations/-organizationId-/projects):
- a project is a container for **deployments**, and the analytics and usage
- information for all deployments within a project.
-- [**Deployments**](https://apidocs.deno.com/#get-/projects/-projectId-/deployments):
- a deployment is a set of configuration, runnable code, and supporting static
- files that can run on an isolate in Deno Deploy. Deployments have an entry
- file that can launch a server, can have a [Deno KV](/deploy/kv/manual)
- database associated with them, and can be set up to run on custom domains.
-- [**Domains**](https://apidocs.deno.com/#get-/organizations/-organizationId-/domains):
- custom domains that can be associated with deployments, giving them a unique
- URL.
+Deno Subhosting is a robust platform designed to allow Software as a Service
+(SaaS) providers to securely run code written by their customers. The Subhosting
+API allows you to deploy untrusted code programmatically and at scale.
+
+## Key Features
+
+- **Ease of Use:** Developers can write code in generic JavaScript or TypeScript
+ without needing specific knowledge of Deno.
+- **Standards Compliance:** Deno supports standard JavaScript and TypeScript and
+ integrates widely-used web APIs like `fetch` and `web cache`.
+- **Deno-Specific Advanced Features:** Offers advanced features like `KV`
+ (Key-Value stores) which extend beyond typical browser capabilities.
+- **Rapid Deployment:** Deno’s cloud products are designed to support extremely
+ short deployment times that range from less than a second for simple
+ applications, to around ten seconds for complex websites with numerous
+ dependencies.
+- **Improved developer experience**: Subhosting will manage the extensive effort
+ of setting up secure infrastructure to run untrusted code in a public cloud
+ for you.
+
+## Overview of Deno Cloud Offerings - Deno Deploy and Deno Subhosting
+
+Deno provides two distinct cloud offerings, Deno Deploy and Deno Subhosting,
+each designed to support specific use cases while leveraging the same underlying
+infrastructure.
+
+### Deno Deploy
+
+Deno Deploy is optimized for individual developers and small teams focused on
+developing and iterating on a limited set of first-party projects. This solution
+is ideal for hosting websites or applications, with deployment processes
+typically managed through GitHub integrations.
+
+- Target Audience: Individual developers and small development teams.
+- Deployment Integration: Primarily through GitHub for continuous integration
+ and delivery.
+- Use Cases: Hosting websites and applications.
+
+### Deno Subhosting
+
+In contrast, Deno Subhosting is engineered to securely manage a larger volume of
+projects and deployments. It supports the deployment of untrusted code or
+functions through an API, making it suitable for scenarios involving multiple
+end-users contributing code.
+
+- Target Audience: SaaS platforms requiring the capability to host
+ customer-generated, untrusted code securely.
+- Deployment Mechanism: Through a robust API designed for scalability and
+ security.
+- Use Cases: Large scale project hosting where end-users contribute the code.
The steps to implement subhosting are roughly as follows:
-1. [Create an organization](./getting_started.md) and get an access token for
- the REST API
-1. [Create a project](./projects_and_deployments.md), and then create your first
- deployment for that project
+1. [Create an organization](./quick_start.md) and get an access token for the
+ REST API
+1. [Create a project](./planning_your_implementation.md), and then create your
+ first deployment for that project
Using these techniques, you can package up user code as "deployments", and
-execute that code on a Deno-provisioned URL or a custom URL you can configure
+execute that code on a Deno-provisioned URL or a [custom URL](../api/#custom-domains) you can configure
yourself.
## REST API reference and OpenAPI spec
diff --git a/subhosting/manual/projects_and_deployments.md b/subhosting/manual/planning_your_implementation.md
similarity index 82%
rename from subhosting/manual/projects_and_deployments.md
rename to subhosting/manual/planning_your_implementation.md
index 1262d198b..369343177 100644
--- a/subhosting/manual/projects_and_deployments.md
+++ b/subhosting/manual/planning_your_implementation.md
@@ -1,17 +1,8 @@
-# Projects and deployments
+# Planning your implementation
-In the [domain model for subhosting](./index.md), a **project** is a container
-for **deployments**. You can track aggregate analytics for a project (like how
-many requests are being processed, KV database usage, etc). But actual code that
-runs and serves requests is contained in a **deployment**. Depending on the data
-model for your application, you might choose to map projects and deployments in
-different ways.
-
-## Planning your implementation
-
-For example - let's say that you were building a SaaS CRM platform like
-Salesforce, and you wanted to empower your customers to write JavaScript code
-that would be executed every time a new lead was captured.
+Let's say, for example, that you are building a SaaS CRM platform like
+Salesforce. You want to empower your customers to write JavaScript code that
+would be executed every time a new lead was captured.
If you were going to implement this feature using Deno Deploy, here's how you
might think about building it:
@@ -35,8 +26,8 @@ Let's look at an example of the API endpoint required to make this happen.
## Creating a deployment for a project
-In the [previous chapter](./getting_started.md), you created a new project and
-noted its `id` property. In the example in the previous chapter, the ID was:
+In the [previous chapter](./quick_start.md), you created a new project and noted
+its `id` property. In the example in the previous chapter, the ID was:
```console
f084712a-b23b-4aba-accc-3c2de0bfa26a
diff --git a/subhosting/manual/pricing_and_limits.md b/subhosting/manual/pricing_and_limits.md
new file mode 100644
index 000000000..74774ac31
--- /dev/null
+++ b/subhosting/manual/pricing_and_limits.md
@@ -0,0 +1,28 @@
+# Pricing and Limits
+
+## Deployment size
+
+Deployments should be less than 1GB across all source code and assets in
+aggregate, per deployment.
+
+## Deployment frequency
+
+The maximum number of deployments per hour that a subhosting user can make is
+either 60 (on the free tier) or 300 (on the builder tier). Higher limits are
+available for organizations on the enterprise plan.
+
+## CPU time per request
+
+- 50ms or 200ms, depending on tier.
+- CPU time limit per request is limited on the average across many requests. It
+ is not strictly enforced on a per-request basis.
+- Does not include time that a deployment is waiting for I/O (e.g. while waiting
+ for the remote server while making a fetch() request)
+
+## Blocking the event loop
+
+Programs should not block the event loop for more than 1s.
+
+## Available memory
+
+512MB max memory is available.
diff --git a/subhosting/manual/getting_started.md b/subhosting/manual/quick_start.md
similarity index 74%
rename from subhosting/manual/getting_started.md
rename to subhosting/manual/quick_start.md
index c4fc5a549..cd446ef9c 100644
--- a/subhosting/manual/getting_started.md
+++ b/subhosting/manual/quick_start.md
@@ -1,4 +1,51 @@
-# Getting started with subhosting
+# Subhosting Quick Start
+
+Looking for the smallest possible example that shows how to deploy code to
+Deno's isolate cloud? We've got you covered below, or you can skip to the
+[more detailed getting started guide](#getting_started).
+
+```ts
+// 1.) Get API access info ready
+const accessToken = Deno.env.get("DEPLOY_ACCESS_TOKEN");
+const orgId = Deno.env.get("DEPLOY_ORG_ID");
+const API = "https://api.deno.com/v1";
+const headers = {
+ Authorization: `Bearer ${accessToken}`,
+ "Content-Type": "application/json",
+};
+
+// 2.) Create a new project
+const pr = await fetch(`${API}/organizations/${orgId}/projects`, {
+ method: "POST",
+ headers,
+ body: JSON.stringify({
+ name: null, // randomly generates project name
+ }),
+});
+const project = await pr.json();
+
+// 3.) Deploy a "hello world" server to the new project
+const dr = await fetch(`${API}/projects/${project.id}/deployments`, {
+ method: "POST",
+ headers,
+ body: JSON.stringify({
+ entryPointUrl: "main.ts",
+ assets: {
+ "main.ts": {
+ "kind": "file",
+ "content": `Deno.serve(() => new Response("Hello, World!"));`,
+ "encoding": "utf-8",
+ },
+ },
+ envVars: {},
+ }),
+});
+console.log(dr.status);
+```
+
+
+
+## Getting started with subhosting
To get started with subhosting, you will need to create an organization in the
[Deno Deploy dashboard](https://dash.deno.com/orgs/new). Follow the on-screen
@@ -6,7 +53,7 @@ instructions to create a new organization for subhosting.
Going through the onboarding flow, you will likely also generate an **access
token**, which you will use to access the [REST API](../api/index.md). If you
-didn't do this (or lost the token you generated), you can
+didn't do this (or your token has expired), you can
[generate a new one here](https://dash.deno.com/account#access-tokens).
:::caution Save your token in a safe place
@@ -118,4 +165,4 @@ Note the `id` of the project that was returned with this repsonse - this is the
project ID we'll use in the next step.
Now that we have REST API access configured and a project set up, we can move on
-to [creating our first deployment](./projects_and_deployments).
+to [creating our first deployment](./planning_your_implementation).