How to run database migrations at deploy time in Django-based applications¶
Django has built-in support for managing database schema migrations via a migrate
management
command. Although automatic, the migrations need to be triggered by running the appropriate
management command.
Previously we baked this command into the container image for the application; each time the application started, it would ensure that the database is using the latest schema version.
While simple, this approach had some drawbacks. Aside from adding additional startup latency to the application, it also was risky if Cloud Run started two containers at the same time since database migration code might end up running twice. The best scenario in this case would be for one of the migrations to fail, thereby causing one Cloud Run container to exit.
We no longer do this. We now run database migrations as a pre-deploy job.
This how-to covers how to add pre-deploy jobs to an existing deployment.
Check that the application needs a pre-deploy job¶
If the application has a docker-entrypoint.sh
file which contains an explicit ./manage.py
migrate
command, you do not need to move to using a pre-deploy job but we strongly encourage you
to do so. This can be done by a) forward-porting boilerplate changes to the application and b)
updating the deployment as outlined in this how-to guide.
Move to version 8 of the Cloud Run terraform module or better¶
In webapp.tf
, check that you are using version 8 or better of our Google Cloud Run terraform
module.
Pre-deployment job support was added in version 8.1.0.
Add the pre-deploy job configuration¶
Add one of the following configurations to the webapp.tf
file depending on the
version of the gcp-cloud-run-app
module being used.
For gcp-cloud-run-app
module versions >= 8.1.0
and < 9.0.0
:
module "webapp" {
source = "gitlab.developers.cam.ac.uk/uis/gcp-cloud-run-app/devops"
version = "~> 8.1"
# ...
enable_pre_deploy_job = true
pre_deploy_job_command = ["python3"]
pre_deploy_job_args = ["/usr/src/app/manage.py", "migrate"]
}
For gcp-cloud-run-app
module versions >= 9.0.0
:
module "webapp" {
source = "gitlab.developers.cam.ac.uk/uis/gcp-cloud-run-app/devops"
version = "~> 9.0"
# ...
enable_pre_deploy_job = true
pre_deploy_job_container = {
image = "image:tag", # need to specify image
command = ["python3"],
args = ["/usr/src/app/manage.py", "migrate"]
}
}
An example of this configuration can be found in the deployment of the Regent House Ballots application.
Summary¶
In this how-to, you learned how to add a pre-deploy job to a Cloud Run deployment in order to run database migrations.
Next steps¶
- Read more about how we deploy via terraform.