<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Steven Roeland | Codestack BV</title>
    <description>The latest articles on DEV Community by Steven Roeland | Codestack BV (@codestackbv).</description>
    <link>https://dev.to/codestackbv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F389206%2Fa68185a5-c376-4a96-b55f-54db95668e5e.png</url>
      <title>DEV Community: Steven Roeland | Codestack BV</title>
      <link>https://dev.to/codestackbv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codestackbv"/>
    <language>en</language>
    <item>
      <title>Running a Containerized Deno Web Application on Microsoft Azure Container Registry</title>
      <dc:creator>Steven Roeland | Codestack BV</dc:creator>
      <pubDate>Tue, 19 May 2020 14:49:32 +0000</pubDate>
      <link>https://dev.to/codestackbv/running-a-containerized-deno-web-application-on-microsoft-azure-container-registry-d2e</link>
      <guid>https://dev.to/codestackbv/running-a-containerized-deno-web-application-on-microsoft-azure-container-registry-d2e</guid>
      <description>&lt;p&gt;This morning my twitter feed featured a post that mentioned &lt;code&gt;Deno&lt;/code&gt;.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OhuewbHq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/media/EX8bWw2UMAAb59k.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--dKX20crG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1235100119231377408/NE1TPoBM_normal.jpg" alt="Jess Telford profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Jess Telford
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @jesstelford
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--52oNvK_0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/twitter-ff4bdab814039c4cb172a35ea369e0ea9c6a4b59b631a293896ae195fa26a99d.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Deno v1.0.0 is out &lt;a href="https://t.co/Yt7DLGwsEJ"&gt;github.com/denoland/deno/…&lt;/a&gt;&lt;br&gt;&lt;br&gt;Node devs, prepare yourselves! 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      02:19 AM - 14 May 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1260756707690418177" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-reply-action.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1260756707690418177" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-retweet-action.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      363
      &lt;a href="https://twitter.com/intent/like?tweet_id=1260756707690418177" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="/assets/twitter-like-action.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
      1891
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Not really knowing what the fuss was all about I started doing some research and eventually I ended up with a full web application running containerized on Microsoft Azure using Container Instances. What a beautiful day indeed. In this post I will give you a step-by-step overview of how I got to that point and what the challenges and hiccups were along the road.&lt;/p&gt;

&lt;p&gt;But first, let's take a look at what Deno really is. From the &lt;a href="https://deno.land/"&gt;official website&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Secure by default. No file, network, or environment access, unless explicitly enabled.&lt;/li&gt;
&lt;li&gt;Supports TypeScript out of the box.&lt;/li&gt;
&lt;li&gt;Ships only a single executable file.&lt;/li&gt;
&lt;li&gt;Has built-in utilities like a dependency inspector (deno info) and a code formatter (deno fmt).&lt;/li&gt;
&lt;li&gt;Has a set of reviewed (audited) standard modules that are guaranteed to work with Deno: deno.land/std&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Deno project was created by Ryan Dahl, original creator of Node.js.&lt;br&gt;
I would strongly encourage you to watch 2 talks from him on YouTube which make a lot of things clear: &lt;a href="https://youtu.be/M3BM9TB-8yA"&gt;10 Things I Regret About Node.js&lt;/a&gt; and &lt;a href="https://youtu.be/HjdJzNoT_qg"&gt;Deno, a new way to JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just to make sure, this article will not be a &lt;em&gt;Node vs Deno&lt;/em&gt; discussion. This article will show you how to serve an application using containerized Deno. That being said, buckle up, let's get started.&lt;/p&gt;

&lt;p&gt;Getting your application up and running will come down to this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an Azure account if you don't have one yet&lt;/li&gt;
&lt;li&gt;Create an Azure Container Registry&lt;/li&gt;
&lt;li&gt;Install docker desktop + Deno&lt;/li&gt;
&lt;li&gt;Build the Deno docker image&lt;/li&gt;
&lt;li&gt;Push the Deno docker image to your Container Registry&lt;/li&gt;
&lt;li&gt;Create a Container Instance off your docker image&lt;/li&gt;
&lt;li&gt;See if everything works and cheer if it does&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Setup an Azure account if you don't have one yet
&lt;/h4&gt;

&lt;p&gt;Having worked a lot with Google Cloud Platform(GCP)/Kubernetes on my last project, I chose Azure to host my docker images this time to see what they had done related to containers since the last time I used it. Getting started with Azure is really easy. Just head over to the &lt;a href="https://azure.microsoft.com/en-us/"&gt;Microsoft Azure Website&lt;/a&gt; and create a new account. You can start off for free and even get free credit for the first month.&lt;/p&gt;

&lt;p&gt;Of course, you can choose whichever platform you like to host your docker containers. For the sake of this demo, I will include the steps to configure this on Azure.&lt;/p&gt;
&lt;h4&gt;
  
  
  Create an Azure Container Registry
&lt;/h4&gt;

&lt;p&gt;Once you have your Azure account all set up, on the &lt;a href="https://portal.azure.com/"&gt;portal&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search for &lt;code&gt;Container Registries&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;select &lt;code&gt;Add&lt;/code&gt; in the top left corner&lt;/li&gt;
&lt;li&gt;provide a &lt;code&gt;Resource group&lt;/code&gt; and &lt;code&gt;Registry name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Next through the remaining steps of the wizard to Create a new registry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once your registry is created, head over to the &lt;code&gt;Access keys&lt;/code&gt; section in the &lt;code&gt;Settings&lt;/code&gt; section of your registry.&lt;br&gt;
Enable the &lt;code&gt;Admin user&lt;/code&gt; toggle. This will allow us to connect to the repository using &lt;code&gt;docker login&lt;/code&gt; later on.&lt;/p&gt;
&lt;h4&gt;
  
  
  Install docker desktop + Deno
&lt;/h4&gt;

&lt;p&gt;Head over to the official &lt;a href="https://www.docker.com/products/docker-desktop"&gt;Docker Website&lt;/a&gt; and download the correct version of Docker Desktop for your machine. This article will not cover docker itself. I advise you to go through &lt;a href="https://docs.docker.com/get-started/overview/"&gt;the excellent docs&lt;/a&gt; on the docker website to get familiar with the main concepts if you aren't already.&lt;/p&gt;

&lt;p&gt;When building a Deno application, it might also be nice to install.. Deno.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using PowerShell&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iwr https://deno.land/x/install/install.ps1 -useb | iex
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will allow you to run your Deno application without having to actually &lt;code&gt;docker build&lt;/code&gt; and &lt;code&gt;docker run&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Build the Deno docker image
&lt;/h4&gt;

&lt;p&gt;Aha! Now that we have all of that out of the way, let's build the actual web application.&lt;br&gt;
For now, it seems as if there are no official Docker images YET (I will update the article accordingly when official Deno Docker containers appear online). Via one of the &lt;a href="https://github.com/denoland/deno/issues/3356"&gt;github issues&lt;/a&gt; on the Deno repo I came across this nice &lt;a href="https://github.com/hayd/deno-docker"&gt;&lt;code&gt;deno-docker&lt;/code&gt;&lt;/a&gt; project which I used as a starting point.&lt;/p&gt;

&lt;p&gt;Create a new project folder somewhere on your filesystem. At a bare minimum, you will need the following 3 files:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A static html page to serve (index.html)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's start with the html file. Create a subfolder named &lt;code&gt;public&lt;/code&gt; in your project folder and add an &lt;code&gt;index.html&lt;/code&gt; file.&lt;br&gt;
You can go as crazy as you want with the content, that really is outside of the scope of this article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An entry point for your application (main.ts)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a file called &lt;code&gt;main.ts&lt;/code&gt; at the root of your project folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Application } from 'https://deno.land/x/abc/mod.ts';

const PORT = 80;
const app = new Application();

app
  .static('/css', 'public/assets/css')
  .file('/', 'public/index.html')
  .start({ port: PORT });

console.log(`Server started on port ${PORT}`);

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's take a second to see what's going on here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Application&lt;/code&gt; is imported from &lt;code&gt;abc&lt;/code&gt;. &lt;code&gt;abc&lt;/code&gt; is a Deno framework to create web applications. More info &lt;a href="https://github.com/zhmushan/abc"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;the application will be started at port &lt;code&gt;80&lt;/code&gt;. I chose &lt;code&gt;80&lt;/code&gt; specifically as this plays along nice with (the limitation of) Azure Container Instances. More on that, further on.&lt;/li&gt;
&lt;li&gt;app.static() static registers a new route to serve files from the provided root directory&lt;/li&gt;
&lt;li&gt;app.file() registers a new route with path to serve a static file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A Dockerfile to create your container image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, we add the file that will allow us to create a nice Docker image of our web application.&lt;br&gt;
Add a file called &lt;code&gt;Dockerfile&lt;/code&gt; to your root project folder (no extension). This is how it should look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM hayd/alpine-deno:1.0.0

EXPOSE 80

WORKDIR /app

ADD . .
RUN deno cache main.ts

CMD ["run", "--allow-net", "--allow-read", "main.ts"]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's take another second to see what's going on HERE.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FROM hayd/alpine-deno:1.0.0&lt;/code&gt; specifies the pre-existing image to start from&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EXPOSE 80&lt;/code&gt; informs Docker that the container is listening on port 80 at runtime.&lt;/li&gt;
&lt;li&gt;the &lt;code&gt;CMD&lt;/code&gt; directive references the &lt;code&gt;main.ts&lt;/code&gt; file we created earlier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would like to delve a little deeper into the &lt;code&gt;CMD&lt;/code&gt; directive here. It describes how to run a container based on the image we are creating. The command that will be executed in a container will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;deno run --allow-net --allow-read main.ts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With Deno, code is executed in a secure sandbox by default. Scripts cannot access the hard drive, open network connections, or make any other potentially malicious actions without permission.\&lt;br&gt;
Users must first give permission. Deno provides analogous behavior in the terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--allow-net&lt;/code&gt; allows network access&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--allow-read&lt;/code&gt; allows read access to the file system. This is necessary for our &lt;code&gt;abc&lt;/code&gt; framework to serve our html file.&lt;br&gt;
If you don't specify the &lt;code&gt;--allow-read&lt;/code&gt; flag, you will run into the following error at runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{"statusCode":500,"error":"Internal Server Error","message":"read access to \"C:\\deno-web-app\", run again with the --allow-read flag"}

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Since we're talking error messages.. One thing I ran into was that initially, the &lt;code&gt;Dockerfile&lt;/code&gt; specified a user with limited permissions. This throws a very cryptic exception:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error: Uncaught PermissionDenied: Permission denied (os error 13)
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at listen ($deno$/net.ts:152:22)
    at serve (https://deno.land/std@0.50.0/http/server.ts:261:20)
    at file:///app/main.ts:4:11
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As it turns out, this was because we want to serve the application on port &lt;code&gt;80&lt;/code&gt;. Non-privileged user (not root) can't open a listening socket on ports below 1024. Thank you &lt;a href="https://stackoverflow.com/questions/9164915/node-js-eacces-error-when-listening-on-most-ports"&gt;StackOverflow&lt;/a&gt;.&lt;br&gt;
To solve this, make sure that user running the process (which can be specified by using &lt;code&gt;USER&lt;/code&gt; in your &lt;code&gt;Dockerfile&lt;/code&gt;) has enough permission. In our case, just omitting the &lt;code&gt;USER&lt;/code&gt; works just fine.&lt;/p&gt;

&lt;p&gt;Now that we have everything in place. Let's build our Docker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t deno-web-app .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Push the Deno docker image to your Container Registry
&lt;/h4&gt;

&lt;p&gt;Now that we've built that shiny Docker image, let's push it to our registry.&lt;br&gt;
To do that, of course, we have to follow a few more steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;login to your Azure Container Registry&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker login [your-azure-registry-name].azurecr.io
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You'll be prompted for a username and password. Use the credentials you configured in the beginning of this article while creating your registry.&lt;/p&gt;

&lt;p&gt;After that, prefix the image with your registry login URI so that it can be pushed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker tag deno-web-app [your-azure-registry-name].azurecr.io/deno-web-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And finally, push your image to your registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker push [your-azure-registry-name].azurecr.io/deno-web-app
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Create a Container Instance off your docker image
&lt;/h4&gt;

&lt;p&gt;So now that we got the image in our registry, it's time to create an actual container, so that we can actually host our web application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to Azure &lt;a href="https://portal.azure.com/"&gt;portal home page&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;In the search box type &lt;code&gt;Container instances&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;select &lt;code&gt;Add&lt;/code&gt; in the top left corner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This will bring up a step wizard where you need to provide some information about the Container Instance you're about to create.&lt;/p&gt;

&lt;p&gt;On the first step&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide a &lt;code&gt;Resource group&lt;/code&gt; and a &lt;code&gt;Container name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Azure Container Registry&lt;/code&gt; as your &lt;code&gt;Image source&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the correct &lt;code&gt;Registry&lt;/code&gt; and &lt;code&gt;Image&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;for now, just use &lt;code&gt;latest&lt;/code&gt; as &lt;code&gt;Image tag&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the next step - Networking - just enter a nice DNS name label, so that you will have a nice url to access your application.&lt;br&gt;
You can leave the default port settings.&lt;/p&gt;

&lt;p&gt;When working with Docker containers, it is common to match the TCP port in the container to a port on the Docker host. One of the limitations I ran into with Azure Container Registries (as far as I can tell) is that this kind of port forwarding is not possible here. This is the reason why, in the &lt;code&gt;Dockerfile&lt;/code&gt; I opted to open up port &lt;code&gt;80&lt;/code&gt; in the container by using &lt;code&gt;EXPOSE 80&lt;/code&gt;. That way it will do a &lt;code&gt;PORT 80:80&lt;/code&gt; binding between host and container.&lt;/p&gt;

&lt;p&gt;Anyways, &lt;em&gt;next&lt;/em&gt; through the remaining steps of the wizard to Create your Container instance.&lt;/p&gt;

&lt;h4&gt;
  
  
  See if everything works and cheer if it does
&lt;/h4&gt;

&lt;p&gt;After a few moments, Azure should finish creating your Container Instance.&lt;br&gt;
You should now be able to see your web application running at the url you just configured.&lt;br&gt;
To find the exact url, look for the &lt;code&gt;FQDN&lt;/code&gt; property of your &lt;code&gt;Container Instance&lt;/code&gt; on its &lt;code&gt;Overview&lt;/code&gt; page.&lt;/p&gt;

&lt;p&gt;All good? Hooray!&lt;/p&gt;

&lt;h4&gt;
  
  
  tl;dr
&lt;/h4&gt;

&lt;p&gt;The complete code for this article is available on &lt;a href="https://github.com/codestack-bv/deno-web-app"&gt;our GitHub repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code on the repo slightly deviates from the code snippets used in this article. The index page of the web application on the repo has a templated landing page and therefore loads additional static content in the &lt;code&gt;main.ts&lt;/code&gt; file. Also, the &lt;code&gt;abc&lt;/code&gt; dependency was moved to a separate file.&lt;/p&gt;

&lt;p&gt;This however changes nothing to the main building blocks discussed in this article and therefore, for the sake of simplicity, it was not mentioned here.&lt;/p&gt;

&lt;h4&gt;
  
  
  Final words
&lt;/h4&gt;

&lt;p&gt;I really enjoyed learning about the Deno project. I really hope this article can be of value for anyone getting started with Deno, docker or Azure Container Registries. If you found this article useful, give us a quick shoutout on our new &lt;a href="https://twitter.com/CodestackBV"&gt;twitter account&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And with that, I would like to thank you for following along with me on my first REAL blog post.&lt;/p&gt;

&lt;p&gt;I hope to welcome you here for another one.&lt;/p&gt;

</description>
      <category>deno</category>
      <category>azure</category>
      <category>docker</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
