Reputation: 193
How to handle Django migrations when using Docker.
For example, using containers in your dev environment, you have a Django app and other services, such as a Postgresql db
container. Everything is docker pulled and docker-composed up. Voila!
Now, you are asked to add features which require altering the database. No problem in dev. You make some model changes, use makemigrations
and migrate
and all looks ok.
When pulling your new images to production your migrations don't jive with what's in the persistent db
in the django_tables in prod and you can't run migrations without erroring out.
Anyone know how to make all this less painful.
Upvotes: 4
Views: 9368
Reputation: 8066
We've been using Docker in dev and production for over a year now. If I understand your situation correctly the issue is that your production db schema is getting out-of-sync with your development schema over time.
What helped us is to have easily shippable snapshots of our production schema (with some test data) so when you build a dev image you're running with the production schema and creating migrations based on the prod schema. When you're satisfied that your schema-to-be-migrated to is solid, check those migrations into source control.
Deployment to prod is then shipping an image with those migrations guaranteed to apply cleanly to the prod schema.
Upvotes: 3
Reputation: 6865
Running migration on docker container. suppose your compose file looks like
services:
# cointainer for django app
app:
build:
context: .
dockerfile: ./Dockerfile
depends_on:
- db
Run command manually, The name of Django app container is app
docker-compose run app python manage.py migrate
# use if docker compose file name is other than `docker-compose.yml`
docker-compose -f production.yml run app python manage.py migrate
Run automatically, every time when you up
container.
Create a file name entrypoint.sh on project root and copy below command in it.
python manage.py migrate --noinput
In DockerFile copy entrypoint.sh from your project folder into container app
.
COPY ./entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r//' /entrypoint.sh
RUN chmod +x /entrypoint.sh
RUN chown app /entrypoint.sh
Now there are 2 ways you can make entrypoint.sh
run automatically
Mention ENTRYPOINT
in DockerFile itself.
ENTRYPOINT ["/entrypoint.sh"]
Or you can mention it in docker-compose file with command
keyword under app
.
app:
build:
context: .
dockerfile: ./Dockerfile
depends_on:
- db
# this will run after cointainer `up`
command: /entrypoint.sh
Upvotes: 3