How to deploy a Deno app using Docker

How to deploy a Deno app using Docker

Docker is a popular open-source technology for running applications in a containerized environment. This is useful because it allows you to easily scaffold and deploy applications to any platform that supports Docker. In this tutorial, we will learn how to build a Deno application that can be run in a Docker container. We will do this by building a Docker image and run it as a container.

What is Deno

If you're new to Deno, you should read this Getting Started with Deno tutorial first. However, as a quick refresher, here is a quick overview of Deno.

Deno is a modern web application framework that is designed to be secure, fast, and robust. It is built on top of Google's V8 engine and written in Rust. It aims to be a modern replacement for Node and solves many of the problems that Node has.

Prerequisites

  1. Basic knowledge of JavaScript
  2. Basic ability to use a command line interface

Installing Deno

The homepage of Deno has all the instructions for how to install it on your computer, but these are the most popular ways:

For Mac users, you can use brew to install Deno.

BASH
brew install deno

For Windows, you can use PowerShell

BASH
iwr https://deno.land/x/install/install.ps1 -useb | iex

Either way, however you install it, you can check your version like so:

BASH
deno --version

You should output similar to this:

BASH
deno 1.16.0 v8 9.0 typescript 4.5.0

A cool thing about Deno is that it also tells you the version of the V8 Engine that it is using and the version of TypeScript that it is using.

Installing Docker

You will also need to install Docker.

  1. Visit the official Docker website to get the installer.
  2. After it downloads, run the installer until the end.
  3. Restart your computer to ensure the changes can take effect.

The Docker installer.

Directory Structure

By the end of this tutorial, our application will be in the following directory structure:

BASH
app ├── .env ├── docker-compose.yml ├── Dockerfile └── server.ts

As you can see, it's a simple application with a few files for the purposes of this tutorial.

Deno app

This tutorial assumes that you already have a Deno app that you want to deploy on a Docker container, however we will build a very minimal one from scratch.

We will be using Deno's standard library to create a simple web server.

Add this to your server.ts file:

JAVASCRIPT
import { serve } from "https://deno.land/std/http/server.ts"; serve(req => new Response("Hello world from Deno!"), { port: 8080 }); console.log(`HTTP server is running at: http://localhost:8080/`);

This app will run a simple HTTP server that will respond with a plain text message on port 8080. Before using Docker, you can test this app by running it, then visiting the URL http://localhost:8080/.

The Deno app running on port 8080.

Docker Overview

Before we continue, let's run through a quick overview of how Docker works. As said before, Docker is a containerization technology that makes it easy to create, deploy, and run applications inside containers.

A Docker container is a lightweight, portable, and isolated unit of software. It is a single process that runs on a single computer. It is designed to run a specific application, such as a web server, or a database.

A Docker image is a blueprint for a Docker container. It is a collection of files and commands that can be used to create a Docker container, and it is stored inside of a file called Dockerfile. The instructions in this file are used to create an image.

Docker overview

Docker Compose

Now that we have an app to deploy and the basic terms for Docker defined, let's deploy it on a Docker container. There are several ways to do this, but the easiest way is to use the Docker Compose tool. It comes with Docker, so you should already have access to it.

Create a file named docker-compose.yml in the root directory of your folder.

YML
version: "3.9" services: deno: container_name: deno image: deno restart: always build: context: . dockerfile: Dockerfile target: base ports: - "${PORT}:${PORT}"

Let's breakdown what's going on here. This file tells Docker to create a service called deno that runs the image deno with container name deno and exposes the port that we will later set to 8080. The actual instructions for building the image are in the Dockerfile file.

Dockerfile

Create a file named Dockerfile in the root directory of your folder.

DOCKERFILE
FROM denoland/deno:latest as base WORKDIR /app COPY . ./ RUN deno cache server.ts CMD ["run", "--allow-net", "server.ts"]

When you take it line by line, it's actually straightforward.

DOCKERFILE
FROM denoland/deno:latest as base

This tells Docker to get the latest version of the deno Docker image by denoland and name this image base.

DOCKERFILE
WORKDIR /app

This tells Docker to switch to and run the app in the /app directory.

DOCKERFILE
COPY . ./

This tells Docker to copy everything to the root of the container's working directory.

DOCKERFILE
RUN deno cache server.ts

This compiles server.ts so that we don't need to keep compiling it every time we start the container.

DOCKERFILE
CMD ["run", "--allow-net", "server.ts"]

This tells Docker to run server.ts with the added flag --allow-net so that it can access network resources, which is needed since we are running a web server.

Env file

Before we can deploy our app on a Docker container, we need to set up the environment variables that we will need to run the app. Create a file named .env in the root directory of your folder.

Since we defined the port as a variable in the docker-compose.yml file, we need to set the port in the .env file.

BASH
PORT=8080

Running the app

Finally we are ready to deploy the app on a Docker container. To do so, use Docker Compose.

BASH
docker compose up --build

On the first build, you don't need the build flag, but you will in subsequent runs. If successful, you should see something like this:

The Docker Compose output.

The app is now built and accessible at http://localhost:8080/ just like before, however now the app is running in Docker.

The Deno app running on port 8080.

You can confirm the container is running in Docker, along with all of the other containers that are running by using the docker ps command.

BASH
docker ps
BASH
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba804e8bff5f deno "docker-entrypoint.s…" 5 seconds ago Up 5 seconds 0.0.0.0:8080->8080/tcp deno

You can stop the running container by then running docker compose down.

Deploying to Production

Now that your Deno app has been containerized successfully, it is ready to be deployed to whatever environment you want. This tutorial showed how to deploy it on your own machine, however, this Docker container can be deployed on a staging environment, remain local, or be deployed to a production environment.

To deploy it to production, you will need some kind of server or hosting platform to host the app. There are several different options for hosting, each with their pros and cons. In addition, if your app is a web app, it will likely need a domain as well. Either way, containerizing your app using Docker is becoming the industry standard and it will certainly help you get your app accessible to your users.

Conclusion

Docker is a powerful tool for a developer to learn and use. As you saw, with just a few lines in your Dockerfile, you can set up a full-blown Deno app. This makes deploying the app anywhere you want a breeze. I hope this tutorial has helped you get a better understanding of Docker and Docker Compose. Happy deploying!

Docker's hot for a reason though!

Resources

  1. Docker
  2. Docker Compose docs
  3. Deno Homepage
  4. Deno Official Docker Image
Recommended Tutorial »
Copyright © 2017 - 2024 Sabe.io. All rights reserved. Made with ❤ in NY.