The issue:
Locally, I use Skaffold (Kubernetes) to hot reload both the client side and server side of my code. When I shut it down, it deletes my server pod, including my /migrations/ folder and thus gets out of sync with my database alembic_version. On production, I'm not deleting my server pod, but I am rebuilding the docker image when I deploy which results in my /migrations/ folder being replaced.
The question
How do I handle these migrations so my database doesn't get out of sync?
application setup
Flask/Python API and use Flask Migrate. For those unfamiliar, what it does is create a migrations folder with version files like 5a7b1a44a69a_.py
. Inside of that file are def upgrade()
and downgrade()
to manipulate the db. It also records the revision and down_revision references for the alembic_version table in my postgres pod.
Kubernetes and Docker setup
I have a server pod and postgres pod. I login to the shell of the server pod to run the migrate commands. It creates the version files inside of the docker container and updates the db.
To show a step-by-step example of the problem:
- sh into server-deployment pod and run db init.
- Migrations folder is created.
- perform migration on server-deployment which creates migration file and updates the db.
- postgres pod db gets alembic_version entered and an update.
- use skaffold delete or ctrl-c skaffold.
- server-deployment pod gets deleted, but postgres doesn't. Migrations folder goes away.
- Start back up skaffold and sh into server-deployment pod and try to run db migrate. Asks you to do an db init.
- If you try to downgrade from here, it doesn't do anything. Now server pod and postgres pod are out of sync in terms of alembic_version.
Final Notes
What I used to do pre-docker/kubernetes was run it locally and I would commit that migrations version file to my repo. It was synced across all environments so everyone's repo was on the same alembic_version. I've considered created a separate, always-on "migrations-deployment" pod that is another instance of flask so that it never loses the /migrations/ folder. However, that seems like a really poor solution.
Hoping for best practices or ideas!