Running Simple Node.js Application
Running a Basic Node.js application inside a Container
The example I’m going to discuss assumes you have a Docker installation that works in your system and a basic understanding of how to work with Node.js . If you are aware of how you must work with Docker , it should be evident that Node.js framework need not be installed on your system, rather we would be using the latest version of the node image available from Docker. Hence if needed you may download the image beforehand with the command docker pull node. (The command automatically pulls the latest version of the node image from docker.)
-
Proceed to make a directory where all your working application files would reside. Create a
package.jsonfile in this directory that describes your application as well as the dependencies. Yourpackage.jsonfile should look something like this:{ "name": "docker_web_app", "version": "1.0.0", "description": "Node.js on Docker", "author": "First Last <first.last@example.com>", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^4.13.3" } }
-
If we need to work with Node.js we usually create a
serverfile that defines a web application. In this case we use theExpress.jsframework (version4.13.3onwards). A basicserver.jsfile would look something like this:var express = require('express'); var PORT = 8080; var app = express(); app.get('/', function (req, res) { res.send('Hello world\n'); }); app.listen(PORT); console.log('Running on https://localhost:' + PORT); -
For those familiar with Docker, you would have come across a
Dockerfile. ADockerfileis a text file that contains all the commands required to build a custom image that is tailored for your application.
Create an empty text file named Dockerfile in the current directory. The method to create one is straightforward in Windows. In Linux, you may want to execute touch Dockerfile in the directory containing all the files required for your application.
Open the Dockerfile with any text editor and add the following lines:
FROM node:latest
RUN mkdir -p /usr/src/my_first_app
WORKDIR /usr/src/my_first_app
COPY package.json /usr/src/my_first_app/
RUN npm install
COPY . /usr/src/my_first_app
EXPOSE 8080-
FROM node:latestinstructs the Docker daemon what image we want to build from. In this case we use thelatestversion of the official Docker imagenodeavailable from the Docker Hub. -
Inside this image we proceed to create a working directory that contains all the required files and we instruct the daemon to set this directory as the desired working directory for our application. For this we add
RUN mkdir -p /usr/src/my_first_app WORKDIR /usr/src/my_first_app -
We then proceed to install application dependencies by first moving the
package.jsonfile (which specifies app info including dependencies) to the/usr/src/my_first_appworking directory in the image. We do this byCOPY package.json /usr/src/my_first_app/ RUN npm install -
We then type
COPY . /usr/src/my_first_appto add all the application files and source code to the working directory in the image. -
We then use the
EXPOSEdirective to instruct the daemon to make port8080of the resulting container visible (via a container-to-host mapping) since the application binds to port8080. -
In the last step, we instruct the daemon to run the command
node server.jsinside the image by executing the basicnpm startcommand. We use theCMDdirective for this, which takes the commands as arguments.CMD [ "npm", "start" ]
- We then create a
.dockerignorefile in the same directory as theDockerfile
to prevent our copy of node_modules and logs used by our Node.js system installation from being copied on to the Docker image. The .dockerignore file must have the following content:
node_modules
npm-debug.log-
Build your image
Navigate to the directory that contains the Dockerfile and run the following command to build the Docker image. The -t flag lets you tag your image so it’s easier to find later using the docker images command:
$ docker build -t <your username>/node-web-app .Your image will now be listed by Docker. View images using the below command:
$ docker images
REPOSITORY TAG ID CREATED
node latest 539c0211cd76 10 minutes ago
<your username>/node-web-app latest d64d3505b0d2 1 minute ago-
Running the image
We can now run the image we just created using the application contents, the node base image and the Dockerfile. We now proceed to run our newly created <your username>/node-web-app image. Providing -d switch to the docker run command runs the container in detached mode,so that the container runs in the background. The -p flag redirects a public port to a private port inside the container. Run the image you previously built using this command:
$ docker run -p 49160:8080 -d <your username>/node-web-app-
Print the output of your app by running
docker pson your terminal. The output should look something like this.CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7b701693b294 <your username>/node-web-app "npm start" 20 minutes ago Up 48 seconds 0.0.0.0:49160->8080/tcp loving_goldstine
Get application output by entering docker logs <CONTAINER ID>. In this case it is docker logs 7b701693b294.
Output: Running on https://localhost:8080
- From the
docker psoutput, the port mapping obtained is0.0.0.0:49160->8080/tcp. Hence Docker mapped the8080port inside of the container to the port 49160 on the host machine. In the browser we can now enterlocalhost:49160.
We can also call our app using curl:
$ curl -i localhost:49160
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
Date: Sun, 08 Jan 2017 14:00:12 GMT
Connection: keep-alive
Hello world