Today we continue our “What and Why” series by taking a closer look at Docker.

picture

Andrii Kovalov, our Python Engineer and all-around problem solver, has experience in many areas including transportation, education, healthcare, and most recently government documents. Andrii will help explain how to debug applications inside of docker containers.
To jump right to the “how to”, see the last section.

Thank you for joining us, Andrii! So, what is Docker?

“Ok. So let’s start with a nonconventional explanation. Docker is software that allows you to create “mini virtual computers’’ for the application that you are developing. It’s virtualization software that allows you to create, manage, run, and deploy those applications almost anywhere. I think we need to discuss what virtualization is.”

You anticipated my next question! What is virtualization?

“Virtualization enables the hardware resources of a single computer to be divided into multiple virtual computers, called virtual machines (VMs). Docker uses “containers” as an abstraction at the app layer that packages code and dependencies together into those smaller virtual machines. Each container is basically a lightweight stand-alone executable package that contains everything that you need to run your application: packages, modules, and all the tools from the system layer that are required for your code or application to run.

So imagine a micro PC just right for your code or application. You might not need the whole robust computer, you just need this specific part. For example, you have a web server, and you need to get a request from a user, do something, and send a response back. Here is where you need a small virtual computer that does just those things and nothing else.”

When is Docker used?

“Let’s start with a meme.

picture

Modern projects are very complex and require a lot of modules, packages, libraries, etc. Setting them up locally for every developer can be a very complex and lengthy process. Having a project that is stable and works the same across all team members’ PCs is very beneficial because everyone is on the same page in terms of the project setup. And it can speed up the process of getting to know the project for the newcomers.

For example, as a backend developer, I know Python. At the same time, we have a front-end developer on the team. And they know how to set up NodeJS and front-end packages and npm packages and stuff like that. I don’t know that part of the application, so for me, it’s going to be a steep learning curve to set up it locally if I need to run the code. If we have a dockerized project, they can tell me: “Hey I have this front-end container service. Can you run it?” And I can run it with one command. I don’t care what is inside, I only get the results and I can see immediately how the front-end interacts with my own backend stuff.

For continuous integration and deployment (CI/CD) having a dockerized project is like having bricks – separate, atomic parts – that we can build and deploy. From the client standpoint, dockerized projects have the value of being atomic, shippable, and deployable. Those qualities reduce cost of development, maintenance, and deployment.

Docker should be used in the early stages of a project, usually even before building the project “skeleton”.”

What advantages does Docker have over alternatives?

“Historically, virtualization was very expensive in terms of system resources. Classic VMs require a lot of system resources and even then interactions with them are not always silky smooth. What makes Docker different is that virtualization includes only a thin “application” layer and re-uses the base computer’s resources for everything else. This approach makes it possible to create a lot of “containers” with few resources and overhead. Docker is “better” than other options mostly because it is a more popular tool and a lot of developers know it.

Alternatives to Docker include:

  • Podman – another “container engine” that doesn’t rely on the Linux “daemon” to work.
  • LXD – another open-source container engine that works only in Linux.
  • Containerd – a high-level container runtime that runs “runc” under the hood.

Since all of these are “contained”, debugging them is a bit tricky. That’s what I’m going to talk about today.”

What is debugging? How does it help? Why is it important?

Debugging is the process of finding and fixing errors or bugs in the source code of any software. It helps to get knowledge about software or a sub-system. As a developer, it is crucial to be able to interact with software that you are developing to be able to see execution flow, variables, etc. Usually, it is the first step in finding and fixing the problem.

Debugging is important because bugs are very expensive. Sometimes the bugs can have tremendous consequences. For example, a bug in the software of an airplane can cause a crash, and it can cost lives. In other cases, imagine a bug in banking software that can cause people to lose money or a market crash.”

How do you debug applications inside Docker containers?

“Many developers develop and debug applications in their local or cloud PCs and debugging in those environments is usually straightforward. But once an application gets containerized the question arises: “How do I interact with a computer inside my computer?” At first, it can seem difficult to get access to the same tools inside the virtual container. This is where Integrated Development Environments (IDEs) software can help us. Currently, I know of two approaches to debug in Docker containers:

  1. Using an IDE from JetBrains (Paid). In Python projects, we use PyCharm, which has support for setting up debugging configurations with Docker or docker-compose. The main drawback is its price. The dockerized debug feature is available only in PyCharm professional edition.

  2. Using the VSCode IDE (Free) and its “Remote” extensions that allow users to connect to various remote systems via ssh, wsl/wsl2, inside a docker container. The main advantage is that it is freeware. The main drawback is that setting it up is a more manual process and the learning curve is somewhat steep.

Can you describe the debugging process using VSCode for Docker?

“The official VS Code documentation is here. The documentation is a little tricky, so I created a demo repository to show how to debug a Python application in docker.

Try it out at github.com/dreamproit/docker-debug

Briefly, you:

  1. Install a number of extensions to VSCode for Docker debugging.
  2. Attach the IDE to the container.
  3. Create a “launch.json” file with debug configurations.
  4. Edit the “launch.json” file and add configurations to debug your code.
  5. Once the “launch.json” file is set up, you can run each configuration, place ‘breakpoints’ in key locations in the code to stop code execution, and investigate the results. From this point on, the debugging process becomes essentially equivalent to debugging locally, outside of a container.

Andrii, thank you for your time and for the comprehensive explanations!

We’ll be coming back with more “What and Why” posts!