Starting the database container before the application container sounds like it should solve startup failures. It only solves part of the problem. The database process can exist before it is ready to accept connections, so an application can still race ahead and fail during an otherwise normal startup.
Docker’s Compose startup-order documentation makes the distinction explicit. A dependency with the service_healthy condition waits for a declared health check to pass. That is more useful than assuming a fixed delay will happen to be long enough on every machine.
I would make the check test the capability the dependent service actually needs. An open socket is not always enough, and a check that relies on unrelated external services can make local startup unnecessarily fragile. Keep it specific, bounded and understandable. Then make the application’s own connection handling sensible, because databases can restart after the initial startup too.
Adding “sleep 30” may hide the issue on your laptop, but it leaves the timing guess in place. A small readiness check expresses what you are waiting for. That is easier to debug, usually quicker when things are healthy, and much less annoying when a slow machine exposes the original assumption.