I would like to run db migrations in cloud run entrypoint (e.g. php artisan migrate) to avoid having to use an external tool to run these before promoting a revision.
In kubernetes this functionality can be achieved by having an init container on a deployment run the migrations and setting max surge to 1, ensuring only one pod attempts the migration before rolling out to other containers.
Is the rollout strategy of CloudRun defined anywhere? It would be nice if CloudRun waited for one container in a revision to be healthy before cutting over wholesale, which would meet this purpose (although it's not too bad of a problem with postgres transactional DDL if multiple containers attempt a migration). I think this is the behaviour I observe but not sure.
Is there a better/low-maintenance way to run the migrations than have it run in every entrypoint?
In kubernetes this functionality can be achieved by having an init container on a deployment run the migrations and setting max surge to 1, ensuring only one pod attempts the migration before rolling out to other containers.
This is not a good practice in general, even in Kubernetes.
Ideally your DB migration code should be idempotent. Especially in serverless world you will find the lack of these primitives surprising unless you shift the mindset and thinking about these concepts.
Cloud Run's rollout strategy is through configuring manual traffic splitting –which routes traffic between revisions based on percentages you define.
You can develop a new revision of a Cloud Run Service, receiving 0% traffic.
Upon deployment of a Revision, Cloud Run will still run at least one container, to see if the application becomes ready (i.e. the process starts listening on PORT). Though, you probably should not rely on only 1 instance coming up during this process, as that's not a guaranteed behavior.
Using this trick, you can perform a DB migration (note the "Limits" section of documentation for startup timeouts) before listening on the PORT number. But you need to write some logic (or use an external locking/synchronization mechanism) to make sure that code path is not executed over and over again in the future (or simultaneously while the migration is happening).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With