If you are a beginner and trying to figure out “What’s docker” then, believe me, you are in the right place. I’m going to start with a little background about docker, the problems it tries to solve and then come to the main topic.
I’m sure you would have heard the word ‘Docker’ in one or the other way (if you haven’t believed me you are in the wrong field). There is a buzz about Docker, Containerization, Kubernets etc. recently, so what is it?
“Docker is a containerization technology that helps you ship your product/software along with its related dependencies”
Hard to understand? I’m here to elaborate on it further. But before we go deep dive into it, let’s talk about what we have been doing earlier when docker wasn’t here. So say, if you want to ship your product on a server (be it Dev, Staging, UAT or Live) what we have been doing is ship binaries associated with software to the relevant person in OPS team. Then the person from the OPS team carries out a deployment. Later when the tester carries out testing he finds fugs or problems with the release. The developer argues that “The same is working on my computer, how the hell does it work on Server?”. And then this goes to “I did wrong” and “You did wrong” blame games. But here the problem is not with a person, rather its more related to the process involved for deployment.
Recently (not very recently it’s been here for one year from the point when I’m writing a blog), the process changed. We came across CI/CD tools for different technologies which kind of help automate the process at some point but still, there is one specific problem which is, the underlying dependencies for the software was not coupled with your deployment package. Think of this, when you deploy an ASP.NET application that is targeted to v3.5, the developer expects that it is installed on a server. But the details are not known to the OPS team. So, you create a Virtual Machine, add all your dependencies into that and then ship your product. But the challenge is, a Virtual Machine is of large size which is not that easy to transfer from one machine to another. Also, the Virtual Machine is carrying a lot of overhead which we don’t want. We simply want our product and dependencies to be ships in one package so that our product will work everywhere (so that I can make a person from the test team my friend .)
And that’s the problem that docker solves. “Docker allows users to package an application with all of its dependencies into a standardized unit for software development”.
The below image depicts Docker architecture.
Let’s go through each component one by one:
- Images – As it implies in general terms, image is a stamp of something. In the context of docker, it’s a stamp of your software package plus dependencies. Different vendor publishes their images (we’ll see where, for now, assume they publish somewhere) based on a framework such as ‘Microsoft/dotnet’ is an official image for .NET code and ASP.NET code application. Similarly, ‘Microsoft/dotnet-framework’ is an official image for .NET Framework-based application. So here two types of images exist:
- Root Images: Theses are ready maid images published by different providers such as Microsoft or Node.
- User/Developer Images: When you develop your application and want to ship your product/software as a docker image, you use those root image (based on your need), add your software package and other dependencies into that and then build your own image.
- Container – Container is the component in docker architecture who’s responsible for hosting your image and running your application.
- DAEMON – Docker daemon is responsible for making your container run. It’s also responsible for the deployment of your image into a container. Ideally, in case of VM, you yourself do RDP into VM guest OS. But since a Docker image doesn’t contain anything related to guest OS, we need something that does operations on the user’s behalf. So, think of a Daemon is a background running service that takes command from a user and executes at appropriate places.
- Docker CLI or Remote API – We discussed that a Daemon accepts the command and then performs some operation at an appropriate place but we didn’t mention where to write these commands. So, Docker CLI is the one where you execute those commands. Remote API is HTTP API that allows you to execute different commands for automation. You can get the reference of APIs from here – https://docs.docker.com/engine/api/v1.24/#1-brief-introduction
- Registry – Let’s assume that you prepared your image and then you want to deploy this to some server. How do you share this with your ops team or how do you take it to your new server? You can, of course, copy your image and paste there but what if you have a central place where all images are saved? When you need any, just execute one simple command and you’ll have an image on that machine. Cool right? And no hassle of copying and pasting. That’s where the registry comes into the picture. Once you think that your image is ready to ship, you register your image into registry and then push it into the registry to save there. When you need it, you just pull it. Docker Hub is such a registry provider and Azure Container Registry is another such provider.
- I covered a lot about Docker internal, now it’s time to explore docker by hosting a simple static HTML page (I’m going to host that on IIS).If you haven’t installed Docker, go through this guideline and do that first. https://docs.docker.com/toolbox/toolbox_install_windows/
- Let the fun begin.
- Create a directory, name if “PlainHtml”
- Inside this directory, Create a simple HTML page, name it ‘index.html’. Add H1 tag with “Hello World to Docker”.
- Create a directory named “Dockerfile” and then navigate into that.
- Create a file named ‘Dockerfile’ (remember with no extension).
- Open Dockerfile in your favorite text editor and add following code inside that-
Let’s understand each line one by one –
1. FROM…….: It says, to use this root image ‘Microsoft/iis’ as my root image. You can also specify the version of image (remember not iis) followed by ‘:’ like microsoft/iis:version
2. RUN ….. : is a CLI command that will be executed. Here is says run Powershell with no profile set and remove all items those are under wwwroot directory.
3. WORKDIR ….. is to set the current working directory
4. COPY is to copy files/directories from local machine into your image. The first argument is the path to local machine and second is to target image (rather inside an image).
5. Start command prompt and navigate to root directory where you created html file.
6. Then run command ‘docker build -t staticpage:1.0 Dockerfile’.
a. Here, ‘build’ command is used to build your image.
b. ‘-t’ is option to set image name which in this case “static page” and version “1.0”.
c. Dockerfile is config file that says Daemon to how to build the image.
You can see in below image, it says … sending context to docker daemon….Then daemon starts downloading image (BTW it’s huge, don’t try on mobile internet ).
Full list of build command can be seen here https://docs.docker.com/engine/reference/commandline/image_build/
docker run -d -p 8000:8000 –name static page-website static page
- ‘run’ is a command that runs your docker image in a container.
- ‘-d’ is very important option that detaches your process from command prompt. “What does this mean?” say if you don’t specify ‘-d’ and then you press Ctrl + C or you close command prompt then docker daemon will stop running your website as well.
- ‘-p’ is published port which says 8000 (left to ‘:’) is my machine port and 8000 (right to ‘:’) is port inside my container. It’s kind of port forwarding between my local machine and container port.
- ‘–name’ is name of my container. I named it “static page-website”
- ‘static page’ is image name that I want to run in this container.
That’s it. You have your simple HTML page up and running!
Few commands that may help you troubleshoot in case –
- docker container ls -a: This lists all containers. It doesn’t matter their status.
- docker container rm <name>: This removes the container from the list. This is helpful if you want to use the same container again and again.
- docker container stop <name>: Stops a container from running
- docker container inspect <name>: Lists container information in a JSON format.
- docker container exec -it <name> <command>: Runs a command in running container in interactive mode. For ex. ‘docker container exec it static page-website cmd’ will run the command prompt in interactive mode. Any cmd command you write thereafter would be executed with-in the docker context.
Frequently asked questions by a beginner:
1. What benefits does docker brings?
a)Smooth deployment process
b)It can be deployed anywhere without worrying about dependencies
c)Flexibility and lightweight of Container
d)They are scalable (depends on application architecture).
2. Can I use this for only Web apps?
No, Docker is a deployment tool and has nothing to do with technology stack. You can use it for anything such as running an application such as desktop or web app.
3. How does my development experience change?
A little if you are trying to run your application through docker during the development. The recommendation is, develop your application the way you have been doing. Use Docker to just create and deploy application. Don’t use it during development process.
4. If Docker has no effect on my development process, what it changes then?
What changes is how you architect your application. Deploying your monolithic application using docker is possible but it doesn’t bring many advantages. Don’t try to fit technology into your business requirements. Let business requirements speak out that they need docker (i.e. Highly scalable, independent and portable deployments).