Deepak Vishwakarma
6 min readAug 13, 2020

--

Photo by Timelab Pro on Unsplash

Deno By Example

Run Deno Application on Docker | Continuous Integration and Deployment

Before starting code, Let's understand the concept of CICD in brief. This will give us the motive to read this blog further.

Continuous Integration (CI) is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early.

By- ThoughtWorks’ definition for CI

Read more: https://www.thoughtworks.com/es/continuous-integration

Continuous Delivery is the ability to get changes of all types — including new features, configuration changes, bug fixes, and experiments — into production, or into the hands of users, safely and quickly in a sustainable way.

By- Jez Humble’s site

Read more: https://continuousdelivery.com/

As we can see, there are many reasons why we should follow the CICD in our project development cycle. The one of reason why I follow CICD in daily work. It eases my work and I get a consistent environment for my development work. So that I can focus on more good things rather than debugging Binary breaking issues.

If you want to read more on CICD, You can read this article.

Photo by Andrik Langfield on Unsplash

In this tutorial, I will mainly focus on how you can set up Simple Deno Web Application just using some docker commands. In the next tutorial, I will explain how to set up a FullStack Deno Application.

1. Create a simple Deno WebApp

To show a working example, We need to create a sample application. Since the focus of this tutorial is not to create WebApp. I will recommend you to check out my tutorial here or medium.

The given app is a Server Side Render(SSR) app. It has some basic functionalities. You can checkout source in /examples/ssr folder.

Once you run the app, Open http://localhost:8000/ on the browser.

cd examples/ssrdeno run --allow-net --allow-read --unstable server.tsx -c tsconfig.json

2. Create a Dockerfile

The app looks good! Let’s now create a Dockerfile to start with.

md docker-app && touch Dockerfile

To test our docker is working fine, Let’s add some Hello World program.

FROM alpineRUN echo "Hello Stanger!"

Build and Run:

docker build -t chucknorris .
docker run -it chucknorris

Explanation: Here in above Dockerfile, First We are pulling the lightest Linux based OS. Once pull done, We are trying to Run echo command. If all good, you will see below output.

---> Running in 5215187d3d6a
Hello Stanger!
Removing intermediate container 5215187d3d6a

The above output tells us, things are OK.

3. Install Deno Using docker

By default, Alpine image does not have any external software. This is one of the thinnest Linux clients. To install Deno, We need to curl the Deno binary. You can read all the details on Deno WebSite.

Let’s add curl using Dockerfile.

FROM alpineRUN apk update && apk add curl
ENTRYPOINT ["curl"]
CMD [ "curl", "https://api.chucknorris.io/jokes/random" ]

Build and Run:

docker build -t chucknorris .
docker run -it chucknorris

Once you run you will see output along with Chuck Norris joke. I got my joke as “Chuck Norris once threw a ‘block party’. The city of Detroit filed for bankruptcy the next day”. If you are lucky, You may get a funnier joke.

Download Deno binary: Now time to install/download pre-compiled version of Deno binary.

FROM alpineRUN apk update && apk add curlRUN curl -fsSL https://deno.land/x/install/install.sh | sh && mv /root/.deno/bin/deno /bin/denoENTRYPOINT ["dono"]CMD ["run", "--allow-net", "https://deno.land/std/examples/welcome.ts"]

Build and Run:

docker build -t deno-app .
docker run -it deno-app

There are some compiled libraries missing on Alpine image. So when you try to run Deno you may see an error like standard_init_linux.go:211: exec user process caused. To fix the above error, We will your modified the version of Alpine Image.

Let’s update our docker file.

FROM frolvlad/alpine-glibc:alpine-3.11_glibc-2.31RUN apk update && apk add curlRUN curl -fsSL https://deno.land/x/install/install.sh | sh && mv /root/.deno/bin/deno /bin/denoENTRYPOINT ["deno"]CMD ["run", "--allow-net", "https://deno.land/std/examples/welcome.ts"]

Explanation: Once we pulled the image, We used curl to get the installation script from deno website and download the deno binary. Since the default path of deno binary is not the bin. So we need to copy binary to the bin. You can find a better way to set up a path. ENTRYPOINT is to tell docker what command to use when we run docker run command. CMD is the command to run.

If all OK, you will see bellow output.

❯ docker run -it deno-app
Download https://deno.land/std@0.64.0/examples/welcome.ts
Check https://deno.land/std@0.64.0/examples/welcome.ts
Welcome to Deno 🦕

4. Running Todo App

We have done excellent job. The 90% of work, has been already done. Let’s run our todo-app. For that, we need to copy all the required files to the docker image. We can do either using COPY command or mount volume. I will show both ways of doing it. However, recommended is to use COPY. This is to decouple your system from Docker.

Error: If you try to access files out of Dockerfile folder. You will get error, The forbidden path outside the build context. So to avoid this error, We have to copy files from /examples/ssr folder to examples/docker-app.

pwd
#something/examples/docker-app
cp -r ../ssr ./ssr

Update Dockerfile to copy files.

FROM frolvlad/alpine-glibc:alpine-3.11_glibc-2.31
RUN apk update && apk add curl
RUN curl -fsSL https://deno.land/x/install/install.sh | sh && mv /root/.deno/bin/deno /bin/deno
WORKDIR /app
COPY ssr/ /app/
ENTRYPOINT ["deno"]
CMD ["run", "--allow-net", "--allow-read", "--unstable", "server.tsx", "-c", "tsconfig.json"]

Build and Run:

docker build -t deno-app .
docker run -d deno-app
## output
# f75f6e55675b1f8558fcfe2c34cd25f366aacc4b0f6b5df7d7982bf3cea3c46d
## Note down the output of last commanddocker logs f75f6e55675b

Note: if you notice, for the first time we have run docker in detached mode ie. docker run -d. Since we are running a long-running server, We should detach the Docket image from our system.

Explanation: Since we are running a docker container in detached mode. We have to grab container-id to see logs of the last docker run.

docker ps | grep todo-appdocker logs f75f6e55675b

You can see output like the server is running on http://localhost:8000/. However, when you try to access http://localhost:8000/ on the browser. You cant access it. This is because the docker runs containers in isolation. It does not implicitly expose ports out of the container. To do so, We have to expose port in docker file and same time need bind to external port while running the command.

## rest of the commandWORKDIR /app
EXPOSE 8080
COPY ssr/ /app/
## rest of the command

Build and run with port binding:

docker build -t deno-app .
docker run -d -p8000:8000 deno-app

Open http://localhost:8000/ in the browser, You can see running todo app on the browser.

As i told you that you can run the file without COPY command using volume mount. For that let us remove COPY command from Dockerfile.

## DockerfileFROM frolvlad/alpine-glibc:alpine-3.11_glibc-2.31
RUN apk update && apk add curl
RUN curl -fsSL https://deno.land/x/install/install.sh | sh && mv /root/.deno/bin/deno /bin/deno
WORKDIR /app
EXPOSE 8080
ENTRYPOINT ["deno"]
CMD ["run", "--allow-net", "--allow-read", "--unstable", "server.tsx", "-c", "tsconfig.json"]

Build and Run:

docker build -t deno-app .
docker run -d -p8000:8000 -v ${PWD}/ssr:/app deno-app

Some Useful Docker Commands

Photo by Sam Dan Truong on Unsplash
Docker Images: docker images ls
Running Process: docker ps
Stop container: docker stop container-id
Stop all container time before: docker ps | grep " minutes ago" | awk '{print $1}' | xargs docker stop
Remove Images: docker rmi -f id1 id2 id3
Logs: docker logs f75f6e55675b

Source: You can get all source code on GitHub. examples/docker-app

Originally published at https://decipher.dev.

--

--

Deepak Vishwakarma

I am a polyglot Blockchain Developer. Mainly work on JavaScript and Nodejs. I work for a multinational Bank as Tech Lead to define the best architecture.