
Привет, Хабр! В этой статье мы запустим 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
