Can I do better: Connecting to Docker Containers 2
I want to share my debugging process when I run into a problem with code that stops working.
The specific situation is when a solution I made to connect to docker containers without typing out the container SHA identifier suddenly stopped working.
I walk through specific steps I took to debug the issue and create a new solution.
This article will take you less than five minutes to read.
Introduction
Following up on a previous: “Can I do Better?” article where I improved how I connect to Docker Containers.
All of the sudden, I was running into an issue where the command:
Started to give me errors:
HUH?? What happened??
Why?
Probably the first place to start is to understand why this command is starting to fail. The command itself is agnostic to the container, specific to the image.
Container not running?
What happens if the foo
image isn’t running in a container?
Let’s try the command so it would definitely fail:
Ideally, this is not that useful of a message, it’s a quick and dirty
test to tell me what the response of the command is when I want to
connect to a container with invalid_image_name
. This is important.
This isn’t the message I saw earlier, so it seems this isn’t the issue.
What happens with a valid name?
Let’s run the same command and this time, give a valid_image_name
so
it should work.
This is the response now:
This isn’t the same response as for an invalid_image_name
and it is
the message I have been receiving.
Things aren’t working even though the container is running the specified image. What’s going on?
Debug script
Let’s break down the script, run each part individually to validate, and check results.
There’s two parts two the script:
- getting the docker container SHA for a specific image name, in this
case:
valid_image_name
- connecting to the docker container SHA
Getting the Container SHA
The main driver of this script is getting the container SHA given a “valid image name”.
What is the output if I run it now?
There are two SHA returned now instead of one?? Are each of these valid?
Validate Outputs
The easiest way to validate: plugin the new SHA values into the next part of the command:
and if it works, then something else is wrong with the first part of the command.
Here goes nothing:
Yup, as expected.
Same here.
So, this is working as expected. Something in the first part of the command changed, it does look the same at the same time, different.
The outputs are correct, SHA values of the container for the image specified. The incorrect part is now there is more than one value.
Investigating higher
Maybe something higher changed at a higher level in the system, outside of the scope of the command.
What does docker ps
tell us?
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8996065500e ubuntu "/bin/bash" 4 seconds ago Up 2 seconds clever_goldstine
5bb3e80c076d nginx:latest "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp objective_hermann.1.6agqbzmx8qiazhwwncdegknwa
f8ead854815d registry:latest "/entrypoint.sh /etc…" 44 seconds ago Up 42 seconds 5000/tcp registry.1.4efrmjz58hqjdtmhdqhpg4q0z
2df0bba15bc6 foo "nginx -g 'daemon ..." 47 seconds ago Up 46 seconds 80/tcp sad_boyd
574687ed515e foo "nginx -g 'daemon ..." 49 seconds ago Up 48 seconds 80/tcp laughing_beaver
There are multiple containers running the foo
image!
The command I wrote was for a single container running that image. I did not account for multiple containers of the same image.
Honestly, I just want to connect to the first container running the
foo
image, it doesn’t really matter to me.
Where are we?
The right image is running one multiple containers. Each container is connect-able.
The one-liner works when there is a single container. When there are more than one container, the result of the container listing command returns multiple items, essentially an array.
To make this command work in a multi-container environment for the same image, there needs to be a change in the first part of the command:
So the second part can handle the result.
Potential Solution?
To me, since the image running on the container is the same, whichever one I connect won’t matter. I can just take the first one.
To do that, I just need to take the output from:
and use the first one.
The easiest way would be to use the head
or tail
function, which
returns the first or last n items specified: head -1
for the first
or tail -1
for the last.
Solution
Incorporating head
into original command:
Results in:
The best part about this solution, it’s still works when there’s a single container that matches the container search function:
Final Solution
The update one-line I will use to connect to docker containers now is:
It’ll work wherever multiple containers running image that has name:
valid_image_name
.
Conclusion
What started off as a solved problem in one specific case evolved into a solution that can handle another case. Best of all, the new solution encapsulates both the new case and the old case.
Now I have a one-liner to connect to any docker container running a
specified name and I understand how to use head
or tail
in array
outputs or at least just picking one.