How to Build and Deploy a Deno Application on Koyeb

May 12, 2021

Édouard Bonlieu

Édouard Bonlieu
@edouardb_

Introduction

Deno is a secure by default JavaScript and TypeScript runtime built in Rust and using V8. Deno provides great primitives to ease developers life such as:

  • Strong security by default, you have to explicitly enable network, filesystem, or environment access
  • Support of TypeScript out of the box
  • Ships a self-contained, standalone binary
  • No package manager, external modules are imported directly into local modules

In this guide, we will build a simple API in Deno using Oak and deploy to production on Koyeb.

Requirements

To successfully follow and complete this tutorial, you need:

  • Docker installed on your machine
  • A Koyeb account to deploy and run the dockerized Deno application

Steps

To successfully complete this guide, you need to follow the steps below:

  1. Write a simple Deno API with Oak
  2. Dockerize the Deno application
  3. Push the Docker image on the Docker Hub
  4. Deploy the Deno application to production on Koyeb

Write a simple Deno API with Oak

Let's start by writing a simple Deno API application with Oak. In a terminal, create a new folder and go to he freshly created directory.

mkdir koyeb-deno-example cd koyeb-deno-example

Create a new file name deno-demo.ts and add the code snippet below:

import { Application, Router } from 'https://deno.land/x/oak/mod.ts' const songs = new Map<string, any>([ [ '1', { id: '1', title: 'Herefore', author: 'Parcels', }, ], [ '2', { id: '2', title: 'True Sorry', author: 'Ibrahim Maalouf', }, ], [ '3', { id: '3', title: 'But I Do', author: 'Poldoore', }, ], ]) const router = new Router() router .get('/', (context) => { context.response.body = 'Hello World!' }) .get('/songs', (context) => { context.response.body = Array.from(songs.values()) }) .get('/songs/:id', (context) => { if (context.params && context.params.id && songs.has(context.params.id)) { context.response.body = songs.get(context.params.id) } }) const app = new Application() app.use(router.routes()) app.use(router.allowedMethods()) console.log(`HTTP webserver running on port 8080.`) await app.listen({ port: 8080 })

The code above uses the Deno oak module, which is a middleware framework for Deno’s HTTP server and also provides a router middleware.

The application listens on port 8080 and exposes three different routes:

  • /: Returning Hello World! as a response when a request is made
  • /songs: Returning a list of songs
  • /songs/:id: Returning details about a specific song

Dockerize the Deno application

The next step is to Dockerize our Deno application to deploy and run it on the Koyeb serverless platform. In the koyeb-deno-example folder, create a Dockerfile with the content below:

FROM hayd/alpine-deno:latest WORKDIR /app ADD deno-demo.ts /app EXPOSE 8080 # Compile the app so that it doesn't need to be compiled at each start. RUN deno cache deno-demo.ts CMD ["run", "--allow-net", "deno-demo.ts"]

As you can see, we pass the --allow-net flag in the CMD instruction. As Deno is secured by default, we need to explicitly enable network access.

Build the Docker image by running the following command in the koyeb-deno-example folder:

docker build . -t <YOUR_DOCKER_HUB_USERNAME>/koyeb-deno-demo

In this guide, we will push the Docker image on the Docker Hub registry. Replace <YOUR_DOCKER_HUB_USERNAME> with your Docker Hub username.

Once the build done, run the Docker image locally to ensure everything is running fine:

docker run -d -p 8080:8080 <YOUR_DOCKER_HUB_USERNAME>/koyeb-deno-demo`

Open your browser and navigate to http://localhost:8080. You see Hello world! served by the Docker container.

Push the Docker image on the Docker Hub

As we previously built and tested our Docker image, we can now push it to the Docker Hub. In your terminal run the command below to push the image.

docker push <YOUR_DOCKER_HUB_USERNAME>/koyeb-deno-demo

Within a few minutes, you will see your Docker image available on your Docker Hub account repository.

Deploy the Deno application to production on Koyeb

On the Koyeb Control Panel, click the Create App button.

In the form, fill the Docker image field with the name of the image we previously created which should look like <YOUR_DOCKER_HUB_USERNAME>/koyeb-deno-demo.

Check the box Use a private registry and, in the select field, click Create Registry Secret.

A modal opens asking for:

  • a name for the Secret which will be created, we can use for instance docker-hub-secret
  • the registry provider to generate the secret containing your private registry credentials, in our case Docker Hub
  • your Docker Hub username and password. We recommend you to generate an access token from the Docker Hub to use instead of your password. Once you've filled all the fields, click the Create button.

In the Ports section, change the export port from 80 to 8080, which is the port our Deno application is listening on. This setting is required to let Koyeb know which port your application is listening to and properly route incoming HTTP requests. We don't need to change the Path, our app will be available at the root of our domain: /.

Give your App a name, i.e koyeb-deno-demo, and click Create App.

You can add more regions to deploy your applications, set environment variables, and define the horizontal scaling according to your needs.

You will automatically be redirected to the Koyeb App page where you can follow the progress of your Deno application deployment. In a few seconds, once your app is deployed, click on the Public URL ending with koyeb.app.

Your Deno application is now running on Koyeb and benefits from native autoscaling, automatic HTTPS (SSL), auto-healing, and global load-balancing across our edge network.

Welcome to Koyeb

Koyeb is a developer-friendly serverless platform to deploy any apps globally.

Start for free
Start for free, pay as you grow

Deploy 2 services for free and enjoy our predictable pricing as you grow

Deploy your first app in no time

Get up and running in 5 minutes