Reader small image

You're reading from  Learn Docker - Fundamentals of Docker 19.x - Second Edition

Product typeBook
Published inMar 2020
PublisherPackt
ISBN-139781838827472
Edition2nd Edition
Tools
Right arrow
Author (1)
Dr. Gabriel N. Schenker
Dr. Gabriel N. Schenker
author image
Dr. Gabriel N. Schenker

Dr. Gabriel N. Schenker has more than 25 years of experience as an independent consultant, architect, leader, trainer, mentor, and developer. Currently, Gabriel works as Lead Solution Architect at Techgroup Switzerland. Prior to that, Gabriel worked as Lead Curriculum Developer at Docker and at Confluent. Gabriel has a Ph.D. in Physics, and he is a Docker Captain, a Certified Docker Associate, a Certified Kafka Developer and Operator, and an ASP Insider. When not working, Gabriel enjoys time with his wonderful wife Veronicah and his children.
Read more about Dr. Gabriel N. Schenker

Right arrow

Debugging Code Running in Containers

In the previous chapter, we learned how to work with stateful containers, that is, containers that consume and produce data. We also learned how to configure our containers at runtime and at image build time using environment variables and config files.

In this chapter, we're going to introduce techniques commonly used to allow a developer to evolve, modify, debug, and test their code while running in a container. With these techniques at hand, you will enjoy a frictionless development process for applications running in a container, similar to what you experience when developing applications that run natively.

Here is a list of the topics we're going to discuss:

  • Evolving and testing code running in a container
  • Auto restarting code upon changes
  • Line-by-line code debugging inside a container
  • Instrumenting your code to produce...

Technical requirements

In this chapter, if you want to follow along with the code, you need Docker for Desktop on macOS or Windows and a code editor—preferably Visual Studio Code. The sample will also work on a Linux machine with Docker and VS Code installed.

Evolving and testing code running in a container

When developing code that will eventually be running in a container, it is often the best approach to run the code in the container from the very beginning, to make sure there will be no unexpected surprises. But, we have to do this in the right way in order not to introduce any unnecessary friction into our development process. Let's first look at a naive way that we could run and test code in a container:

  1. Create a new project folder and navigate to it:
$ mkdir -p ~/fod/ch06 && cd ~/fod/ch06
  1. Let's use npm to create a new Node.js project:
$ npm init
  1. Accept all the defaults. Notice that a package.json file is created with the following content:
{
"name": "ch06",
"version": "1.0.0",
"description": "",
"main": "index.js...

Auto restarting code upon changes

Cool—in the last section, we showed how we can massively reduce friction by volume mapping the source code folder in the container, thus avoiding having to rebuild the container image and rerun the container over and over again.

Yet we still feel some remaining friction. The application running inside the container does not automatically restart when a code change happens. Thus, we have to manually stop and restart the container to pick up the new changes.

Auto-restarting for Node.js

If you have been coding for a while, you will certainly have heard about helpful tools that can run your applications and restart them automatically whenever they discover a change in the code base. For...

Line-by-line code debugging inside a container

Before we dive into this section about the line-by-line debugging of code running inside a container, let me make a disclaimer. What you will learn here should usually be your last resort, if nothing else works. Ideally, when following a test-driven approach when developing your application, the code is mostly guaranteed to work due to the fact that you have written unit and integration tests for it and run them against your code, which also runs in a container. Alternatively, if unit or integration tests don't provide you with enough insight and you really need to debug your code line by line, you can do so having your code running directly on your host, thus leveraging the support of development environments such as Visual Studio, Eclipse, or IntelliJ, to name just a few IDEs.

With all this preparation, you should rarely need...

Instrumenting your code to produce meaningful logging information

Once an application is running in production, it is impossible or strongly discouraged to interactively debug the application. Thus, we need to come up with other ways to find the root cause when the system is behaving unexpectedly or causing errors. The best way is to have the application generate detailed logging information that can then be used by the developers that need to track down any errors. Since logging is such a common task, all relevant programming languages or frameworks offer libraries that make the task of producing logging information inside an application straightforward. 

It is common to categorize the information output by an application as logs into so-called severity levels. Here is the list of those severity levels with a short description of each:

...

Security levels

Explanation

Using Jaeger to monitor and troubleshoot

When we want to monitor and troubleshoot transactions in a complex distributed system, we need something a bit more powerful than what we have just learned. Of course, we can and should continue to instrument our code with meaningful logging messages, yet we need something more on top of that. This more is the capability to trace a single request or transaction end to end, as it flows through the system consisting of many application services. Ideally, we would also want to capture other interesting metrics such as the time spent on each component versus the total time that the request took.

Luckily, we do not have to reinvent the wheel. There is battle-tested open source software out there that helps us to achieve exactly the aforementioned goals. One example of such an infrastructure component or software is Jaeger (https://www.jaegertracing...

Summary

In this chapter, we have learned how to debug Node.js, Python, Java, and .NET code running inside a container. We first started by mounting the source code from the host into the container to avoid a rebuild of the container image each time the code changes. Then, we smoothed out the development process further by enabling automatic application restart inside the container upon code changes. Next, we learned how to configure Visual Studio Code to enable the full interactive debugging of code running inside a container. Finally, we learned how we can instrument our applications such that they generate logging information that can help us to do root cause analysis on failures or misbehaving applications or application services running in production.

In the next chapter, we are going to show how using Docker containers can super-charge your automation, from running a...

Questions

Please try to answer the following questions to assess your learning progress:

  1. Name two methods that help to reduce the friction in the development process introduced by the use of containers.

  2. How can you achieve a live update of code inside a container?

  3. When and why would you use the line-by-line debugging of code running inside a container?

  4. Why is instrumenting code with good debugging information paramount?

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Learn Docker - Fundamentals of Docker 19.x - Second Edition
Published in: Mar 2020Publisher: PacktISBN-13: 9781838827472
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Dr. Gabriel N. Schenker

Dr. Gabriel N. Schenker has more than 25 years of experience as an independent consultant, architect, leader, trainer, mentor, and developer. Currently, Gabriel works as Lead Solution Architect at Techgroup Switzerland. Prior to that, Gabriel worked as Lead Curriculum Developer at Docker and at Confluent. Gabriel has a Ph.D. in Physics, and he is a Docker Captain, a Certified Docker Associate, a Certified Kafka Developer and Operator, and an ASP Insider. When not working, Gabriel enjoys time with his wonderful wife Veronicah and his children.
Read more about Dr. Gabriel N. Schenker