Earlier quoted context omitted.
This. I use celery with the same code base/docker image. Just a different entry point to start a celery worker instead of a wsgi (web) worker. Too many http requests? Add web worker instances. Background jobs piling up? Add celery workers. Clearly separate read endpoints from write/transactional endpoints and you can hit a slave postgres db or the master db depending on the http call. This creates a very robust syste…
I do the same, it's easy enough and doesn't require a ton of hosting logic. Out of interest, how do you run your migrations in production, deploy the service then run an ad-hoc job with the same container again? That was one thing I was never super happy with.
So new version can work with the previous version's DB schema.
Then, yes, simply run the migration in a transaction once the new code is deployed. Postgres has fully transactional DDL changes which helps.
Of course, it heavily depends on the actual change being made. Some changes will require downtime or must be avoided if it is too heavy on the db.
Another approach if the migration can be applied quickly is to just run the migrations as part of the deployment script. This will cause a downtime but can be short.
Easiest is just to do runmigrations in your docker image start commands, so DB is always migrated when the container starts.
tl;dr: It depends on the complexity of the migrations and your uptime requirements.