Django не подключается к базе данных postgresql с помощью docker

Я довольно новичок в Django и очень новичок в docker. Это мой первый раз, когда я использую docker. Я пытаюсь подключить мое приложение django в одном контейнере docker к базе данных postgreSQL в другом контейнере docker. Я следовал учебнику youtube, когда столкнулся с этой проблемой. Однако я следовал не совсем так, как показано в видео. Я использую Docker на Windows 10.

Мой файл 'docker-compose.yml':


    version: '3.8'
    
    services:
      db:
        container_name: db_ramrobazar
        image: postgres
        restart: always
        environment:
          - POSTGRES_DB=postgres
          - POSTGRES_USER=postgres
          - POSTGRES_PASSWORD=postgres
        ports:
          - '5432:5432'
        volumes:
          - postgres_data:/var/lib/postgresql/data/
        # env_file: .env
        networks:
          - djangonetwork
    
      web:
        container_name: web_ramrobazar
        build:
          context: .
        depends_on:
          - db
        command: >
          sh -c "python manage.py makemigrations && 
                 python manage.py migrate &&
                 python manage.py runserver 0.0.0.0:8000"
        ports:
          - "8000:8000"
        env_file: .env
        links:
          - db:db
        networks:
          - djangonetwork
        volumes: 
          - .:/usr/src/app
    
    volumes:
      postgres_data:
    
    networks:
      djangonetwork:
        driver: bridge

Мой Dockerfile файл:


    FROM python:3.8-slim-buster
    
    
    # setting work directory
    WORKDIR /usr/src/app
    
    
    # env variables
    ENV PYTHONUNBUFFERED 1
    ENV PYTHONDONTWEITEBYTECODE 1
    
    # install psycopg dependencies
    RUN apt-get update && apt-get install -y \
        build-essential \
        libpq-dev \
        && rm -rf /var/lib/apt/lists/*
    
    
    # install dependencies
    RUN pip install --upgrade pip
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    
    
    COPY . .

Мой .env файл:


    DEBUG=True
    SECRET_KEY=mysecretkey
    ALLOWED_HOSTS=*
    DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres
    
    # postgres
    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    POSTGRES_DB=postgres
    ENGINE=django.db.backends.postgresql_psycopg2
    HOST=localhost
    PORT=5432

Мой settings.py файл:


    # DATABASES = {
    #     'default': {
    #         'ENGINE': 'django.db.backends.sqlite3',
    #         'NAME': BASE_DIR / 'db.sqlite3',
    #     }
    # }
    
    DATABASES = {
        'default': {
            'ENGINE': config('ENGINE'),
            'NAME': config('POSTGRES_DB'),
            'USER': config('POSTGRES_USER'),
            'PASSWORD': 'postgres',
            'HOST': config('HOST'),
            'PORT': config('PORT'),
        }
    }
    
    # DATABASE_URL = config('DATABASE_URL').replace("\'", "")
    # DATABASES = {
    #     'default': dj_database_url.parse(DATABASE_URL, conn_max_age=600)
    # }

Когда я удаляю все файлы миграции (например, 0001_initial.py) и выполняю docker-compose up --build, я получаю следующее:

Когда в docker запущена только база данных 'db_ramrobazar' и я пытаюсь выполнить python manage.py makemigrations, я получаю следующее:


    (venv) C:\Users\ashut\Desktop\ramrobazar>python manage.py makemigrations
    C:\Users\ashut\Desktop\ramrobazar\venv\lib\site-packages\django\core\management\commands\makemigrations.py:121: RuntimeWarning: Got an error checking a consistent migration history performed for database connection 'default': connection to server at "localhost" (::1), port 5432 failed: FATAL:  password authentication failed for user "postgres"
    
      warnings.warn(
    Migrations for 'account':
      ramrobazar\account\migrations\0001_initial.py
        - Create model User
        - Create model UserProfile
    Migrations for 'inventory':
      ramrobazar\inventory\migrations\0001_initial.py
        - Create model Brand
        - Create model Category
        - Create model Product
        - Create model ProductAttribute
        - Create model ProductAttributeValue
        - Create model ProductInventory
        - Create model ProductType
        - Create model Stock
        - Create model SoldStatus
        - Add field product_type to productinventory
        - Create model Media

После получения вышеуказанного результата из makemigrations, когда я выполняю python manage.py migrate, я получаю следующее:

Я пробовал изменить пароль пользователя 'postgres' с помощью CLI, как показано ниже, но это ничего не дало.


    # psql -U postgres -d postgres
    psql (14.3 (Debian 14.3-1.pgdg110+1))
    Type "help" for help.
    
    postgres=# ALTER USER postgres WITH PASSWORD 'postgres';
    ALTER ROLE
    postgres=#

Пожалуйста, дайте мне знать, если потребуется что-то еще.

Попытайтесь удалить

command: >
  sh -c "python manage.py makemigrations && 
         python manage.py migrate &&
         python manage.py runserver 0.0.0.0:8000"

Запустите контейнер с помощью docker-compose run -p 8000:8000 web_ramrobazar sh

И как только он окажется в оболочке, запустите команды миграции. В противном случае вы можете написать команду управления, которая проверяет, запущен ли postgresql, а затем выполнить команду.

  sh -c "python manage.py wait_for_db &&
         python manage.py migrate"

Возможно, вы хотите добавить в web_ram...

зависит_от:

  • db_ram...

Вот wait_for_db, который вы можете написать в одном из своих приложений:

import time

from django.db import connections
from django.db.utils import OperationalError
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    """Django command to pause execution until database is available"""

    def handle(self, *args, **options):
        self.stdout.write("Waiting for database...")
        db_conn = None
        while not db_conn:
            try:
                db_conn = connections["default"]
            except OperationalError:
                self.stdout.write("Database unavailable, waiting 1 second...")
                time.sleep(1)

        self.stdout.write(self.style.SUCCESS("Database available!"))

Итак, похоже, что я уже нашел ответ в первой правке. Я просто забыл вернуть глупое изменение, которое я сделал, пробуя разные вещи. Вот решение:

В моем .env файле:


    DEBUG=True
    SECRET_KEY=mysecretkey
    ALLOWED_HOSTS=*
    DATABASE_URL=postgres://postgres:postgres@db:5432/postgres
    
    # postgres
    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    POSTGRES_DB=postgres

Измените DATABASE_URL, как показано выше.

Я использую python-decouple для переменных окружения. Вы можете найти его здесь. Я также использую dj-database-url для переменной окружения DATABASE_URL. Вы можете найти его здесь.

В моем settings.py:


    from decouple import config
    import dj_database_url
    
    DATABASE_URL = config('DATABASE_URL').replace("\'", "")
    DATABASES = {
        'default': dj_database_url.parse(DATABASE_URL, conn_max_age=600)
    }

Запустите все команды управления, как показано ниже (внесите соответствующие изменения в соответствии с именем вашей службы и другими именами):

docker-compose run --rm web python manage.py makemigrations
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py runserver
docker-compose run --rm web python manage.py createsuperuser

Это сработало для меня. Я нашел приведенные выше команды здесь в комментарии пользователя Iain Shelvington.

Вернуться на верх