Angular 6 for Enterprise:Ready Web Applications
上QQ阅读APP看书,第一时间看更新

Containerizing the app using Docker

Docker docker.io is an open platform for developing, shipping, and running applications. Docker combines a lightweight container virtualization platform with workflows and tooling that help manage and deploy applications. The most obvious difference between Virtual Machines (VMs) and Docker containers are that VMs usually are dozens of gigabytes in size and require gigabytes of memory, whereas containers are megabytes in disk and memory size requirements. Furthermore, the Docker platform abstracts away host operating system (OS) level configuration settings, so every piece of configuration that is needed to successfully run an application is encoded within the human-readable Dockerfile format, as demonstrated here:

Dockerfile
FROM
duluca/minimal-node-web-server:8.11.1
WORKDIR /usr/src/app
COPY dist public

The preceding file describes a new container that inherits from a container named duluca/minimal-node-web-server, changes the working directory to /usr/src/app, and then copies the contents of dist folder from your development environment into the container's public folder. In this case, the parent image is configured with an Express.js server to act as a web server to serve the content inside the public folder. Refer to the following diagram for a visual representation of what's happening:

Context of a Docker Image

At the base layer is our host OS, such as Windows or macOS that runs the Docker runtime, which will be installed in the next section. The Docker runtime is capable of running self-contained Docker images, which is defined by the aforementioned Dockerfile. duluca/minimal-node-web-server is based off of the lightweight Linux operating system Alpine. Alpine is a completely pared down version of Linux that doesn't come with any GUI, drivers or even most CLI tools you may expect from a Linux system. As a result, the OS is around only ~5 MB in size. The base package then installs Node.js, which itself is around ~10 MB in size and my custom Node.js-based Express.js web server, resulting in a tiny ~15 MB image. The Express server is configured to serve the contents of the /usr/src/app folder. In the preceding Dockerfile, we merely copy the contents of the /dist folder in our development environment and place it into the /usr/src/app folder. We will later build and execute this image, which will run our Express web server containing the output of our dist folder.

The beauty of Docker is that you can navigate to https://hub.docker.com, search for duluca/minimal-node-web-server, read its Dockerfile, and trace its origins all the way back to the original base image that is the foundation of the web server. I encourage you to vet every Docker image you use in this manner to understand what exactly it brings to the table for your needs. You may find it either overkill or has features you never knew about that can make your life a lot easier. Note that the parent images require a specific version of duluca/minimal-node-web-server at 8.11.1. This is quite intentional, and as the reader, you should choose the latest available version of a Docker image you find. However, if you don't specify a version number, you will always get the latest version of the image. As more versions of an image is published, you may pull a future version that may break your application. For this reason, always specify a version number for images you're depending on.

One such case is the HTTPS redirection support that is baked into duluca/minimal-node-web-server. You can spend countless hours trying to set up a nginx proxy to do the same thing, when all you need to do is add the following line to your Dockerfile:

ENV ENFORCE_HTTPS=xProto

Just like npm packages, Docker can bring great convenience and value, but you must take care to understand the tools you are working with.

In Chapter 11, Highly-Available Cloud Infrastructure on AWS, I mention the use of a lower footprint docker image based on Nginx. If you're comfortable configuring nginx, you can use duluca/minimal-nginx-web-server as your base image.