Как связать Django и PostgreSQL в Docker контейнерах

Как связать Django и PostgreSQL в Docker контейнерах

Связываем Django и PostgreSQL в Docker через Docker Compose

Введение

Контейнеризация стала стандартом для локальной разработки и продакшена. Чтобы связать django и postgresql в докере, достаточно правильно настроить сетевое взаимодействие и переменные окружения. Данный подход исключает конфликты версий, изолирует зависимости и ускоряет деплой. В статье разберём практическую реализацию через docker compose, которая упрощает управление мультиконтейнерными приложениями и обеспечивает воспроизводимость среды.

Файловая структура и Dockerfile

Создайте проект с минимальной структурой: requirements.txt, manage.py и Dockerfile. Для django оптимизируем базовый образ, используя slim-версию Python. Это снизит размер контейнера, время сборки и поверхность атаки.

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

Конфигурация Docker Compose

Определим два сервиса: веб-приложение и базу данных. postgresql запустится в изолированном контейнере с сохранением данных через volume. Сеть создаётся автоматически, поэтому обращение к БД происходит по имени сервиса, а не по localhost.

version: '3.9'
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DB_NAME=devdb
      - DB_USER=devuser
      - DB_PASSWORD=devpass
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      - POSTGRES_DB=${DB_NAME}
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:

Настройка settings.py

Для подключения к БД используем переменные окружения. Это безопаснее хардкода и соответствует принципам 12-Factor. В коде django настройки выглядят так:

import os
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.getenv('DB_NAME'),
        'USER': os.getenv('DB_USER'),
        'PASSWORD': os.getenv('DB_PASSWORD'),
        'HOST': 'db',
        'PORT': '5432',
    }
}

Параметры подключения

Параметр Значение в Docker Назначение
ENGINE django.db.backends.postgresql Драйвер подключения
HOST db Имя сервиса в сети compose
PORT 5432 Стандартный порт PostgreSQL
USER/PASSWORD из переменных окружения Аутентификация

Для production рекомендуется добавить healthcheck к сервису db и использовать gunicorn вместо runserver. Также стоит настроить PG_HBA.conf для ограничения доступа по сети и включить логирование запросов через переменную POSTGRES_LOG_STATEMENT.

Запуск и проверка

Выполните docker compose up —build. После старта контейнеров примените миграции: docker compose exec web python manage.py migrate. Приложение готово к работе по адресу localhost:8000. Данные БД сохраняются в именованном томе, что гарантирует их целостность при перезапуске контейнеров.

Вопрос-ответ (FAQ)

Почему не стоит использовать SQLite в продакшене?

SQLite не поддерживает конкурентный доступ на запись, не масштабируется и блокирует файл при одновременных запросах. PostgreSQL обеспечивает ACID-транзакции, конкурентность и надёжность для production-сред.

Как сбросить базу данных при разработке?

Удалите именованный том командой docker compose down -v, затем выполните миграции заново. Это полностью очистит данные и вернёт схему к начальному состоянию.

Что делать, если контейнер web не видит db?

Проверьте поле depends_on, имя хоста в settings.py (должно совпадать с ключом сервиса в compose.yml) и убедитесь, что оба контейнера находятся в одной пользовательской сети. Ошибки подключения часто связаны с таймаутами ожидания готовности БД.

Comments are closed.