1

I have a Django-Postgres app deployed with Docker. I have two docker containers web and dband one docker volume for persistent storage.

My docker-compose.yml file:

version: '2'
services:
  db:
    image: postgres
    ports:
      - '5432:5432'
    volumes:
      - 'postgres:/var/lib/postgresql/data'
    env_file: .env

  web:
    build: .
    command: ./start.sh
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    depends_on:
      - db
    env_file: .env

volumes:
  postgres:

I made a change in my django model.py:

class Meeting(models.Model):
    [...]
    participants = models.CharField(max_length=200)

to

class Meeting(models.Model):
    [...]
    user_participants = models.CharField(max_length=200)

However, this change is not reflected on my Django app and I get the following error:

column call_meeting.user_participants does not exist

I ran:

python manage.py makemigrations call
python manage.py migrate

Then I tried to delete Django migrations and re-run the above commands. I have tried to re-run docker-compose build but none of them worked.

Why does this happen? Should I change the column names with raw SQL?

Risadinha
  • 16,058
  • 2
  • 88
  • 91
Galil
  • 859
  • 2
  • 16
  • 40
  • Are there any errors reported when running `makemigrations` or `migrate`. After running `migrate` what does `showmigrations` display? Which django version do you use? Raw SQL should not be necessary. – Risadinha Jan 31 '17 at 13:47
  • @Risadinha I am running Django 1.10.5. I deleted old migrations and executed ``makemigrations`` and ``migrate`` again. There are no errors. ``showmigrate`` for this app returns ``call [X] 0001_initial`` – Galil Jan 31 '17 at 14:14
  • Deleting the migrations, recreating them and running them again without dropping the database should have produced an error, because normally you either have to recreate the database as well or use the `--fake` flag. Have you had a look at the db with `psql` inside the docker postgres container? – Risadinha Jan 31 '17 at 14:32
  • Yes, inside the docker container the tables have not changed at all. They still have the old column name ``participants`` instead of ``user_participants``. Do you think that the problem has to do with the fact that I am using a volume? – Galil Jan 31 '17 at 14:38

1 Answers1

0

From your question and comments, I get the impression that your django is not using the correct database. Or more probably (rather than two co-existing db instances), the database is recreated on every docker restart even though the docker-compose file does not look like it.

We are using a similar setup which works for us, but the data volume is mounted differently - so that might be the issue here:

- ./pgdata:/var/lib/postgresql/data/pgdata

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ.get('POSTGRES_DB', 'my_db'),
        'HOST': os.environ.get('POSTGRES_HOST', 'localhost'),
        'PORT': os.environ.get('POSTGRES_PORT', '5432'),
        'USER': os.environ.get('POSTGRES_USER', 'my_user'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'my_password'),
        'CONN_MAX_AGE': 120
    }
}

docker-compose.yml

version: '2'

services:
    postgres:
        image: postgres:9.5
        volumes:
            - ./pgdata:/var/lib/postgresql/data/pgdata
        environment:
            - PGDATA=/var/lib/postgresql/data/pgdata
            - POSTGRES_DB=<name>  #django.settings.DATABASES['default']['NAME']
            - POSTGRES_USER=<user>  #django.settings.DATABASES['default']['USER']
            - POSTGRES_PASSWORD=<password>  #django.settings.DATABASES['default']['PASSWORD']
        ports:
            - 5432:5432

    web:
        depends_on:
            - postgres
        volumes:
            - .:/app
        environment:
            - POSTGRES_HOST=postgres
            - POSTGRES_DB=<host>  # no need if settings.py is fine
            - POSTGRES_USER=<user>  # no need if settings.py is fine
            - POSTGRES_PASSWORD=<password>  # no need if settings.py is fine
        build: .
        ports:
            - 8000:8000
        command: ./start.sh
Risadinha
  • 16,058
  • 2
  • 88
  • 91
  • Now I get ``django.db.utils.OperationalError: could not connect to server: Connection refused Is the server running on host "db" (172.20.0.2) and accepting TCP/IP connections on port 5432?`` – Galil Jan 31 '17 at 15:31
  • Have you replaced `postgres` with `db` everywhere in my above code? (Or use as is.) Can you start docker-compose without the `-d` flag to see the output of both containers? Make sure, all of the db settings in your settings.py match the docker compose envs. – Risadinha Jan 31 '17 at 16:01
  • I have removed the IP address from the ports directive. That was the problem for me right now (I don't remember why I put it in, initially). – Risadinha Jan 31 '17 at 17:27