Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PostgreSQL: Document how a dependent service/container should detect when the database has started #2467

Open
Chealer opened this issue Jul 15, 2024 · 9 comments

Comments

@Chealer
Copy link

Chealer commented Jul 15, 2024

The postgres images provide an RDBMS which is usually a dependency of other services. The Compose depends_on attribute allows to express that, but its conditions attribute defaults to service_started, which does not work properly (the dependency is satisfied too early).

Lots of webpages deal with that issue, such as the docker-compose-healthcheck project, usually suggesting the service_healthy condition instead. It would be great to either provide a proper/reliable way for PostgreSQL to signal dependents that it is actually started, or at least mitigate by documenting the best way to workaround.

@tianon
Copy link
Member

tianon commented Jul 22, 2024

The best way for your application to know whether a dependency it relies on is up/ready for use is to query it directly, and I don't think there are really very many good shortcuts for doing so.

In general, the best way to test for postgres being ready for connections is to query it via TCP, but to my point above, that only verifies that it's listening, not that any database migrations have run, etc. (ie, not that it's necessarily ready for application use, just that it's "up")

See https://github.com/docker-library/healthcheck/blob/40afbf64d69cf933af0da4df6383958a29113601/postgres/docker-healthcheck for an example "healthcheck" which does this from within the postgres container itself (but again, with the caveat that it's only a partial solution for the actual end use case).

@Chealer
Copy link
Author

Chealer commented Jul 25, 2024

Thanks
The application is responsible for checking that the database's content matches its expectations, and to make it so if not. All this is asking is to document the best way a different container can detect the end of startup.

@Chealer Chealer changed the title PostgreSQL: Document how to poll when the database has started PostgreSQL: Document how a dependent service/container should detect when the database has started Jul 25, 2024
@Chealer
Copy link
Author

Chealer commented Aug 7, 2024

It looks like this can be achieved with:

depends_on:
  postgres-pes:
    condition: service_healthy

However, at least as of postgres:12 and with Docker 27.1.1, how the database checks its health doesn't appear to be controllable, unlike what is documented in a 2022 blog post and suggested by comments in ticket #2391. I do not understand how that check works and am unable to change the intervals from the default values.

@tianon
Copy link
Member

tianon commented Aug 7, 2024

That condition relies on a configured and working healthcheck on the container (https://docs.docker.com/reference/dockerfile/#healthcheck and/or https://docs.docker.com/reference/cli/docker/container/run/#:~:text=groups%20to%20join-,%2D%2Dhealth%2Dcmd,-Command%20to%20run), none of which is installed, enabled, or configured in this image by default.

(the comment you linked to notably does not explicitly connect via TCP as noted in this thread and in that thread lower in #2391 (comment), so it will not detect that PostgreSQL is ready but rather will mis-detect the initial setup instance as healthy)

@yosifkit
Copy link
Member

yosifkit commented Aug 7, 2024

best way a different container can detect the end of startup.

When using the provided docker-entrypoint.sh and not modifying the temporary postgresql server it runs during initialization, if the postgres container is listening/responding to remote connections on the configured port (i.e., not via the unix socket), then it has completed its startup.

https://github.com/docker-library/postgres/blob/66da3846b40396249936938ee17e9684e6968a57/docker-entrypoint.sh#L329-L351

@Chealer
Copy link
Author

Chealer commented Sep 24, 2024

Sorry, I retract most of my previous comment. I can't remember the details, but I was confused because basically I was just not using the right command for the changes to take effect. The intervals are set in the compose file, it's just that depending on which command you use, you could stick with the values from earlier versions of your compose file.

@Chealer
Copy link
Author

Chealer commented Sep 24, 2024

best way a different container can detect the end of startup.

When using the provided docker-entrypoint.sh and not modifying the temporary postgresql server it runs during initialization, if the postgres container is listening/responding to remote connections on the configured port (i.e., not via the unix socket), then it has completed its startup.

Yes, thanks anyway but by "best" I don't just mean reliable, I also mean efficient. I.e. a method which uses a pushed signal rather than polling.

@tianon
Copy link
Member

tianon commented Sep 26, 2024

Yeah, that would be nice, but I don't think Docker supports anything like sd_notify, so we don't have a mechanism for the container to notify outwards except polling / listening port state changes.

@Chealer
Copy link
Author

Chealer commented Sep 27, 2024

Thanks Tianon, I'm afraid you're right. So yes, this seems to be about:

  1. checking that there is no way
  2. assuming there isn't, checking if there's a ticket tracking that
  3. document the best way, mentioning the relevant issue report if possible so that readers can check that the recommended method is still the best one at the time they read it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants