Code your way through – II

Application Runtime as Code – Part 2

We have come so far in getting the docker file and have gone through the different instructions used. In this dispatch we take this a step further.

Remember the keywords, Image and Container. We have come so far in defining what the image will contain. Now we create the image in the registry. Before we do that check if your installation of docker is all good. There is enough authoritative content on the installation from docker.com. To check the installation, you can do that with this –

 

docker –version

 

 

You should see something like – Docker version —–, build ——. The dashes are some version numbers.

We do that with command –

 

docker build .

 

 

The command above is initiated in the developer machine but the command is processed where the daemon process is running. Typically, in a developer environment this will be the same as the developer machine. However, in most production operated environment the daemon could run on a remote process in different machine. The docker CLI takes care of passing the required information and files to the daemon.

The first argument to the docker CLI is the command followed by the parameter for the command. In this case it is the context for the command. A dot points to the current directory from where the command is executed.

Command expects that a Dockerfile (by convention) is found in the context. In case the file with that name is not found it reports an error and stops.

You could use a general command structure which looks like this if you want to use a different name for the file –

 

docker build -f “/path to the/Dockerfile” .

 

 

Typically, you will use a command like this

 

docker build -t experiments/eShopOnWeb .

 

 

The -t command switch tells the command to tag the image with a text you provide. This is done so that you could retrieve a specific image that you built. We will pick this tag again in some lines down this article.

The CLI locally validates the syntax of the Dockerfile. Once it is satisfied the daemon kicks in and performs the operation with obediently to yield the image that we wanted. It might take sometime but once done it will offer some feedback like this on the console amongst many other things that it printed on the console –

 

Successfully built 87fe974ac589

 

 

Once you have that output, the daemon has taken the base image indicated using the FROM instruction in the Dockerfile. It has performed the instructions that you have given the daemon after that line. Thus, customising the image. This is where the power of code your way through in the title comes from. You have basically used the command to create a brand-new image which has all that is required for the application to perform.

You can check the newly created image using the command

 

docker images ls

 

 

Next, we create a container. Right from the terminology we explained in the earlier dispatch we have to instantiate the image to use it. We do that with following command –

 

docker run -p 8080:80 –name eShopOnWeb experiments/eShopOnWeb

 

 

We ask docker CLI to pass on a command to the daemon to run with some parameters. The important parameters if we block some of the command line switches here is the repetition of the tag experiments/eShopOnWeb. This is where the tag we gave earlier comes in handy. Had we not used d a tag we would have to use the UUID that docker would have assigned. Not that it is a problem, this approach becomes more useful in the context of automating as we know the name instead of adding command retrieve the UUID and some processing logic to use it in the next command.

The command line switch -p instructs the daemon to channel the io that it receives in the port 80 of the container to current machine’s (where the docker daemon is running) port 8080. Thus, what inside the container is http://localhost will become http://localhost:8080 from the machine where docker daemon is running or from the machine where the machine running the daemon is accessible in the same network.

Remember that container is also a piece of OS that has all the concept of port, disk and memory. So, we using the -p switch we tell the OS to do that channelling of IO that we explained.

The –name command line switch does what -t tag does to the image. This switch assigns a name to the container. The name comes in handy in starting, stopping, and other such operations.

The command emits output in the same console from where you are running the command. This might be desirous and, in some instance, this might not be the case. Typically, in the case where you want to use the console for subsequent operation in DevOps pipeline or when you want it to do something else after launching the container. For either of the scenarios you would have to pass the -d switch additionally to instruct docker to run in detached mode –

 

docker run -d -p 8080:80 –name eShopOnWeb experiments/eShopOnWeb

 

 

After this command you should be able to launch a browser and explore the fruit of you labour in the URL http://localhost:8080.

Let us take this step further with the docker compose. This is an additional tool other than docker. It is used to perform sequential docker operations one after another. Using this tool an application that needs multiple docker containers can be instantiated and operated. Had you not used the tool then you would have issued a docker build followed by docker run. This will have to repeat this for multiple containers that application needs. However, with docker compose it is a single command. Example of any such necessity is the front-end web interface is hosted out of one container and the web API is exposed via another container. Docker compose file uses convention-based approach for file name like docker and it has its own set of instruction. But now that you are familiar with the docker this should resonate quickly.

 

services:

 webapp:

   image: experiments/eShopOnWeb

   build:

     context: .

     dockerfile: src/Web/Dockerfile

 webapi:

   image: experiments/eShopOnWebApi

   build:

     context: .

     dockerfile: src/Api/Dockerfile

 

If you have noticed this is a split of docker build command over many lines. However, there are no specific commands related to run like the port mapping. You can add them as well to take a shape like this –

 

services:

 webapp:

   image: experiments/eShopOnWeb

   build:

     context: .

     dockerfile: src/Web/Dockerfile

   ports:

     – “8080:80”

 webapi:

   image: experiments/eShopOnWebApi

   build:

     context: .

     dockerfile: src/Api/Dockerfile

   ports:

     – “9090:80”

 

 

 

 

These commands help parameterise the build and run operation for container. With this file placed in the root folder of your solution you can get all that we accomplished so far and more with a single command –

 

docker compose up

 

 

That is all you are set. You can do this for another environment like test, UAT, and prod etc. Now, if this has excited you with possibilities that are there for you to code your way through, you can follow up with Kubernetes from the house of Google. It takes all these concepts to a level up with orchestration and opens doors for the concept of application infrastructure choreography.