I'm creating a PHP container with two associated services; Redis and Postgres.
Before going too far in my CI, I would like to capture as quick as possible connectivity errors: can PHP connect to Redis and can PHP connect to Postgres? And to stop my CI in case of problems.
I would like to wait until both Redis and Postgres are "ready" before continue my Python code. Like I do using depends_on in a compose.yaml file.
For Redis, my code works (at the bottom of my message below); not for Postgres. Postgres is still starting up and the database not yet ready.
More detail below.
I've a code like this:
self.container = (
# So attach the postgres container to my PHP one
await self.container.with_service_binding(postgres.host, postgres.server)
# [...]
)
# Test if the connection if successfull i.e. port, host, user, password, ... are OK and connectivity works
self.container = await self.container.with_exec(
["psql", "-h", postgres.host, "-p", postgres.port, "-U", postgres.username],
expect=ReturnType.ANY,
).sync()
output: str = await self.container.stdout()
# For the illustration, I run an exception just to see what stdout() contains
raise RuntimeError(
f"{await self.container.stdout()}\n"
)
And I get this output:
psql: error: connection to server at "(my host)" (10.87.1.115), port 5432 failed: FATAL: the database system is starting up
So... ouch... Postgres isn't yet ready. ==> how can I wait for it's ready?
If I do the same for Redis; it works:
self.container = (
await self.container.with_exec(["pecl", "install", "redis"])
.with_exec(["docker-php-ext-enable", "redis"])
# [...]
)
# [...]
self.container = await self.container.with_exec(
["redis-cli", "-h", redis.host, "--pass", redis.password, "ping"],
expect=ReturnType.ANY,
).sync()
output: str = str(await self.container.stdout()).strip().upper()
# And output is well "PONG"; nice!
Thanks!