Deploy to Deno Deploy
With this guide, you can learn how to build and deploy a simple application to Deno Deploy. The application uses Prisma ORM to save a log of each request to a Prisma Postgres database.
This guide covers the use of Prisma CLI with Deno CLI, Deno Deploy, Prisma Client, and Prisma Postgres.
This guide demonstrates how to deploy an application to Deno Deploy in conjunction with a Prisma Postgres database, but you can also use your own database with Prisma Accelerate.
Prerequisites
- a free account
- a free Deno Deploy account
- Node.js & npm installed
- Deno v1.29.4 or later installed. Learn more.
- (Recommended) Latest version of Prisma ORM.
- (Recommended) Deno extension for VS Code. Learn more.
1. Set up your application and database
To start, you create a directory for your project, and then use deno run
to initialize your application with prisma init
as an npm package with npm specifiers.
To set up your application, open your terminal and navigate to a location of your choice. Then, run the following commands to set up your application:
mkdir prisma-deno-deploy
cd prisma-deno-deploy
deno run --reload -A npm:prisma@latest init --db
Enter a name for your project and choose a database region.
This command:
- Connects your CLI to your account. If you're not logged in or don't have an account, your browser will open to guide you through creating a new account or signing into your existing one.
- Creates a
prisma
directory containing aschema.prisma
file for your database models. - Creates a
.env
file with yourDATABASE_URL
(e.g., for Prisma Postgres it should have something similar toDATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI..."
).
Edit the prisma/schema.prisma
file to define a Log
model, add a custom output
path and enable the deno
preview feature flag:
generator client {
provider = "prisma-client-js"
previewFeatures = ["deno"]
output = "../generated/client"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Log {
id Int @id @default(autoincrement())
level Level
message String
meta Json
}
enum Level {
Info
Warn
Error
}
To use Deno, you need to add the preview feature flag deno
to the generator
block of your schema.prisma
file.
Deno also requires you to generate Prisma Client in a custom location. You can enable this with the output
parameter in the generator
block.
Then, install the Client extension required to use Prisma Postgres:
deno install npm:@prisma/extension-accelerate
Prisma Client does not read .env
files by default on Deno, so you must also install dotenv-cli
locally:
deno install npm:dotenv-cli
2. Create the database schema
With the data model in place and your database connection configured, you can now apply the data model to your database.
deno run -A npm:prisma migrate dev --name init
The command does two things:
- It creates a new SQL migration file for this migration
- It runs the SQL migration file against the database
At this point, the command has an additional side effects. The command installs Prisma Client and creates the package.json
file for the project.
3. Create your application
You can now create a local Deno application. Create index.ts
in the root folder of your project and add the content below:
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
import { withAccelerate } from "npm:@prisma/extension-accelerate";
import { PrismaClient } from "./generated/client/deno/edge.ts";
const prisma = new PrismaClient().$extends(withAccelerate());
async function handler(request: Request) {
// Ignore /favicon.ico requests:
const url = new URL(request.url);
if (url.pathname === "/favicon.ico") {
return new Response(null, { status: 204 });
}
const log = await prisma.log.create({
data: {
level: "Info",
message: `${request.method} ${request.url}`,
meta: {
headers: JSON.stringify(request.headers),
},
},
});
const body = JSON.stringify(log, null, 2);
return new Response(body, {
headers: { "content-type": "application/json; charset=utf-8" },
});
}
serve(handler);
VS Code error: An import path cannot end with a '.ts' extension
If you use VS Code and see the error An import path cannot end with a '.ts' extension
for the import
statements at the beginning of index.ts
, you need to install the Deno extension for VS Code, select View > Command Palette and run the command Deno: Initialize Workspace Configuration. This tells VS Code that the TypeScript files in the current project need to run with Deno, which then triggers the correct validations.
4. Test your application locally
You can now start your application locally and test the creation of log entries.
npx dotenv -- deno run -A ./index.ts
In a web browser, open http://localhost:8000/. This page writes your request to the database.
{
"id": 1,
"level": "Info",
"message": "GET http://localhost:8000/",
"meta": {
"headers": "{}"
}
}
Reload the page a few times.
Every time you reload, the script generates a new log entry and the id
of the current log entry increments.
This confirms that your application works when you run it from your local environment.
5. Create a repository and push to GitHub
You need a GitHub repository to add your project to Deno Deploy and enable automated deployments whenever you push changes.
To set up a GitHub repository:
-
Initialize your repository locally and push your changes to GitHub, with the following commands:
git init -b main
git remote add origin https://github.com/<username>/prisma-deno-deploy
git add .
git commit -m "initial commit"
git push -u origin main
6. Deploy to Deno Deploy
Use the GitHub repository to add your application to Deno Deploy:
- Go to https://dash.deno.com/.
- Select a GitHub organization or user and then select a repository.
- Select a production branch and select Fresh (Automatic) mode so that Deno Deploy can deploy every time you push a change to the repository.
- Select
index.ts
as the entry point to your project. - Click
Create & Deploy
.
The deployment should fail as you have to add the DATABASE_URL
environment variable.
Locate and navigate to the settings for the project.
- To define the database connection string, click Add Variable in the Environment Variables section.
- For KEY, enter
DATABASE_URL
. - For VALUE, paste the database connection string.
- For KEY, enter
- Click Save.
You have to add some code and create another commit to trigger a re-dployment.
Add the following code in your index.ts
file:
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
import { withAccelerate } from "npm:@prisma/extension-accelerate";
import { PrismaClient } from "./generated/client/deno/edge.ts";
const prisma = new PrismaClient().$extends(withAccelerate());
async function handler(request: Request) {
// Ignore /favicon.ico requests:
const url = new URL(request.url);
if (url.pathname === "/favicon.ico") {
return new Response(null, { status: 204 });
}
console.log("Request received.")
const log = await prisma.log.create({
data: {
level: "Info",
message: `${request.method} ${request.url}`,
meta: {
headers: JSON.stringify(request.headers),
},
},
});
const body = JSON.stringify(log, null, 2);
return new Response(body, {
headers: { "content-type": "application/json; charset=utf-8" },
});
}
serve(handler);
Commit the new changes:
git add .
git commit -m "add log"
git push origin main
This rebuilds the deployment, which now works because the environment variable has been added. After it completes, follow the URL in the deployment output. The application should show the same result as before, with a new, incremented log record ID:
{
"id": 5,
"level": "Info",
"message": "GET https://prisma-deno-deploy.deno.dev/",
"meta": {
"headers": "{}"
}
}
Summary
You successfully deployed a Deno application that you created in TypeScript, which uses Prisma Client connecting to a Prisma Postgres database.