Mitch
Mitch

Reputation: 193

Django migrations and docker containers

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

Answers (2)

A Lee
A Lee

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

Satendra
Satendra

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

Use docker-compose run

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

Use entrypoint.sh

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

Related Questions