Running DADI Web in a container


  • DADI

    DADI & Docker series

    Part I: Running DADI Web in a container
    Part II: Running DADI API in a container
    Part III: Running DADI CDN in a container (coming soon)
    Part IV: Running DADI Web, API, and CDN together with Docker & HAProxy (coming soon)

    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.


Log in to reply
 

Looks like your connection to DADI Forum was lost, please wait while we try to reconnect.