Why am I unable to run django migrations via the 'docker-compose run web' command?

So I am deploying django, postgress and nginx containers via docker-compose and I have an issue that I can’t seem to figure out.

In order to resolve the following error in my Django app, I knew I just had to run a Django migration.

  • Service docker start not work(daemon), ubuntu-15.10, To run dockerfile with intelliJ
  • What are the differences between sharing a dockerfile on git and sharing a docker container?
  • Unable to install chef-server on docker container
  • Docker-compose restart only updated images
  • Docker can not be installed on CentOS
  • Vagrant with Docker provider does not share folders
  • 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.

    my docker-compose

    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/
    

  • Docker installation on ubuntu raring
  • How to create docker containers with the same internal IP address?
  • Run app inside docker container as non-root user with capabilities
  • Restrict published port to a specific container with Docker
  • Vagrant + docker errors
  • How to persist data using a postgres database, Docker, and Kubernetes?
  • 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 run.

    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.

    Dockerfile:

    COPY entrypoint.sh /entrypoint.sh
    RUN chmod +x /entrypoint.sh
    

    entrypoint.sh:

    #!/bin/sh
    python manage.py makemigrations
    python manage.py migrate
    exec "$@"
    

    docker-compose.yml (under ‘web’):

    entrypoint: /entrypoint.sh
    

    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 runserver).

    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.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.