As software craftsmen, one of the most common things we do on a daily basis is debug our code. When using docker, be it locally or on cloud, a lesser known, yet incredibly powerful tool available to us is
Quoting from the docker docs.
docker attachto attach your terminal’s standard input, output, and error (or any combination of the three) to a running container using the container’s ID or name. This allows you to view its ongoing output or to control it interactively, as though the commands were running directly in your terminal.
Most programming languages have debuggers that allow you to halt execution at specific points by defining break points in your program at which point you can inspect the current state of the program. From there you could either go step by step or continue execution until instructed to halt again at some other code path or the program exits. This is a very commonly used approach for debugging your application and allows the developer to be able to inspect the exact state of program at key points to determine if it’s behaving as intended or not.
Most debuggers also support a client-server architecture that allows IDEs (Integrated Development Environment) to be able to connect to the debugger server and allow us to use it’s features from within the IDE like defining break points, etc. For keeping this article short, I am not going to get into how to do that with docker. You can read up documentation for your IDE on how to do the same.
For ruby, as an example you can use either
pry to define break points in your code, by adding statement
binding.pry respectively and when your code execution reaches at that point, it will spawn a
pry repl for you to be able to inspect the state of your application.
Here’s a demo showing what that looks like :
For nodejs, we can make use of
node inspect to do a similar thing, here’s a demo on what that looks like :
A similar strategy can be applied to other programming languages with their debuggers and since we are using containers it makes it very easy to isolate all the dependencies and makes this fairly generic.
One annoyance with
docker attach is that if you use
detach from the container, it sends a
SIGKILL to the container by default and this may not be what you want. To get around this, you can use :
docker attach --detach-keys 'ctrl-c' <container id>
The above tells
docker attach to treat
ctrl-c as the key sequence to detach from the container, instead of sending a
SIGKILL to the container and hence keep it running in the background once you detach from it.
With Docker Compose
If you’re using
docker-compose to manage your development infrastructure, you need to add a couple of options to your application service in order to be able to attach to it, namely
Following is an example
docker-compose configuration with these options enabled for the
All the above code is available at https://github.com/dhruvasagar/docker-attach