Running DADI Web in a container

This is the first article in a series of articles which will take you through the containerization of three core DADI web services: Web, API, and CDN.

🔗Part I: Running DADI Web in a container

This is the first article in a series of articles which will take you through the containerization of three core DADI web services: Web, API, and CDN.

The first service we’ll containerize is DADI Web, our schemaless templating layer. First we’ll create a standard Web project, and then we’ll containerize it. We’ll go through some of the basics of Docker, and how we can use them alongside DADI Web.

🔗Docker

Docker is an open container platform providing developers and sysadmins with a lightweight method of process & resource isolation, the ability to package an application and all it’s dependencies into a single image, allowing greater levels of automation and portability.

The DADI suite runs on Node.js and works perfectly fine without containers, but by utilising containers, we can gain greater isolation, scalability, and enhance our automation ability as well.

If you haven’t used Docker before, then I’d recommend reading through the Docker getting started guide.

🔗Requirements

For this article I’ll be working with Docker 17.06.2-ce-mac27 and macOS Sierra . If you don’t have Docker installed, you can get it from the Docker Community Edition website.

I’ll also be installing DADI applications with the DADI command line interface, to install that run npm install @dadi/cli -g.

🔗Getting started

We’ll begin by creating a directory for our project and installing DADI Web using the DADI command-line interface tool. When asked to pick a template engine, select @dadi/web-dustjs.

$ mkdir web-project
$ cd web-project
$ dadi web new

Once Web is installed, you should have a number of files & directories. By default, no configuration is necessary. Read more about DADI Web configuration.

Let’s start the application and preview the default site.

$ npm start

Now open http://127.0.0.1:3001.

You should be greeted by the default site. Cool, now let’s containerize it.

🔗Configuring Web

The first thing we need to do is configure DADI Web to work inside a container. Containers don’t by default have a local loopback so we can’t bind our port to 127.0.0.1, instead we need to bind to 0.0.0.0. Open up the config/config.development.json file in your favourite text editor and change the host to 0.0.0.0, and while we’re here, the port to 80 as well.

$ vi config/config.development.json
{
  "global": {
    "site": "Your site name",
    "description": "An exciting beginning."
  },
  "globalEvents": [
    "global"
  ],
  "server": {
    "host": "0.0.0.0",
    "port": 80
  },
  "cluster": false,
  "allowJsonView": true,
  "debug": true
}

DADI Web should now be ready to run in a container.

🔗Creating a Dockerfile

Dockerfiles are like recipes for container images. Traditionally they are kept in the root of the project. Create a file named Dockerfile and open it up in your text editor.

$ vi Dockerfile
FROM node:6.11

RUN mkdir /var/web
ADD . /var/web
WORKDIR /var/web

RUN npm install -q

CMD ["npm", "start"]

First we specify a parent container image that we want to build on top of, in this case, node:6.11, the official Node.js image. Then we create a directory for the service and add in our project files. We set the working directory, run npm install and then, finally, specify the command to run on execution (npm start).

🔗Building a Docker image

Now that we have our Dockerfile setup, we need to build our container image. Docker has images, which are binaries generally built from Dockerfiles, and containers, which are running instances of those images.

Before we do this, let’s create a .dockerignore file. This works a lot like a .gitignore file, and lets us exclude files and directories from being sent to the Docker daemon. This’ll make our build process quicker and more efficient.

$ vi .dockerignore
node_modules
log

Now let’s build our image. With Docker installed, we simply need to tell the Docker CLI to build the image from the current directory. We’ll give it a tag with the -t flag as well so we can refer to it easier later on.

$ docker build -t web-project .

Once the build has finished, we should be able to see the image:

$ docker images | grep web-project

web-project latest 2398fc7376be About a minute ago 770MB

Great. Now we’re ready to run the container.

🔗Running the Docker container

There are two methods that we can use to run the container: in the foreground with an attached tty, or in the background detached. First, let’s test everything’s running okay by running it in the foreground. The -ti flags tell Docker that we want to attach an interactive tty, and the --rm flag will remove the container once we exit.

$ docker run -ti --rm web-project

> @dadi/web-boilerplate@ start /var/web
> node server.js

 ----------------------------
 DADI Web (Repo Default)
 Started 'DADI Web'
 ----------------------------
 Server: http://0.0.0.0:80
 Version: 4.0.2
 Node.JS: 6.11
 Environment: development
 Engine: dust
 API: Disabled
 ----------------------------

You’ll see that the application starts up and is listening, by default, on http://0.0.0.0:80, but we can no longer access the Web service from our browser. We need to setup some port mapping. Let’s exit out of the container with ctrl-c .

Each container connects by default to the docker0 bridge network. This is fine for us but we need to map a port on our host to port 80 on the container. The easiest way to do this is with a direct port mapping using the -p or --publish flag.

Let’s map port 8000 on our host to port 80 on our container.

$ docker run -ti -p 8000:80 --rm web-project

If you open up http://127.0.0.1:8000, you should now be greeted by the default website. Great, it works! Let’s exit out of the container with ctrl-c again and now we’ll start the container in the background, using the -d or --detach flag. We no longer want the container to remove-on-exit so we’ll also remove the --rm flag. We’ll also give the container a name so that we can refer to it later on. You can also refer to containers via their long or short UUID identifiers, but names are much nicer, aren’t they?

$ docker run -d -p 8000:80 --name web-project web-project

403d5e10f5416d7f7a445fb88a851019e6dfd1335a59c35e0d8e2f83c9524c64

We can now see that the container web-project is running.

$ docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
403d5e10f541 web-project "npm start" 22 seconds ago Up 21 seconds 0.0.0.0:8000->80/tcp web-project

We can stop and start this container with the docker stop <id/name> and docker start <id/name> commands, and if we want to create a fresh container with the name web-project then we can remove it with docker rm <id/name> .

That’s all there is to it. You now have a website running in DADI Web.

Next up, Part II: Running DADI API in a container.

Related articles

More tutorials articles
Mail icon

Like what you are reading? Want to earn tokens by becoming a DADI Node? Save money on cloud computing services? Build amazing digital product with DADI Web Services? Join our mailing list.

To hear about our news, events and products or services subscribe now. You can also indicate which services you are interested in, which we use for research and to inform the content that we send generally.

* You can unsubscribe at any time by emailing us at data@dadi.cloud or by clicking on the unsubscribe link which can be found in our emails to you. Read our Privacy Policy.