How to write to a docker container’s log from another process

I try hard to make my integration tests run in docker containers to guarantee they are not mistakenly dependent on my system and that they test the system as if a real deployment was in place.

Sometimes a test depends on some startup string existing in the logs. An example is that my server emits an administrator temporary password for the first time the server runs. This one-time administrator password is written to stdout and docker logs <container> captures it. Unfortunately for my testing setup, when the container is destroyed and re-setup the logs are reset losing that one-time password needed by the tests. That destroy/re-setup cycle is often manual and not part of the expected flow but it happens frequently due to manual tunings.

I used to just hardcode the temporary password on the tests for when manual iteration was ongoing but this was annoying because I needed to be careful to not commit the temporary change, and because it always meant I always needed to carry over a diff with such workaround. That temporary password would actually be meaningless if it was committed and would break automated actual testing. Instead of changing code with the drawbacks above, I found a way to manually write the temporary password back to the docker logs.

The docker logs --follow command will continue streaming the new output from the container’s STDOUT and STDERR.

The question is how can we write to the container’s log if the container’s process itself will not do it?

By default, docker spawns a container with a process ID=1. In Linux, you can write to a process’ file descriptors as long as have the right permissions. stdout is file descriptor number 1. This means:

docker exec -it <container name> bash
echo 'magic string' > /proc/1/fd/1 # Where /proc/$PID=1/fd/fd=1(stdout0

Make sure your container is running to be able to do this, otherwise it will not work:

The docker exec command runs a new command in a running container.

PS: I could not find a primary source documenting that PID = 1 is the default PID for a newly spawned container. Given the meaning of PID=1 in Linux it is baffling or I am making a very wrong assumption.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s