Why am I unable to run django migrations via the 'docker-compose run web' command?
In order to resolve the following error in my Django app, I knew I just had to run a Django migration.
docker@postgres ERROR: relation "accounts_myprofile" does not exist
In an attempt to run migrations, I tried:
docker-compose run web python manage.py makemigrations docker-compose run web python manage.py migrate
which returned the following:
Migrations for 'accounts': accounts/migrations/0001_initial.py: - Create model Entry - Create model MyProfile Running migrations: No migrations to apply.
I was only able to successfully migrate from within the Django container, example:
docker exec -i -t 6dc97c6a305c /bin/bash python manage.py makemigrations python manage.py migrate
Although I have resolved the issue, I still don’t understand why running the migrate via docker-compose run does not actually migrate anything. I’m hoping someone can maybe point me in the right direction on this.
Also, I don’t know if this is a related issue or not, but when I run those docker-compose run web commands, they seem to be creating new containers that won’t shutdown unless I manually stop them, docker-compose stop doesn’t remove them.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a7bb3c7106d1 accounts_web "python manage.py che" 4 hours ago Restarting (0) 41 minutes ago 8000/tcp accounts_web_run_62 ee19ca6cdf49 accounts_web "python manage.py mig" 4 hours ago Restarting (0) 43 minutes ago 8000/tcp accounts_web_run_60 2d87ee35de3a accounts_web "python manage.py mak" 4 hours ago Restarting (0) 43 minutes ago 8000/tcp accounts_web_run_59 1c6143c13097 accounts_web "python manage.py mig" 4 hours ago Restarting (1) 44 minutes ago 8000/tcp accounts_web_run_58 6dc97c6a305c b1cb7debb103 "python manage.py run" 3 days ago Up 4 hours 8000/tcp accounts_web_1
Note: Docker-compose stop will properly stop the container at the bottom (as it should), but the other container that were created by docker-compose run web python manage.py migrate, will need to be manually stopped.
web: restart: always build: ./web expose: - "8000" links: - postgres:postgres volumes: - /usr/src/app - /usr/src/app/static env_file: .env environment: DEBUG: 'true' command: python manage.py runserver 0.0.0.0:8000 postgres: restart: always image: kartoza/postgis:9.4-2.1 ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data/
One Solution collect form web for “Why am I unable to run django migrations via the 'docker-compose run web' command?”
docker-compose run creates new containers
You have already noticed the problem. When you use
docker-compose run, a new container is created.
When you ran the first command (makemigrations), a new container was created, makemigrations ran, and the migration files were written to the (new) container’s filesystem.
When you ran the second command (migrate), another new container was created. The migration ran, but it had nothing to do. That’s because the migration files were not available – they were written in a different container than this new one.
You can solve this in a couple of ways.
Using docker-compose exec
First, you can do what you already did, but use
docker-compose exec instead of
docker-compose exec web python manage.py makemigrations docker-compose exec web python manage.py migrate
exec will use the already-running container, rather than creating new containers.
Using an entrypoint script
Another option is to use an entrypoint script and run the migration there, before the server is started. This is the way to go if you’d prefer things to be more automatic.
COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh
#!/bin/sh python manage.py makemigrations python manage.py migrate exec "$@"
docker-compose.yml (under ‘web’):
In this scenario, when the container starts, the entrypoint script will run, handle your migration, then hand off to the
command (which in this case is Django
The new containers loop forever
As you noticed, the new containers stay running. That is normally unexpected, because you overrode the command with one that should exit (rather than stay running). However, in docker-compose.yml, you specified
restart: always. So they will run the migration commands over and over, restarting each time the command exits.