Современная разработка на Django всё чаще происходит в контейнеризированной среде, где Docker и docker-compose становятся стандартом де-факто. Подключение PostgreSQL к Django через docker-compose — это не просто техническая задача, а целая философия разработки, обеспечивающая воспроизводимость, изоляцию и масштабируемость вашего приложения. В этом руководстве мы разберём каждый шаг — от базовой настройки до продвинутых практик, которые превратят вашу локальную разработку в профессиональный процесс.
Почему именно Docker-compose для Django и PostgreSQL?
Docker-compose позволяет описывать многоконтейнерные приложения в одном YAML-файле. Для Django-проекта это означает, что вы можете одновременно запускать: контейнер с вашим приложением, контейнер с PostgreSQL, а при необходимости — дополнительные сервисы вроде Redis, Celery или Nginx. Все они будут общаться через изолированную сеть, иметь общие тома для данных и запускаться одной командой.
Главное преимущество — идентичность окружений. То, что работает на вашем ноутбуке, гарантированно заработает на сервере коллеги или в production-среде. Больше не будет проблем с версиями Python, PostgreSQL или системными библиотеками.
Структура проекта и базовый docker-compose.yml
Начнём с типичной структуры проекта:
- your_project/
- ├── Dockerfile (для Django-приложения)
- ├── docker-compose.yml
- ├── requirements.txt
- └── src/ (ваш Django-проект)
Содержимое docker-compose.yml
Создайте файл docker-compose.yml в корне проекта:
version: '3.8'
services:
db:
image: postgres:15-alpine
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=django_user
- POSTGRES_PASSWORD=strong_password
- POSTGRES_DB=django_db
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U django_user"]
interval: 10s
timeout: 5s
retries: 5
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- ./src:/app
ports:
- "8000:8000"
depends_on:
db:
condition: service_healthy
environment:
- DATABASE_URL=postgres://django_user:strong_password@db:5432/django_db
volumes:
postgres_data:
Настройка Django для работы с PostgreSQL в контейнере
Ключевой момент — правильная конфигурация settings.py. Вместо хардкода параметров используем переменные окружения:
import os
from pathlib import Path
import dj_database_url
# Чтение DATABASE_URL из переменных окружения
database_url = os.environ.get('DATABASE_URL')
DATABASES = {
'default': dj_database_url.parse(database_url) if database_url else {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('POSTGRES_DB', 'django_db'),
'USER': os.environ.get('POSTGRES_USER', 'django_user'),
'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'strong_password'),
'HOST': os.environ.get('POSTGRES_HOST', 'db'), # 'db' — имя сервиса в compose
'PORT': os.environ.get('POSTGRES_PORT', 5432),
}
}
Обратите внимание на HOST: 'db'. В Docker-compose сервисы общаются по именам, указанным в файле конфигурации. Имя 'db' разрешается во внутренний IP-адрес контейнера с PostgreSQL.
Dockerfile для Django-приложения
Ваш Dockerfile должен устанавливать зависимости и настраивать приложение:
FROM python:3.11-slim
WORKDIR /app
# Установка зависимостей для PostgreSQL клиента
RUN apt-get update && apt-get install -y \
libpq-dev gcc \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ .
# Рекомендуется использовать gunicorn для production
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "your_project.wsgi"]
Работа с миграциями и статикой
Создайте скрипт entrypoint.sh для автоматического применения миграций при запуске:
#!/bin/bash
# Ждём готовности PostgreSQL
until pg_isready -h db -p 5432; do
echo "Waiting for database..."
sleep 2
done
# Применяем миграции
python manage.py migrate --noinput
# Собираем статику
python manage.py collectstatic --noinput --clear
# Запускаем основной процесс
exec "$@"
И обновите Dockerfile:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
Продвинутые сценарии
Использование .env файла для конфиденциальных данных
Никогда не храните пароли в docker-compose.yml! Создайте .env файл:
POSTGRES_PASSWORD=your_strong_password_here
POSTGRES_USER=django_user
POSTGRES_DB=django_db
SECRET_KEY=django-secret-key
И обновите docker-compose.yml:
db:
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
env_file:
- .env
Добавление pgAdmin для управления БД
Добавьте в docker-compose.yml:
pgadmin:
image: dpage/pgadmin4
environment:
- PGADMIN_DEFAULT_EMAIL=admin@admin.com
- PGADMIN_DEFAULT_PASSWORD=admin
ports:
- "5050:80"
depends_on:
- db
FAQ: Часто задаваемые вопросы
Как подключиться к PostgreSQL извне Docker?
Используйте localhost:5432 с теми же credentials, что указаны в environment. Убедитесь, что порт проброшен (ports: "5432:5432").
Данные PostgreSQL пропадают после остановки контейнеров?
Используйте volumes (как в нашем примере). Данные будут храниться в томе postgres_data, который сохраняется между перезапусками. Для полного удаления используйте docker-compose down -v.
Как выполнить manage.py команды?
Используйте docker-compose exec web python manage.py migrate или создайте отдельный сервис для management-команд.
Проект работает медленно на macOS/Windows?
Используйте cached volumes и настройте ресурсы Docker Desktop. Для Linux-хостов проблем с производительностью обычно нет.
Как обновить версию PostgreSQL?
Измените тег образа (например, на postgres:16-alpine), создайте дамп, обновите и восстановите данные. Всегда тестируйте на staging-окружении!