All right.
So in this lecture I want to show you how we can actually connect a debugger to our running microservices
in Docker so that when we send a request to our microservices, we can actually debug it and see our
defined variables and our control flow as the request actually enters our Http server.
This can be super useful when debugging and trying to find out what our code is actually doing.
And it's going to be super easy to debug with Nestjs.
So let's get started by firstly going into our package.json where we need to update our scripts.
So right now you can see we actually already have a command to start in debug mode.
So this is start debug.
And this is just going to use the nest CLI to start the app.
Still with the watch flag.
So we can make changes but also with this debug flag.
So the debug flag allows us to actually enter debug mode.
And specify an address where we want to listen for debug requests.
So in our case I want to go ahead and specify this address.
So the IP is going to be 0000.
So that we attach to all network interfaces running.
Well in our case we know our app is running inside of a Docker container.
So we want to listen on all IP addresses in that container.
And we want to specifically then listen on port 9229 which is going to be the debugging port we're going
to use.
So now we've specified the debug command.
We now need to go into our Docker compose.
And now we need to actually change the command that our services are using to actually start up the
application.
As of right now we're simply running the start dev command, which we know just starts up the dev server.
However, we want to start it up in this debug mode.
So we simply are going to change start dev to start debug.
And that's all we'll have to do to actually start up.
Then we'll also want to add our new port of 9229, so that it's actually exposed for traffic on our
Docker container and importantly, is mapped to our local machine's port of 9229.
So the Docker container is going to map this port that's running in the container to our local machine,
so that we can send requests to localhost 9229 and have them forwarded into the actual container, which
we know is listening for requests to debug.
So our final step is to actually create what's called a launch configuration.
So in VS code I'm going to create a launch dot Json file by first clicking on Run and Debug.
And then you can see here we have a created launch Json file.
Then we'll select the suggested runtime in our case NodeJS.
So it creates a default launch Json for us.
So this is going to create a new VS code folder and include this launch Json inside of it.
So let's go ahead and start updating this.
This is essentially going to be the configuration that VS code is going to use when we enter debug mode.
So we need to update this actual configuration to specify our specific application information.
So we can leave the default type.
Here we're going to change request to actually attach to an already running application.
Then for the name I'll give it a name of debug NodeJS Docker.
Then let's go ahead and get rid of these two extra properties.
And next we'll add the actual address that we want to debug on.
In our case we know it's just going to be localhost.
And then importantly the port needs to be 9229.
Since this is the port that we're actually mapping to our running container.
So that's going to get forwarded into the container.
We'll also include source maps to true.
So we have source maps.
We'll set restart to true as well.
And then we need to specify the local route which is going to be quote dollar sign bracket workspace
folder bracket.
So this is a special variable we can use in our Launch.json to actually specify the current workspace
folder for the project, which is at the default is just going to be the root of our VS code project.
Now the final property we need that works with local root is the remote route.
So this is the path locally on our file system where our code lives.
In our case it's just at this route where the launch.json actually lives.
So that's easy enough to specify.
However, on the remote route, we need to map this workspace folder to where it lives on the host machine.
So in our case, we know that by looking at one of our Docker files for the application we're debugging.
Remember where we're actually hosting our app on the file system is in this user source app directory.
So this is where the app is actually going to get placed.
And that's exactly where we need to tell remote route where the app lives.
So its user source app so that we can map the code on our local machine to the running container.
Now before we run in debug, we of course need to make sure that our containers are up and running.
So go ahead and run docker compose up to start everything up.
All right, so once all of our services have started up we'll then go back to VS code and click on Run
and Debug.
And now you can see we actually have our debug configuration defined in this top bar.
So you can add many more configurations easily by clicking add here if you want to add more for different
runtimes.
Let's choose the custom one we've created, and then go ahead and click on the play button.
So this is going to attach our debugger to localhost 9229, which is going to be mapped to the Docker
container that's actually running and can accept debug requests since we told Nestjs about it.
So now if we go back to our application logs, we can actually see that our logs for our reservation
service, the debugger was attached.
So we actually have attached to the service correctly.
Now I'm going to go back to our reservation service and let's open up the reservations controller.
And I'll simply place a breakpoint by clicking on this red dot here on the create route to create a
new reservation.
Now in postman, I'll go ahead and send a request to our reservation service, and immediately you can
see VSCode has opened back up and our code is actually stopped now on this breakpoint.
So we can actually control the execution of the request.
And importantly, we can actually see here this variable section.
So we can see what each variable is actually defined as as it's coming into our system.
So we can see our create reservation DTO with all of our DTO information on it, as well as our user
for this particular request on our decoded token.
So this is super helpful.
We can then follow the request down into the reservation service by adding another breakpoint and then
clicking on the continue button.
So now you can actually see how the code is running.
And I'll set one more breakpoint inside of our map here in our pipe, where we actually get the response
back from the payment service.
So after we send the request back, we'll see that map gets executed with the response.
So I'll click on continue one more time.
And now you can see we are in the map lock, with the response coming back from the payment service
so we can actually see the entire payments object.
We're getting back from the stripe API which is excellent.
So this is super helpful when trying to debug issues with our app or in general, just try to see the
state of an application for a given request at any time.