Представьте: вы написали программу. На вашем компьютере всё работает идеально. Вы отправляете код коллеге. Он скачивает, запускает — и получает:

ModuleNotFoundError: No module named 'flask'
Error: connect ECONNREFUSED 127.0.0.1:5432
python3: command not found

Три ошибки. Ни одна не связана с вашим кодом — он правильный. Проблема в другом: у коллеги не установлен Flask, нет базы данных, а Python называется python, а не python3. Его компьютер — это другая планета с другой атмосферой. Ваше приложение там задыхается.

«У меня на машине работает!» — самая бесполезная фраза в истории разработки.

Docker создан, чтобы эта фраза потеряла смысл. Он упаковывает приложение вместе со всем, что ему нужно — код, зависимости, настройки, нужную версию языка — в одну «коробку». Эта коробка запустится одинаково на любом компьютере: вашем ноутбуке, ноутбуке коллеги, тестовом сервере, облаке Amazon.

Эта «коробка» называется контейнер.

Аналогия из жизни. Вы заказываете еду с доставкой. Курьер привозит не просто котлету — а контейнер с готовым блюдом: котлета, гарнир, соус, приборы, салфетка. Вам не нужно иметь дома плиту, сковородку и рецепт. Открываете контейнер — и едите. Docker работает так же: контейнер приезжает на сервер со всем необходимым, и серверу не нужно ничего доустанавливать. Чтобы не изучать Docker на абстрактных примерах, мы будем строить реальный проект — постепенно, от урока к уроку. Знакомьтесь: TaskMaster — консольный менеджер задач на Python.

Вот как он работает:

$ python taskmaster.py add "Купить молоко"
Добавлено: Купить молоко

$ python taskmaster.py add "Написать отчёт"
Добавлено: Написать отчёт

$ python taskmaster.py list
  [ ] 1. Купить молоко
  [ ] 2. Написать отчёт

$ python taskmaster.py done 1
Задача 1 выполнена!

$ python taskmaster.py list
  [x] 1. Купить молоко
  [ ] 2. Написать отчёт

$ python taskmaster.py stats
Всего: 2, выполнено: 1, осталось: 1

Простой и понятный. Четыре команды: add, list, done, stats. Задачи хранятся в JSON-файле. Никаких фреймворков, никаких баз данных — чистый Python, 40 строк кода.

А вот и сам код:

import json, sys, os
from datetime import datetime

DATA_FILE = os.environ.get("TASKS_FILE", "tasks.json")

def load():
    try:
        with open(DATA_FILE) as f:
            return json.load(f)
    except FileNotFoundError:
        return []

def save(tasks):
    with open(DATA_FILE, "w") as f:
        json.dump(tasks, f, indent=2, ensure_ascii=False)

def main():
    if len(sys.argv) < 2:
        print("TaskMaster — менеджер задач")
        print("Команды: add  | list | done  | stats")
        return

    cmd = sys.argv[1]
    tasks = load()

    if cmd == "add" and len(sys.argv) > 2:
        text = " ".join(sys.argv[2:])
        tasks.append({"text": text, "done": False, "created": datetime.now().isoformat()})
        save(tasks)
        print(f"Добавлено: {text}")
    elif cmd == "list":
        if not tasks:
            print("Задач нет.")
        for i, t in enumerate(tasks, 1):
            mark = "[x]" if t["done"] else "[ ]"
            print(f"  {mark} {i}. {t['text']}")
    elif cmd == "done" and len(sys.argv) > 2:
        n = int(sys.argv[2])
        tasks[n - 1]["done"] = True
        save(tasks)
        print(f"Задача {n} выполнена!")
    elif cmd == "stats":
        total = len(tasks)
        done = sum(1 for t in tasks if t["done"])
        print(f"Всего: {total}, выполнено: {done}, осталось: {total - done}")

if __name__ == "__main__":
    main()

Сохраните этот код в файл taskmaster.py — он нам понадобится уже через пару уроков. На протяжении курса мы будем развивать TaskMaster: сначала запустим его в контейнере, потом напишем Dockerfile, подключим базу данных, настроим Docker Compose, задеплоим на сервер. Каждая новая тема Docker — новая возможность для нашего приложения.

Теперь давайте посмотрим, почему TaskMaster — идеальный пример «проблемы окружений».

Вы написали этот скрипт на своём компьютере с Python 3.11. Всё работает. Отправили коллеге. А у коллеги:

Сценарий 1: Python не установлен вообще. python: command not found. Нужно скачать, установить, настроить PATH. Полчаса.

Сценарий 2: Python установлен, но версия 3.7. F-строки (f"Добавлено: {text}") работают, но вы использовали фичу из 3.9 — и код падает с загадочной ошибкой.

Сценарий 3: На Windows Python называется py, на macOS — python3, на Linux — где как. Скрипт запуска не универсален.

А теперь представьте, что в проекте не 40 строк, а 40 000. Не чистый Python, а Flask + SQLAlchemy + Redis + Celery + десяток других библиотек конкретных версий. У коллеги другая ОС, другие системные библиотеки, другая кодировка по умолчанию. Каждое различие — потенциальная ошибка, а различий — десятки.

Docker решает это радикально: вместо инструкции «установи Python 3.11, потом pip install, потом...» вы говорите:

docker run taskmaster add "Купить молоко"

Одна команда. Python нужной версии, все зависимости, правильная кодировка — всё уже внутри контейнера. Коллеге не нужно ничего устанавливать, кроме самого Docker. Docker — не только про «запустить у коллеги». Вот ситуации, в которых вы окажетесь рано или поздно:

Пятница, 18:00. Нужно выкатить новую версию на сервер. Без Docker — вы заходите по SSH, обновляете код, ставите зависимости, правите конфиги, перезапускаете, проверяете... и понимаете, что на сервере другая версия библиотеки. Час убит. С Docker — одна команда, и новая версия работает. Потому что сервер запускает тот же контейнер, что и ваш ноутбук.

У вас два проекта: один на Python 3.9, другой на Python 3.11. Без Docker они конфликтуют — на компьютере может быть только один системный Python. С Docker каждый проект живёт в своём контейнере и не знает о существовании другого.

TaskMaster разрастётся: приложение, база данных, кэш, веб-сервер — четыре компонента, которые должны работать вместе. Docker Compose позволит описать их в одном файле и поднять одной командой. Мы дойдём до этого ближе к середине курса.

Docker решает проблему «у меня на машине работает» — упаковывает приложение со всеми зависимостями в контейнер, который работает одинаково везде.

Контейнер — изолированная среда с приложением и всем необходимым: кодом, библиотеками, настройками, нужной версией языка.

TaskMaster — наш сквозной проект на весь курс: консольный менеджер задач на Python. Начинаем с простого скрипта (40 строк), постепенно упаковываем в Docker, подключаем базу данных, настраиваем Compose, деплоим на сервер.

Типичные сценарии Docker: единое окружение для команды, изоляция проектов, развёртывание на серверах, CI/CD, микросервисы.

Обсуждение урока

0
Комментарии видны всем. Чтобы участвовать в обсуждении, войдите или зарегистрируйтесь.
Модерация сообщества

Пожаловаться на комментарий

Расскажите модераторам, что именно требует внимания.