Please wait until that HTTP service is ready
When ready isn't ready
All container environments have a "depends" clause, so the container runtime can determine the correct startup sequence for the zoo of containers comprising the application to be launched. Each container will usually signal when it is ready.
However ready can mean different things to different applications.
In the container world it should be: the service is available.
However it could be: service was successfully started, but might be busy with house keeping. In the later case the start scripts of the dependent services need to do their own waiting
curl to the rescue
Whipping up a little shell script provides what we need:
#!/bin/bash # Wait for a http service to be available export TARGET=http://baseservice.local/ curl -v \ --retry 10 \ --retry-delay 20 \ --retry-connrefused \ $TARGET if [ "$?" -ne 0 ]; then echo "Failed to reach $TARGET" exit 1 else echo "$TARGET has replied!" fi
Let's break it down:
export TARGETdefines the URL you want to reach. Works for both
https. Potentially works for other protocols supported by curl as well, but I haven't tested that (yet). You might swap it out for
$1to capture the first parameter called
\denominates line continuation. The whole command needs to be on one line which is hard to read.
\tells Linux to treat the following line as belonging to the current one. On Windows you need to replace
^and alter the syntax according to Powershell
curl -vVerbose output, so the logs tell the full story. When you work with privat CA or self signed certificates (Don't do self signed, use your own CA), you need to add
--insecureto make this work
--retry 10try the connection 10 times
--retry-delay 20Wait 20 sec until the next try
--retry-connrefusedretry even on "connection refused" responses. By default curl retries only http responses not in the
2xxrange. Connection refused is HTTP's way telling you: there's nothing taking your call, which curl, without
--retry-connrefusedtakes as final, fatal error and terminates retries. When you have curl v7.71.0 (from 2020 or later), you can use
--retry-all-errorsinstead. The documentation warns This option is the "sledgehammer" of retrying. Use it wisely
if [ "$?" -ne 0 ]; thenCommands usually return a numeric result. Anything other than
0indicates a failure condition of some sort. When curl has exhausted the number of retries a value greater 0 will be returned. To capture the return value we us
return 1We indicate that our script failed. So it can be called from other scripts
We could swap out
$1 which makes the script callable handing over the target URL e.g
The script is also useful in "classic" situations, where you start a service in the background (which by definition is asynchonous). Your local environment uses anything like:
systemctl start myservice
You can use the curl retry for any automation. Adjust the wait time and the retry time to your needs.
As usual YMMV