Связываем 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.