πLab4 - Docker
I cannot be contained because I am the container! --Jim Carrey
Last updated
I cannot be contained because I am the container! --Jim Carrey
Last updated
In the previous Lab, you learned how to install Docker and also you have started working with Linux Comand Line within Docker which I believe feels awesome to have such flexibility and freedom!
In software engineering, containerization is operating system-level virtualization or application-level virtualization over multiple network resources so that software applications can run in isolated user spaces called containers in any cloud or non-cloud environment, regardless of type or vendor. Wikipedia
Let's start by adding a dockerfile to the main directory of your project. But what needs to be added to this file?!
As you have seen in the lecture this file contains several parts that need to be defined carefully (otherwise it wonβt work!). Instead of jumping into a super-advanced fancy dockerfile, we adopt an incremental approach and add more fancy items as needed!
First, we need to pull the official base image. Since we use the node module, we need to make sure the base image contains a node and make sure the node version in our local machine is identical to the node version on the image.
The node version in my machine is 18.14.2.
To find out what base image is compatible with this version login to your account: https://hub.docker.com/
Then search for βnodeβ and inside the sort by box type the version of your node module plus the name of the (minimal) OS, in this case, it is going to be: 18.14-apline
What we need from this page is the complete name (tag name) of this image to refer to it in our dockerfile: 18.14-alpine3.17
Okay add this line to the dockerfile and then run the following command in the command prompt:
If everything goes well you should be able to see this image in our docker desktop app:
As you have seen in t the lecture you can interact with this image using the shell:
It is a good time to brush up your memory about linux file system! You can also verify the version of the node running on this machine.
Now that we have the base image, the next step is to copy the application files into the image. Before that letβs define the working directory, i.e., app.
If you have noticed this process takes a lot of time! Essentially because it copies all the files in node_modules
directory into the image! We should do something about it!
If the process is still ongoing, just stop it (ctrl + c) we donβt want a large image!
Letβs add the .dockerignore file beside our dockerfile and add node_modules to it.
It is better now! Everything is done in less than 3 seconds!
Verify the results again by running the image:
Next, we install the dependencies on the image every time it is started and expose the port we would like to use to communicate with the image.
It is easy! The only thing we need to add to the dockerfile is:
If you do that you will run into an error like this:
To understand what is going wrong on your image when you run npm install you should comment out these two lines and rebuild your image and then go to that and manually run the command:
You will need more options here!
Letβs go back to the dockerfile and fix the issue. If you open the README file you will get the additional arguments that need to be added.
Yes! It takes more time now. We will get back to this issue later!
We can verify that the node_modules directory is generated in the image:
Since we would like to start the app once the container starts running, we need to add this command to the dockerfile: CMD [βnpmβ, βrunβ, βstartβ]
From the lectures, we have seen that the container is listening to port 8000 and it needs to be mapped to any port in the host, so we can get access to the ports on the container from the host. For that, we need to run the following script:
But when you try to see the portfolio from the host you will see the page like this:
That means it is not accessible from the host (YET)
To debug the issue first we need to make sure the port on the container is listening. For that, we need to install the nload
package on the container and then run nload -m
that to show us the incoming and outgoing data from our network. (Try this and see the result, also check out this link and this link for more information)
According to this link (and many other resources!), it seems since we use Gatsby in this project we need to some adjustments in the docker file to be able to see the result:
We should use yarn instead of npm
We need to explicitly mention the IP address of the host (i.e., 0.0.0.0)
Apply the modification in the dockerfile and then run:
Finally, run the container with port mapping and check the result in your browser:
Everything works fine!
First go to this address: https://portal.azure.com/#home
Then use the plus sign to create a resource and search for Azure Container Registry
Pick a name for the registry name, in this case, I use the registry name: teamportfolio
Use the default values for the rest and create the container registry.
Then click on βgo to resourceβ and then use βAccess Keysβ to log in to the registry:
To log into the registry, you can use the script below:
Then get the list of all images and create an alias for the image with the proper name as below:
To deploy our app, we need to create a Web App using the production dockerfile.
First go to this address: https://portal.azure.com/#home
Then use the plus sign to create a resource and search for: Web App
Use the option βWeb App for Containersβ and create one.
So far everything has worked smoothly but now just in the very last step, it seems the web app we just created wonβt work! Now it is your turn to put what you have learned as a software engineer into practice and try to fix the issue.
If you log into your portal, you can check the log files:
Please explain your solution and how did you find it in the learning journal!
Here are some hits that might come in handy as you try to debug the issue:
Check the portfolio-app
on your local machine and make sure it works OK. If it doesn't work maybe it is a good point to start!
Check dockerfile and make sure its configuration is to be used in the web application.
Check the platform we are using, in this case, Gatsby, do we need to do special treatment to support this platform in the web app.
Check our web app configuration again, did we miss anything?!