
Привет, Хабр! В этой статье мы запустим Docker с Django на локальной машине. Этот материал ориентирован исключительно на локальную разработку — наш Django будет работать с SQLite без использования образов PostgreSQL. Уже в следующей статье мы соберем более сложное приложение. Все действия будем выполнять в Windows, так как большинство начинающих разработчиков используют именно эту операционную систему. Перед началом работы убедитесь, что у вас установлен и настроен Docker Desktop для Windows. В сети много руководств по его установке, поэтому думаю, что с этим не возникнет проблем. Мы будем использовать Django 5.2.6 и Docker Desktop 28.4.0. Весь проект доступен на GitHub. Если материал оказался полезным, буду благодарен за звёзды в репозитории. Первым делом создадим приложение, для которого будем собирать образ:
pip install django==5.2.6
django-admin startproject app
cd startproject/
python manage.py runserver
Перейдем по url - http://127.0.0.1:8000/

Мы создали приложение Django, теперь сделаем простое приложение в нем и выведем - hello habr:
python manage.py startapp test_app
Теперь добавим приложение и сделаем самую простой views на FBV.
# app/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('test_app.urls')), # Добавляем наше test_app приложение
]
# app/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'test_app', # Наше приложение
]
# test_app/views.py
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("<h1>hello habr!<h1>") # вывод на нашу HTML страницу.
Создаем urls.py в test_app/ и вставляем данный код:
# test_app/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
Теперь повторно запускаем проект и видим:

По итогу у вас должен получится вот такой проект:

Теперь к Docker'у. Но перед этим важно понять для чего он нужен. Если вы только начинаете свой путь в веб-разработке, закономерный вопрос: "Зачем усложнять себе жизнь Docker'ом, если Django и так отлично работает?". Давайте разберемся на практических примерах. По моему мнению если хочешь что-то объяснить, то покажи на понятном примере.
Представьте ситуацию: - Вы написали крутое приложение на Django 5.2.6 с Python 3.11 - Ваш друг хочет помочь с разработкой, но у него стоит Python 3.8 - При запуске возникают ошибки совместимости - Вы тратите день на настройку окружения вместо программирования
Почему Docker, а не встроенный venv? Хороший вопрос. В Python есть встроенный инструмент venv для виртуальных окружений. Зачем тогда нужен Docker? Давайте вернемся обратно к примерам.
venv это как отдельная комната в доме:
- У вас есть изоляция для Python-пакетов
- Можно иметь разные версии Django для разных проектов - Не конфликтуют зависимости между проектами
На бумажке всё звучит очень хорошо. И будто Docker ваш и не нужен. Уже задумались и без него об этом в Python. Сделав такой прекрасный инструмент, как venv. Но не всё так просто, как кажется. Но не стоит кое что забывать. А как насчет версии Python? Системные библиотеки? Базы данных? Внешние сервисы (Redis, Celery)?
Если вы частенько любите обновлять Windows или пишите на нескольких устройствах. Вы встречались с этой проблемой и прекрасно понимаете всю эту боль. Клонируешь репозиторий на новое устройство и при запуске приложения видите, что библиотека не установлена, другая старой версии, у третей с четвертой несовместимость версий.
Надеюсь! Понимание у вас появилось для чего все компании просят Docker. И мы можем приступить к созданию первого Dockerfile. Расположение у него будет в корне.

Но перед заполнением первого Dockerfile. Выполним данную команду, которая собирает все библиотеки, которые установлены на вашем устройстве, окружение.
pip freeze > requirements.txt
# Мой пример requirements.txt
asgiref==3.9.1
Django==5.2.6
sqlparse==0.5.3
tzdata==2025.2
Теперь заполним Dockerfile:
# Dockerfile
# Берем готовую основу: Python 3.11 на упрощенной системе Linux
FROM python:3.11-slim-bookworm
# Говорим Python не создавать временные файлы (.pyc) - чтобы не захламлять контейнер
ENV PYTHONDONTWRITEBYTECODE 1
# Говорим Python сразу показывать все сообщения в консоли (без задержек)
ENV PYTHONUNBUFFERED 1
# Создаем папку /app внутри контейнера и переходим в нее
# Это как создать рабочую папку на новом компьютере
WORKDIR /app
# Копируем файл с зависимостями (список что нужно установить)
COPY requirements.txt .
# Устанавливаем все нужные библиотеки из requirements.txt
# Флаг --no-cache-dir говорит не сохранять временные файлы установки
RUN pip install --no-cache-dir -r requirements.txt
# Копируем ВСЕ файлы из нашей текущей папки в папку /app контейнера
COPY . .
# Сообщаем что наше приложение будет работать на порту 8000
EXPOSE 8000
# Самая главная команда - что запускать когда контейнер стартует
# Запускаем Django-сервер так, чтобы он был доступен снаружи
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
После этого выполним команды:
# Эта команда читает Dockerfile и создает образ
docker build -t django_docker .
# Стартуем!!!
docker run -p 8000:8000 django_docker
Мы запустили первое приложение с помощью Docker'a! Оно доступно по http://127.0.0.1:8000/
Теперь посмотрим в Docker Desktop:


Можете не пугаться, если увидите в containers другое имя. Docker сам их придумывает, если мы не указываем их явно. Проект запущен в Docker. Неужели это так просто? Было бы так, если современные приложения были такими маленькими и без всяких nginx, PostgreSQL, React. Для них нужны точно такие же Dockerfile. Но не в ручную же каждый запускать? Конечно это можно сделать, но будет ли такой подход удобный.
Судя приходит Docker Compose, который решает эту проблему. Если Dockerfile - это инструкция по сборке одного компьютера, то Docker Compose - это пульт управления целым компьютерным классом.
Создадим его в корне нашего проекта:

Теперь заполним содержимым данный файл:
services:
# Создаем сервис с названием - backend
backend:
# Даем понятное имя контейнеру - django_app
container_name: django_app
# Собираем образ из Dockerfile. Выше мы уже выполняли эту команду)
build:
context: . # указываем путь где лежит этот Dockerfile. У меня в корне.
dockerfile: Dockerfile # Используем инструкции из файла Dockerfile
# Иногда названия могут быть другие, например Dockerfile.prod - для продакшена
# запускаем наш проект, как все собрали
command: python manage.py runserver 0.0.0.0:8000
# Синхронизируем папки: связываем текущую папку на компьютере с папкой /app в контейнере
volumes:
- .:/app
# Указываем рабочую папку внутри контейнера (где лежит наш код)
working_dir: /app
# Открываем порт 8000: связываем порт твоего компьютера с портом контейнера
ports:
- "8000:8000"
А теперь стартуем!
docker-compose up --build
А что такое volumes? Представьте, что контейнер Docker - это отдельный компьютер, а volumes - это общая папка между вашим реальным компьютером и этим виртуальным. На практике без volumes. Мы копируем при старте папку, а в дальнейшем без обновления сборки - код не обновляется. Мы находимся в том же состояние кода, который был при сборки. Но благодаря такой технологии - мы обновляем проект в реальном времени. Все изменения кода - сразу обновляются.
Я надеюсь, что Docker не показался тебе чем-то ненужным или совершенно непонятным. Объяснить даже базовую работу с Docker в одной статье - очень сложно, поэтому в первой части мы разобрали простую конструкцию, но уже начали закладывать фундамент. Если тебе что-то непонятно - это нормально. Главное - не сдаваться и продолжать изучать. Не существует человека, который бы понимал всё сразу.
Все исходники проекта: Github
Комментарии (6)
danilovmy
06.10.2025 16:39а зачем нужны requirements.txt ?
Можно же сразу в докер файл писать.
swcasimiro Автор
06.10.2025 16:39А зачем усложнять Dockerfile? А если библиотек будет под 20? Вместо лаконичной строчки, будет огромный ад из 20 библиотек. Ну если нравится такой подход, то окей. Ну я особого преимущества лично не вижу в твоем варианте. Да и для примера, как мне кажется в этой статье. Такой вариант был бы куда проще для восприятия.
shqiptar
06.10.2025 16:39Вы тратите день на настройку окружения вместо программирования
чегооооооо??? установил новую версию питона в отдельную папку, в проекте сделал венв python -m venv .venv активировал .venv\scripts\activate. всё.
объяснение докера в статье - не люблю такое выражение,но чувак - учи матчасть. смотри не скажи такое на собеседовании.pip freeze > requirements.txt
uv? не, не слышал
Мы будем использовать Django 5.2.6
задачки на подумать.
1) что будет если использовать django select2 для выборки и таблицы с 20-30 тыс записей? а про подавление некоторых исключений в классах я вообще молчу.
2) сколько предложений о работе на джанге и колько на фастапи?
ky0
Плохой Докерфайл - несколько слоёв будет пересоздаваться при каждом изменении кода. Сначала копируете requirements, устанавливаете их - и только потом
COPY . .
, тогда первые два останутся закэшированными, пока не решите что-то изменить в зависимостях.swcasimiro Автор
@ky0, привет. Благодарю за критику, исправил. Писал от руки, если есть еще замечания, то буду рад выслушать.