In this guide, we'll introduce how to use NodeJS and Docker to create a web service on the Edge. Our goal is to create a web application that accepts an HTTP request and returns the nearest StackPath PoP's airport code where an example container is running.
Note: Here we will use Docker, a popular package for building and deploying containers, though any container image that adheres to the OCI specification can be deployed onto Edge Computing.
Before we get started, let's make sure you have a few basic requirements out of the way.
You should have:
- Docker installed on your machine
- NodeJS & NPM installed
- A repository to host docker images (DockerHub or Docker server)
Basic Components of the Application
- Dockerfile: Configuration file that instructs the runtime how to build your container
- package.json: Configuration file for NodeJS
- .dockerignore: Files to ignore when building the container image
- server.js: Javascript script to handle inbound requests to the container
Create your package.json
The package.json will bring some order to your Nodejs application. A package.json helps to organize versioning, dependencies and gives a reproducible template to help others easily rebuild your project.
- Run NPM init to start your project
>npm init
- The initialization will prompt you with a series of fields to fill. Fill in these fields with your app's information
- Since we'll be using Express, you will need to install this package to your default node modules. the "--save" flag will additionally add your Express to your package dependencies.
>npm install --save express
- Open package.json with a text editor of your choice and add the following options
{ "name": "nodejs_web_app", "version": "1.0.0", "description": "Node.js on Docker", "author": "StackPath", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, "dependencies": { "express": "^4.16.1" } }
The line, "start": "node server.js", enables "npm start" to run server.js when your working directory inside your project directory.
Now that your NPM module is complete, we can move onto writing the application itself. Below is the full package.json file we created in this section.
{
"name": "nodejs_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "StackPath",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
Write the Server app
Now we'll get started on the logic of your container application. This app will use a very simple script to handle a request and return the airport code of that request. Feel free to use this script yourself to get started or expand its functionality.
- Create a directory and install npm modules
>mkdir compute_webserver && cd compute_webserver >npm install
>touch server.js - Open server.js with your text editor. Declare the packages being used in this module. We'll use Express to set up handle the incoming web requests.
'use strict'; const express = require('express');
- Declare the port and host the web server will listen on
const PORT = 80;
- Use Express to handle the incoming request object and respond with a JSON formatted HTML body.
app = express();
app.listen(PORT);
app.get('/', (req, res) => {
var hostname = process.env["HOSTNAME"].split("-"); res.send(hostname[hostname.length -2]); }); - Tell Express to listen on the port and log this to the container output when the application starts.
console.log(`Listening on ${PORT}`);
You now have all the logic to return a PoPs airport code in the body of a response. next we'll work on setting up a Docker configuration to containerize this application.
'use strict';
const express = require('express'); const PORT = 80; const app = express();
app.listen(PORT);
app.get('/', (req, res) => {var hostname = process.env["HOSTNAME"].split("-"); res.send(hostname[hostname.length -2]);
});
console.log(`Listening on ${PORT}`);
Create your Dockerfile
A Dockerfile manages how docker will build your application when the container is opened. This file is roughly a list of commands run in the containers CLI.
- Create your dockerfile
>touch Dockerfile
- Use your text editor of choice to open Dockerfile.
- Load the Node version 8 base container image and copy the package.json to
FROM node:8 WORKDIR /usr/src/app COPY package*.json ./
- Install npm modules and copy contents of the current folder
RUN npm install COPY . .
- Open port 80 and start the npm server
EXPOSE 80 CMD [ "npm", "start" ]
The Dockerfile we just created does a couple of really interesting things. First, it imports a pre-made Node container image, then we move our application contents into that folder and start it up. This simplicity of deployment emphasizes how incredibly powerful containers can be.
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 80
CMD [ "npm", "start" ]
Build your Docker Image
Building your docker image will bundle all of the needed assets for your application to run on any machine with Docker installed. Before we build the Docker image, let's ignore any unnecessary files to reduce the container image size.
- Create a .dockerignore file in your app root and open it in a text editor. Add the node_modules folder inside and save the file.
node_modules
- Now that the project is ready, use Docker to build your image.
>docker build -t <your name>/compute_webserver .
A local repository has been created. It contains the full image file that can be deployed with any container manager. To view the new image, use the command "docker images"
>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<your_repo>/compute_webapp latest 418a87009dad 3 hours ago 895MB>
Deploy your Image locally
Before your image is deployed on the StackPath environment, let's make sure it works as we expect on your local computer.
- Start the container image and port forward port 80 inside on the container to port 49160 on your local machine. Here we use the -e flag to set an environment variable our script needs to pull the PoP airport code, the -p flag for port forwarding, and the -d flag for detaching the runtime from your current terminal session.
>docker run -p 49160:80
-e HOSTNAME='compute-webapp-dfw-0'
-d <your_repo>/compute_webapp - Open a browser and enter http://0.0.0.0:49160 in the address bar. Verify the container is working properly and returning a "DFW" in the browser.
- Run docker ps to display active containers
>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8a33b021b1bb rransom/compute_webapp "npm start" 5 seconds ago Up 4 seconds 0.0.0.0:49160->80/tcp nervous_thompson - Let's shut down the container
>docker stop <container id>
Now that we've confirmed the Docker image built successfully, its time to deploy the script onto Edge Computing.
Push the new docker image by its Repository name to your DockerHub or personal docker repository.
>docker push <your_repo>/compute_webapp
Now your docker image is publicly accessible and everything is set up for easy deployment on Edge Computing.
Deploy your image on Edge Computing
- Create a new Workload
- Select the Workload Type: Container. Use the repository you pushed your Docker image to in the Image field.
- Select port 80 for your workload public ports
- Select and name locations, server size, and deploy your image.
Congratulations, your first web application has been containerized. In less than a minute StackPath will partition IP addresses to your Pod and the web application will be live.
Use the Application
Now that your container is deployed, lets test that your code behaves as you expect. If you build your application to this document's specification, every response should return a three letter airport code in the response body.
- Pull the container's unicast IP address from the StackPath Control Panel.
- Navigate to this IP address in your browser window.
- If you have an Anycast IP address, your request will hit the nearest container to you and return the location's airport code.