Почему мой контейнер django docker не подключается к базе данных контейнера postgresql? Проблемы с Psycopg2?
Я только что начал использовать django cookiecutter для проекта, который я уже сделал ранее. Я следовал инструкциям, найденным здесь --> https://justdjango.com/blog/django-docker-tutorial, чтобы убедиться, что у меня есть нужные папки и файлы для докеризации моего проекта.
Я успешно создаю контейнеры docker-compose -f local.yml build
журнал командной строки:
Однако когда я поднимаю контейнеры "вверх", у psycopg2 возникают проблемы с подключением.
docker-compose -f local.yml up
журнал командной строки:
[+] Running 2/2
- Container postgres Created 0.0s
- Container django Recreated 2.2s
Attaching to django, postgres
postgres |
postgres | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres |
postgres | 2021-09-25 17:45:02.026 UTC [1] LOG: starting PostgreSQL 13.2 (Debian 13.2-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
postgres | 2021-09-25 17:45:02.026 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres | 2021-09-25 17:45:02.026 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres | 2021-09-25 17:45:02.029 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres | 2021-09-25 17:45:02.033 UTC [27] LOG: database system was shut down at 2021-09-25 17:39:48 UTC
postgres | 2021-09-25 17:45:02.037 UTC [1] LOG: database system is ready to accept connections
django | Unable to connect!
django | could not connect to server: Connection refused
django | Is the server running on host "127.0.0.1" and accepting
django | TCP/IP connections on port 5432?
django |
django | Waiting for PostgreSQL to become available...production
Gracefully stopping... (press Ctrl+C again to force)
[+] Running 2/2
- Container django Stopped 10.6s
- Container postgres Stopped 0.5s
canceled
Я заранее установил url базы данных set DATABASE_URL=postgres://postgres:password@127.0.0.1:5432/PDT
.
Я создал базу данных в pgAdmin4 и могу перенести изменения в нее без проблем.
(Env) C:pathreplacement/>python manage.py makemigrations
Migrations for 'customer_app':
customer_app\migrations\0001_initial.py
- Create model company
- Create model user
(Env) C:pathreplacement/>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, customer_app, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying customer_app.0001_initial... OK
Applying sessions.0001_initial... OK
вот файл, отвечающий за подключение к базе данных и сообщение об этой проблеме.
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
if [ -z "${POSTGRES_USER}" ]; then
base_postgres_image_default_user='postgres'
export POSTGRES_USER="${base_postgres_image_default_user}"
fi
export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
postgres_ready() {
python << END
import sys
import psycopg2
try:
psycopg2.connect(
dbname="${POSTGRES_DB}",
user="${POSTGRES_USER}",
password="${POSTGRES_PASSWORD}",
host="${POSTGRES_HOST}",
port="${POSTGRES_PORT}",
)
except psycopg2.OperationalError as e:
print('Unable to connect!\n', e)
sys.exit(-1)
sys.exit(0)
END
}
until postgres_ready; do
>&2 echo 'Waiting for PostgreSQL to become available...production'
# echo ${POSTGRES_USER}
# echo ${POSTGRES_PASSWORD}
# echo ${POSTGRES_HOST}
# echo ${POSTGRES_PORT}
# echo ${POSTGRES_DB}
sleep 1
done
>&2 echo 'PostgreSQL is available'
exec "$@"
Я запустил другой проект django, чтобы убедиться, что я правильно использую psycopg2, и у меня не было проблем с подключением, запросами и вставкой в базу данных. Я не уверен, чего мне не хватает. Любая помощь будет очень признательна. Задавайте любые вопросы, которые вам нравятся.
После просмотра ваших журналов,
Is the server running on host "127.0.0.1" and accepting
Не удается найти хост.
Ваш контейнер postgres запущен, но строка подключения DATABASE_URL
кажется неправильной, Когда вы создаете образ postgres docker внутри файла docker-compose, попробуйте создать DATABASE_URL
в переменной окружения контейнера django следующее:
Примечание: Соблюдайте правильные отступы в yml
// DB_USER
// DB_PASSWORD
// DB_NAME
// these are the variables you probably specifying in "env_file:" as said in the tutorial link you follwing.
// postgres_service_name
// this is the service name that you specify in docker-compose.yml file same like you see in the tutorial link "postgres", "django" or "doc" so in your case its probably "postgres".
environment:
DATABASE_URL: postgres://DB_USER:DB_PASSWORD@postgres_service_name:5432/DB_NAME
Когда вы используете имя сервиса в качестве хоста, вы указываете ему подключиться к хосту postgres, запущенному внутри другого сервиса docker.
Когда вы не уверены, запущен ли ваш контейнер docker или нет, просто проверьте, выполнив следующую команду в терминале, она выведет список всех запущенных контейнеров.
docker ps
Другим способом решения проблемы является использование IP контейнера postgres, найдите IP контейнера docker, используя имя или id docker
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id
Теперь вы можете передать IP контейнера как host
часть в вашей DATABSE_URL
строке и, надеюсь, это сработает.