Webinar Series: Building Containerized Applications

Webinar Series

This article supplements a series that is webinar deploying and handling containerized workloads within the cloud. The show covers the requirements of containers, including container lifecycle administration, deploying multi-container applications, scaling workloads, and understanding Kubernetes, and highlighting recommendations for operating stateful applications.

This guide includes the ideas and commands covered within the session that is second the show, Building Containerized Applications.

Introduction

In the tutorial that is last How to Install and Configure Docker, we explored one method for converting Docker containers into Docker images. Although the method we used worked, it is not always the way that is optimal of pictures.

In numerous situations, you need to bring current rule into container pictures, and you should wish a repeatable, constant device for producing Docker pictures which can be in sync with all the latest form of your codebase.

A Dockerfile addresses these demands by giving a declarative and way that is consistent of Docker pictures.

Additionally, you will often wish to containerize applications that are entire are consists of numerous, heterogeneous containers which can be implemented and handled together.

Docker Compose, like a Dockerfile, takes a approach that is declarative give you a technique for determining a whole technology stack, including system and storage space demands. This not just causes it to be more straightforward to build containerized applications, but inaddition it causes it to be more straightforward to handle and measure them.

In this guide, you will definitely utilize an example internet application predicated on Node.js and MongoDB to create a Docker image from a Dockerfile, you will definitely produce a customized system that enables your Docker containers to communicate, and you may utilize Docker Compose to introduce and measure a application that is containerized.

Prerequisites

To follow this guide, you’ll need:

Step 1 — Building a picture with a Dockerfile

Start by changing to your house directory, then utilize Git to clone this guide’s test internet application from the repository that is official onHub.

  • cd ~
  • git clone https://github.com/janakiramm/todo-app.git

This will duplicate the test application into a fresh directory known as todo-app.

Switch to todo-app and make use of ls to see the directory’s articles.

The brand new directory contains two subdirectories and two files:

  • app - the directory where in actuality the test application's supply rule is saved
  • compose - the directory where in actuality the Docker Compose setup file is saved
  • Dockerfile - a file which has guidelines for building the Docker image
  • README.md - a file which has a one-sentence summary associated with the test application

Running cat Dockerfile shows united states the ( that is following********)

~/todo-app/Dockerfile

FROM node:slim
LABEL maintainer = "[email protected]"
RUN mkdir/usr/src/app that is-p
WORKDIR /usr/src/app
CONTENT ./app/ ./
RUN npm install
CMD ["node", "app.js"]

Let's have a look at this file's articles much more information:

  • FROM suggests the bottom image where you're building the customized image. The image is based on node:slim, a public Node.js in this example image that contains only the packages that are minimal to operate node.
  • LABEL is an integral value set typically accustomed include information that is descriptive. In this full instance, it has the e-mail target associated with the maintainer.
  • RUN executes commands in the container. Including tasks like producing directories and initializing the container by operating fundamental Linux commands. The very first RUN demand inside file is employed to generate the directory /usr/src/app that holds the foundation rule.
  • WORKDIR describes the directory in which the commands are performed. It's often the directory where in actuality the rule is copied.
  • COPY copies the files from host device in to the container image. In this instance, you're copying the whole app directory in to the image.
  • The 2nd RUN demand executes npm install to set up the applying's dependencies as defined in package.json.
  • CMD operates the method which will keep consitently the container operating. Inside instance, you will definitely execute node with all the parameter app.js.

Now it is time for you build the image from Dockerfile. Utilize the -t change to tag the image with all the registry username, image title, and an tag that is optional.

  • docker build -t sammy/todo-web .

The production confirms your image is Successfully built and tagged accordingly.

Output from docker build -t

Sending develop context to Docker daemon 8.238MB Action 1/7 : FROM node:slim ---> 286b1e0e7d3f Action 2/7 : LABEL maintainer = "[email protected]" ---> making use of cache ---> ab0e049cf6f8 Action 3/7 : RUN mkdir/usr/src/app that is-p ---> making use of cache ---> 897176832f4d Action 4/7 : WORKDIR /usr/src/app ---> making use of cache ---> 3670f0147bed Action 5/7 : COPY ./app/ ./ ---> making use of cache ---> e28c7c1be1a0 Action 6/7 : RUN npm install ---> making use of cache ---> 7ce5b1d0aa65 Action 7/7 : CMD node app.js ---> making use of cache ---> 2cef2238de24 Successfully built 2cef2238de24 Successfully tagged sammy/todo-web:latest

We can validate your image is done by operating the docker pictures demand.

right here, we could start to see the size associated with the image combined with the time elapsed as it was made.

Output from docker pictures

REPOSITORY TAG IMAGE ID CREATED SIZE sammy/todo-web latest 81f5f605d1ca 9 mins ago 236MB

Since we likewise require a MongoDB container to operate the test internet application, let’s have that to the device.

The production reports precisely which image had been drawn combined with the down load status.

Output from docker pull

latest: Pulling from library/mongo Digest: sha256:18b239b996e0d10f4ce2b0f64db6f410c17ad337e2cecb6210a3dcf2f732ed82 Reputation: Downloaded more recent image for mongo:latest

We are in possession of every thing we have to run the test application, therefore let us produce a customized system which will enable our containers to keep in touch with both.

(they would not be able to find each other*******)If we were to launch the web application and database containers independently through the docker run command.

To understand why, see the articles associated with the internet application's database setup file.

After importing Mongoose — a MongoDB object-modeling collection for Node.js — and determining a database that is new, the internet application attempts to hook up to the database within hostname, db, which does not occur yet.

~/todo-app/app/db.js

var mongoose = require( 'mongoose' );
var Schema   =.Schema that is mongoose

var Todo = brand new Schema({
    user_id    : String,
    content    : String,
    updated_at : Date
});

mongoose.model( 'Todo', Todo );

mongoose.connect( 'mongodb://db/express-todo' );

To make sure that containers from the exact same application discover both, we have to introduce them regarding the network that is same.

Docker offers the capability to produce networks that are custom addition towards standard companies created during installation.

You can always check your now available companies with all the command that is following********)

Each system developed by Docker is dependant on a motorist. Into the output that is following we come across your system known as bridge is dependant on the motorist bridge. The local range suggests your system can be acquired just with this host.

Output from docker system ls

NETWORK ID NAME DRIVER SCOPE 5029df19d0cf bridge bridge local 367330960d5c host host neighborhood f280c1593b89 none null neighborhood

We will now produce a customized system known as todo_net for the application after which we'll introduce containers on that system.

  • docker system make todo_net

The production informs united states the hash associated with the system which was developed.

Output from docker system create

C09f199809ccb9928dd9a93408612bb99ae08bb5a65833fefd6db2181bfe17ac

Now, list the networks that are available.

right here, we come across that todo_net is prepared to be used.

Output from docker system ls

NETWORK ID NAME DRIVER SCOPE c51377a045ff connection connection neighborhood 2e4106b07544 host host neighborhood 7a8b4801a712 none null neighborhood bc992f0b2be6 todo_net bridge local

while using the docker run demand, we could now relate to this system with all the --network switch. Let’s launch the database and web containers with certain hostnames. This may make sure that the containers can hook up to both through those hostnames.

First, introduce the MongoDB database container.

  • docker run -d
  • --name=db
  • --hostname=db
  • --network=todo_net
  • mongo

Taking a better check that demand, we come across:

  • The -d switch operates the container in detached mode.
  • The --name and --hostname switches assign a person defined title towards container. The --hostname switch additionally adds an entry towards DNS solution handled by Docker. This can help in resolving the container by host title.
  • The --network switch instructs Docker motor to introduce the container on a customized system as opposed to the standard connection system.

once we see a string that is long production from docker run demand, we could assume your container is effectively launched. But, this could perhaps not guarantee your container is obviously operating.

Output docker run

aa56250f2421c5112cf8e383b68faefea91cd4b6da846cbc56cf3a0f04ff4295

Verify your db container is ready to go with all the docker logs demand.

This images the container logs to stdout. The line that is last of log suggests that MongoDB is prepared and waiting for connections.

Output from docker logs

2017-12-10T02:55:08.284+0000 We CONTROL [initandlisten] MongoDB beginning : pid=1 port=27017 dbpath=/data/db 64-bit host=db . . . . 2017-12-10T02:55:08.366+0000 We NETWORK [initandlisten] waiting for connections on slot 27017

Now, let’s launch the internet container and validate it. Now, we are additionally including --publish=3000:3000 which posts the host's port 3000 towards container's slot 3000.

  • docker run -d
  • --name=web
  • --publish=3000:3000
  • --hostname=web
  • --network=todo_net
  • sammy/todo-web

You'll get a string that is long production like before.

Letis also verify that container is ready to go.

The production verifies that Express — the Node.js framework our test application is dependant on — is listening on slot 3000.

Output from docker logs

Express host paying attention on slot 3000

Verify your internet container can speak with the container that is db a ping demand. We repeat this by operating the docker exec demand in an interactive (-i) mode mounted on a pseudo-TTY (-t).

  • docker exec -it internet db that is ping

The demand creates standard ping production and allows us to realize that the 2 containers can keep in touch with both.

Output from docker exec web that is-it db

PING db (172.18.0.2): 56 information bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.210 ms 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.095 ms ...

Press CTRL+C to avoid the ping demand.

Finally, access the test application by pointing your online web browser to http://your_server_ip:3000. You shall see a web web page with a label that checks out Containers Todo Example and a textbox that takes a todo task as input.

To avoid naming disputes, it's simple to stop the containers and clean the resources up with all the docker rm and docker system remove commands.

  • docker rm db that is-f
  • docker rm web that is-f
  • docker system eliminate todo_net

At this time, we've a web that is containerized made up of two separate containers. In the next step, we will explore a more approach that is robust.

Step 3 — Deploying a Multi-Container Application

(it’s not the most elegant way of dealing with multi-container applications*******)Although we were able to launch linked containers. We need a better way to declare all of the related containers and manage them as one unit that is logical.

Docker Compose is a framework open to designers to cope with multi-container applications. Like Dockefile, it's a declarative device to determine the stack that is entire. We shall now transform our Node.js and MongoDB application into a Docker application that is compose-based.

Start by setting up Docker Compose.

  • sudo apt-get install docker-compose that is-y

Let’s examine the docker-compose.yaml file found in the test internet application's compose directory.

  • cat compose/docker-compose.yaml

The docker-compose.yaml file brings every thing together. It describes the the MongoDB container within the db: block, the Node.js internet container within the web: block, additionally the customized system within the networks: block.

Note that with all the build: ../. directive, our company is pointing Compose towards Dockerfile within the app directory. This may instruct write to create the image before starting the internet container.

~/todo-app/compose/docker-compose.yaml

version: '2'
solutions:
  db:
    image: mongo:latest
    container_name: db
    companies:
      - todonet
  internet:
    build: ../.
    companies:
      - todonet
    ports:
     - "3000"
companies:
  todonet:
    motorist: connection

Now, modification towards compose directory and introduce the applying with all the docker-compose up demand. The-d switch starts the container in detached mode.( as with docker run********)

  • cd compose
  • docker-compose up -d

The production reports that Docker Compose created a community called compose_todonet and established both containers about it.

Output from docker-compose up -d

Creating system "compose_todonet" with motorist "bridge" Producing db Producing compose_web_1

Notice we didn’t give you the explicit host mapping that is port. This will force Docker Compose to assign a port that is random expose the internet application regarding the host. We are able to discover that slot by operating the command that is following********)

We observe that the internet application is exposed on host slot 32782.

Output from docker ps

CONTAINER ID IMAGE COMMAND CREATED REPUTATION PORTS NAMES 6700761c0a1e compose_web "node app.js" 2 mins ago Up 2 mins 0.0.0.0:32782->3000/tcp compose_web_1 ad7656ef5db7 mongo:latest "docker-entrypoint..." 2 mins ago Up 2 mins 27017/tcp db

Verify this by navigating your online web browser to http://your_server_ip:32782. This may bring the web application up in the same way you saw it by the end of action 2.

With our application that is multi-container up running right through Docker Compose, let us have a look at handling and scaling our application.

Step 4 — controlling and Scaling the application form

Docker Compose allows you to measure web that is stateless. We are able to introduce 10 cases of our web container with an individual demand.

  • docker-compose scale web=10

The production allows us to view the circumstances being developed and were only available in realtime.

Output from docker-compose scale

Creating and compose_web_2 that is starting done Making and compose_web_3 that are starting done Making and compose_web_4 that are starting done Making and beginning compose_web_5 ... done Making and compose_web_6 that are starting done Making and compose_web_7 that are starting done Making and compose_web_8 that are starting done Making and beginning compose_web_9 ... done Making and starting**********************************************************************************************************************************************************) that is compose_web_( done

Verify your internet application is scaled to 10 circumstances by operating docker ps.

Notice that Docker has assigned a port that is random expose each web container regarding the host. These ports could be used to access the applying.

Output from docker ps

CONTAINER ID IMAGE COMMAND CREATED REPUTATION PORTS NAMES Cec405db568d compose_web "node app.js" About a full minute ago Up About a moment 0.0.0.0:32788->3000/tcp compose_web_9 56adb12640bb compose_web "node app.js" About a moment ago Up About a moment 0.0.0.0:32791->3000/tcp compose_web_10 4a1005d1356a compose_web "node app.js" About a full minute ago Up About a moment 0.0.0.0:32790->3000/tcp compose_web_7 869077de9cb1 compose_web "node app.js" About a moment ago Up About a moment 0.0.0.0:32785->3000/tcp compose_web_8 Eef86c56d16f compose_web "node app.js" About a full minute ago Up About a moment 0.0.0.0:32783->3000/tcp compose_web_4 26dbce7f6dab compose_web "node app.js" About a moment ago Up About a moment 0.0.0.0:32786->3000/tcp compose_web_5 0b3abd8eee84 compose_web "node app.js" About a full minute ago Up About a moment 0.0.0.0:32784->3000/tcp compose_web_3 8f867f60d11d compose_web "node app.js" About a full minute ago Up About a moment 0.0.0.0:32789->3000/tcp compose_web_6 36b817c6110b compose_web "node app.js" About a moment ago Up About a moment 0.0.0.0:32787->3000/tcp compose_web_2 6700761c0a1e compose_web "node app.js" 7 mins ago Up 7 mins 0.0.0.0:32782->3000/tcp compose_web_1 ad7656ef5db7 mongo:latest "docker-entrypoint..." 7 mins ago Up 7 mins 27017/tcp db

You also can scale-in the internet container with all the command that is same.

  • docker-compose scale web=2

This time, we come across the instances that are extra eliminated instantly.

Output from docker-compose

Stopping and compose_web_3 that are removing done Stopping and compose_web_4 that are removing done Stopping and getting rid of compose_web_5 ... done Stopping and compose_web_6 that are removing done Stopping and compose_web_7 that are removing done Stopping and compose_web_8 that are removing done Stopping and getting rid of compose_web_9 ... done Stopping and removing**********************************************************************************************************************************************************) that is compose_web_( done

Finally, re-check the circumstances.

The production confirms that we now have just two circumstances left.

Output from docker ps

CONTAINER ID IMAGE COMMAND CREATED REPUTATION PORTS NAMES 36b817c6110b compose_web "node app.js" three full minutes ago Up three full minutes 0.0.0.0:32787->3000/tcp compose_web_2 6700761c0a1e compose_web "node app.js" 9 mins ago Up 9 mins 0.0.0.0:32782->3000/tcp compose_web_1 ad7656ef5db7 mongo:latest "docker-entrypoint..." 9 mins ago Up 9 mins 27017/tcp db

You are now able to stop the applying, and, exactly like prior to, you can clean the resources up in order to avoid naming disputes.

  • docker-compose end
  • docker-compose rm -f
  • docker system eliminate compose_todonet

Conclusion

This guide introduced one to Dockerfiles and Docker Compose. We began with a Dockerfile while the declarative device to then build images we explored the basics of Docker networking. Finally, we scaled and managed applications that are multi-container Docker Compose.

To expand your setup, you could add an reverse that is nginx running inside another container to route requests to one of the available web application containers. Or, you can take advantage of DigitalOcean's Block Storage and Load Balancers to bring durability and scalability to the applications that are containerized.

LEAVE A REPLY

Please enter your comment!
Please enter your name here