Synchronizing docker containers with netcat
A user in
asked “How can i wait for container to exit with code 1 before starting another
container using docker-compose”. Ignoring the question of “why?” (a fair
question, but let’s assume a valid use case), one response was “use a shared
volume and write the exit code to a file”. Not a terrible solution, shared
volumes are quite useful. However, I realized this was a great use of the
netcat, so whipped up a sample compose file for fun.
Here’s a simple compose file with two containers:
second that starts a netcat
server on port 3000 that will return “OK” on connect, then print the message
cat, this is where any logic based on the exit code would go) and run our
first runs our first workload (sleep for five seconds) then
opens a connection to
second, passing the exit code. Note that there’s a few
netcat out there, but I think this basic usage is the same between
version: '3' services: second: image: alpine command: - '/bin/sh' - '-c' - 'echo "OK" | nc -l -p 3000 | cat && echo "doing the second thing"' first: image: alpine command: - '/bin/sh' - '-c' - 'echo "doing the first thing" && sleep 5 && echo "$$?" | nc second 3000'
) docker-compose up Recreating container_wait_second_1 ... done Recreating container_wait_first_1 ... done Attaching to container_wait_second_1, container_wait_first_1 first_1 | doing the first thing second_1 | 0 first_1 | OK second_1 | doing the second thing container_wait_first_1 exited with code 0 container_wait_second_1 exited with code 0
A neat variation on this is to use the
-e argument (in this version of
netcat anyways) to have
netcat run the workload, and send the stdout back to
- - 'echo "OK" | nc -l -p 3000 | cat && echo "doing the second thing"' + - 'nc -l -p 3000 -e echo "doing the second thing"'
) docker-compose -f docker-compose.passback.yml up Recreating container_wait_second_1 ... done Starting container_wait_first_1 ... done Attaching to container_wait_first_1, container_wait_second_1 first_1 | doing the first thing first_1 | doing the second thing container_wait_first_1 exited with code 0 container_wait_second_1 exited with code 0