The application server

For this component, we will pick a framework with a minimal amount of boilerplate needed to get a service up and operational, which most people would say today is Node.js with Express. Since Node.js is based on JavaScript, which was originally based on a Java-like syntax, most people who worked on HTML should be able to figure out what the application code is be doing, but before we get there, we need to define our Node package and our dependencies, so create a new application_server directory on the same level as web_server and add the following to a file called package.json:

{
"name": "application-server",
"version": "0.0.1",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.15.4"
}
}

There's nothing really magical here; we're just using a Node package definition file to declare that we need Express as a dependency and that our npm start command should run node index.js.

Let's also make our Dockerfile now:

FROM node:8

# Make sure we are fully up to date
RUN apt-get update -q &&
apt-get dist-upgrade -y &&
apt-get clean &&
apt-get autoclean

# Container port that should get exposed
EXPOSE 8000

# Setup any variables we need
ENV SRV_PATH /usr/local/share/word_test

# Make our directory
RUN mkdir -p $SRV_PATH &&
chown node:node $SRV_PATH

WORKDIR $SRV_PATH

USER node

COPY . $SRV_PATH/

RUN npm install

CMD ["npm", "start"]

Many of these things should be very familiar here, especially with people familiar with Node. We are starting with the node:8 image, adding our application code, installing the dependencies we defined in package.json (with npm install), and then finally making sure that the app starts when run from the docker CLI.

The order here is pretty important to both avoid cache breaking and ensure proper permissions. We place things that we don't expect to change much (USER, WORKDIR, EXPOSE, mkdir, and chown) above COPY since they are much less likely to change as opposed to the application code and since they're mostly interchangeable, we arrange them in the ascending order of what we think are the least likely to change in the future in order to prevent rebuilding of layers and wasted computing power.

Here is also a Node.js-specific image optimization trick: since npm install is usually the most time and CPU intensive part of dealing with code changes to a Node application, you can even further optimize this Dockerfile by copying only package.json, running npm install, and then copying the rest of the files to the container. Creating the container in this manner will only do the pricey npm install if package.json changes and will generally improve build times by a large margin, but this was excluded from this example in order to not derail our main conversation with framework-specific optimizations.

So far, we haven't really defined any application code, so let's see what that looks like too. First, we need an HTML view to be our landing page, and we can throw one together pretty quickly using a pug (formerly also known as jade) template. Create a views/ folder and put this in a file named index.pug located in that folder:

html
head
title Docker words
body
h1 Saved Words

form(method='POST' action='/new')
input.form-control(type='text', placeholder='New word' name='word')
button(type='submit') Save

ul
for word in words
li= word

You don't have to know much about this templating style except that it is a simple HTML page on which we will display all items from the words array passed into it during rendering, and if a new word is put in, there will be a form submitted as a POST request to the /new endpoint.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset