{{announcement.body}}
{{announcement.title}}

Docker: Ready! Steady! Deploy!

DZone 's Guide to

Docker: Ready! Steady! Deploy!

Take a look at how Docker can be used to set up and deploy applications to any environment manually or with Travis CI.

· Cloud Zone ·
Free Resource

How often have you had to set up a server environment to deploy your application? Probably more often than you would like.

At best, you had a script performing all the operations automatically. At worst, you had to:

  • Install the D database of the x.x.x version;
  • Install the N web server of the x.x version;
  • and so on...

Over time, environmental management configured in this way becomes very resource-intensive. Any minor change in configuration means at least that:

  • every member of a development team should be aware of this change;
  • this change should be safely added to the production environment.

It is challenging to track changes and manage them without special tools. One way or another, problems with the configuration of environment dependencies arise. As development continues, it becomes more and more challenging to find and fix bottlenecks.

I have described what is called vendor lock-in. This phenomenon becomes quite a challenge in the development of applications, in particular, server-type ones.

In this article, we will consider one of the possible solutions — Docker. You will learn how to create, deploy, and run an application based on this tool.

ÐаÑÑинки по запÑоÑÑ Docker

Disclaimer: This is not a review of Docker. This is the first entry point for developers who plan to deploy Node.JS applications using Docker containers.

While developing one of our projects, my team faced a lack of detailed articles on the topic, and this greatly complicated our work. This post was written to simplify the pathways of colleague developers who will follow our footsteps.

What is Docker?

Simply put, Docker is an abstraction over LXC containers. This means that processes launched using Docker will see only themselves and their descendants. Such processes are called Docker containers.

Images ( docker image ) are used for creating abstractions based on such containers. It is also possible to configure and create containers based on Docker images.

There are thousands of ready-made Docker images with pre-installed databases, web servers, and other important elements. Another advantage of Docker is that it is a very economical (in terms of memory consumption) tool since it uses only the resources it needs.

Let’s Get Closer

We will not dwell on the installation. Over the past few releases, the process has been simplified to a few clicks/commands.

In this article, we will analyze the deployment of a Docker application using the example of a server-side Node.js app. Here is its primitive, source code:

// index

const http = require('http');

const server = http.createServer(function(req, res) {

res.write('hello world from Docker');

res.end();

});

server.listen(3000, function() {

console.log('server in docker container is started on port : 3000');

});

We have at least two ways to package the application in a Docker container:

  • create and run a container using an existing image and the command-line-interface tool;
  • create your own image based on a ready sample.

The second method is used more often.

To get started, download the official node.js image:

docker pull node

The "docker pull" command downloads a Docker image. After that, you can use the "docker run" command. This way you will create and run the container based on the downloaded image.

docker run -it -d --rm -v "$ PWD": / app -w = / app -p 80: 3000 node node index.js


This command will launch the index.js file, map a 3000 port to an 80 port, and display the ID of the created container. Much better! But you will not go far with CLI only. Let's create a Dockerfile for a server.

FROM node

WORKDIR /app

RUN cp . /app

CMD ["node", "index.js"]


This Dockerfile describes the parent image of the current version, as well as the directory for starting container commands and the command for copying files from the directory where the image assembly is being launched. The last line indicates which command will run in the created container.

Next, we need to build an image that we will deploy based on this Dockerfile: docker build -t username / helloworld-with-docker: 0.1.0.   This command creates a new image, marks it with username helloworld-with-docker   and creates a 0.1.0 tag.

Our container is ready. We can run it with the docker run  command. The vendor lock-in problem is solved. The launch of the application is no longer dependent on the environment. The code is delivered along with the Docker image. These two criteria allow us to deploy the application to any place where we can run Docker.

Deploy

The first part is not as tricky as the remaining steps.

After we have completed all the instructions above, the deployment process itself becomes a matter of technics and your development environment. We will consider two options for deploying Docker:

  • Manual deployment of Docker image;
  • Deployment using Travis-CI.

In each case, we will consider delivering the image to an independent environment, for example, a staging server.

Manual Deployment

This option should be chosen if you do not have a continuous integration environment. First, you need to upload the Docker image to a place accessible to the staging server. In our case, it is a DockerHub. It provides each user with a free private image repository and an unlimited number of public repositories.

Log in to access the DockerHub:

docker login -e username@gmail.com -u username -p userpass


Upload the image:

docker push username/helloworld-with-docker:0.1.0


Next, go to the staging server (Docker must be already preinstalled on it). To deploy the application on the server, we need to execute only one command:  docker run -d --rm -p 80: 3000 username / helloworld-with-docker: 0.1.0 . And that’s all!

Check the local register of images. If you don’t find your image, enter username helloworld-with-docker  to check the DockerHub registry. An image with the name you indicate must be in the register since we have already uploaded it there. Docker will download it, create a container on its basis, and launch your application in it.

From this moment, every time you need to update the version of your application, you can make a push with a new tag and just restart the container on the server.

P.S. This method is not recommended if Travis-CI is available.

Deployment Using Travis-CI

First, we should add DockerHub data to Travis-CI. They will be stored in environment variables.

travis encrypt DOCKER_EMAIL=email@gmail.com

travis encrypt DOCKER_USER=username

travis encrypt DOCKER_PASS=password

Then we should add the received keys to the .travis.yml file. We should also add a comment to each key in order to distinguish between them in the future.

env:

  global:

    - secure: "UkF2CHX0lUZ...VI/LE=" # DOCKER_EMAIL

    - secure: "Z3fdBNPt5hR...VI/LE=" # DOCKER_USER

    - secure: "F4XbD6WybHC...VI/LE=" # DOCKER_PASS

Next, we need to login and upload the image:

after_success:

  - docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS

  - docker build -f Dockerfile -t username/hello-world-with-travis.

  - docker tag username/hello-world-with-travis 0.1.0

  - docker push username/hello-world-with-travis

Also, image delivery can be launched from Travis-CI in various ways:

  • manually;
  • via SSH connection;
  • online deploy services (Deploy Bot, deployhq);
  • AWS CLI;
  • Kubernetes;
  • Docker deployment tools.

Conclusion

We have considered two ways (automatic and via Travis-CI) of preparation and deployment of Docker using an example of a simple node.js server. The knowledge gained should greatly simplify your work. Thanks for your time!

Topics:
docker application ,deploy ,app dev ,node ,travis-ci ,cloud ,deployment ,automation

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}