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.