The Vite point is the one that bites quietly. Without server.strictPort it just moves to 5174, and the only symptom is an OAuth callback or CORS error that looks unrelated. Setting strictPort: true in shared repos turns that into a loud failure, which is easier to debug. Binding databases to 127.0.0.1 is also a good default even when there's no clash, since nothing outside the machine needs to reach a dev Postgres.
Thanks, you've put your finger on exactly the failure that hurts most. The 5174 fallback is the worst kind of bug, because the error you see (an OAuth redirect mismatch or a CORS block) points somewhere completely different from the real cause.
PortClash already covers both points:
Vite: when a Vite dev server's port clashes with something else, the finding says Vite will silently move to the next free port unless server.strictPort is true. It also checks whether strictPort is already set in vite.config or passed as --strictPort, so you know which behaviour you'll get.
Databases: if a compose service publishes a database port on all interfaces ("5432:5432" with no host IP, which means 0.0.0.0), it gets flagged even when nothing else is using that port. It's reachable from your network, and Docker's published ports can bypass host firewall rules like ufw. The fix is to bind it to 127.0.0.1:5432:5432.
I agree on strictPort: true as a default for shared repos. A loud "port already in use" takes ten seconds to fix. A quiet move to 5174 can cost an afternoon.
StackShortlist
Proof Over Promises.
The Vite point is the one that bites quietly. Without server.strictPort it just moves to 5174, and the only symptom is an OAuth callback or CORS error that looks unrelated. Setting strictPort: true in shared repos turns that into a loud failure, which is easier to debug. Binding databases to 127.0.0.1 is also a good default even when there's no clash, since nothing outside the machine needs to reach a dev Postgres.