Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updating subhosting documentation #436

Merged
merged 15 commits into from May 8, 2024
58 changes: 54 additions & 4 deletions sidebars/subhosting.js
@@ -1,13 +1,63 @@
const sidebars = {
subhosting: [
subhosting: [],

subhostGuideHome: [
{
type: "html",
value: "<div>Getting Started</div>",
className: "section-header",
},
"manual/index",
"manual/getting_started",
"manual/projects_and_deployments",
{
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: "Subhosting Usecases",
id: "manual/usecases",
},

{
type: "html",
value: "<div>Subhosting Platform</div>",
className: "section-header",
},
{
type: "doc",
label: "Organizations",
id: "manual/subhosting",
},
{
type: "link",
label: "Projects",
href: "/subhosting/manual/subhosting#projects",
},
{
type: "link",
label: "Deployments",
href: "/subhosting/manual/subhosting#deployments",
},
{
type: "link",
label: "Custom Domains",
href: "/subhosting/manual/subhosting#domains",
},
{
type: "link",
label: "Connecting a Database",
href: "/subhosting/manual/subhosting#database",
},
"manual/events",
{
type: "html",
Expand Down
30 changes: 30 additions & 0 deletions 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
thisisjofrank marked this conversation as resolved.
Show resolved Hide resolved

## 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.
6 changes: 0 additions & 6 deletions subhosting/manual/domains.md

This file was deleted.

148 changes: 54 additions & 94 deletions subhosting/manual/index.md
@@ -1,102 +1,62 @@
# 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
thisisjofrank marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
@@ -1,13 +1,4 @@
# Projects and deployments

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
# 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
Expand Down Expand Up @@ -35,7 +26,7 @@ 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
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
Expand Down
23 changes: 23 additions & 0 deletions subhosting/manual/pricing_and_limits.md
@@ -0,0 +1,23 @@
# Pricing and Limits
thisisjofrank marked this conversation as resolved.
Show resolved Hide resolved

## Deployment size

Deployments should be less than 1GB across all source code and assets in aggregate, per deployment.

## Deployment frequency

Bert to define, varies based on pricing tier.
thisisjofrank marked this conversation as resolved.
Show resolved Hide resolved

## 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.
@@ -1,4 +1,52 @@
# 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);
```

<br/>
<a name="getting_started"></a>

## 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
Expand Down Expand Up @@ -118,4 +166,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).