Poetry и uv — управление зависимостями Python
Классическая связка venv + pip + requirements.txt описана в зависимостях Python. Она работает для коротких скриптов, но в командных проектах быстро упирается в ограничения:
- версии вроде
requests>=2.31задают диапазон, а не точный граф всех транзитивных пакетов; - метаданные проекта (имя, версия, точка входа) часто живут отдельно от зависимостей;
- на разных машинах и в CI дерево пакетов может разойтись, хотя
requirements.txtодин и тот же.
Poetry и uv решают это через единый pyproject.toml и lock-файл — снимок всех версий, который воспроизводит окружение один в один.
| Инструмент | Автор | Особенность |
|---|---|---|
| Poetry | Сообщество Python Packaging | Зрелый UX, poetry add, публикация на PyPI |
| uv | Astral (создатели Ruff) | Очень быстрый install/lock/sync, совместим с pip workflow |
Практикум идёт по шагам — от понимания pyproject.toml до Poetry, uv, CI и типичных ошибок.
| Шаг | Тема | Зачем |
|---|---|---|
| 1 | pyproject.toml и PEP 621 | Единый манифест проекта |
| 2 | Lock-файл | Воспроизводимые сборки |
| 3 | Poetry — установка и команды | Классический workflow |
| 4 | uv — установка и команды | Скорость и современный CLI |
| 5 | Миграция с requirements | Перенос учебного проекта |
| 6 | CI и git | Что коммитить |
| 7 | Выбор инструмента | Когда достаточно pip |
| Материал | Зачем |
|---|---|
| Зависимости Python — pip | Базовый pip и requirements |
| Виртуальные окружения | Зачем изолировать .venv |
| Манифесты в проекте | Теория lock и SemVer |
| Python для ML | Тяжёлые пакеты через uv add |
Общая теория конфигураций — конфигурации и данные.
Команды удобно выполнять во вкладке Терминал VS Code (Ctrl+`). Укажите интерпретатор из .venv проекта — иначе IDE не увидит установленные пакеты.
Шаг 1 — базовый pyproject.toml
Оба инструмента опираются на стандарт PEP 621 — секция [project] в TOML-файле.
[project]
name = "demo-app"
version = "0.1.0"
description = "Учебный проект"
requires-python = ">=3.11"
dependencies = [
"requests>=2.31.0",
]
[project.scripts]
demo = "demo_app.cli:main"
Разбор:
[project]— имя, версия, минимальный Python, прямые зависимости.requires-python— Poetry и uv откажутся ставить пакет на слишком старый интерпретатор.dependencies— то, что раньше писали вrequirements.txt, но декларативно.[project.scripts]— консольная командаdemoпослеpip install/poetry installпакета в editable-режиме.
Структура каталога для библиотеки:
demo-app/
pyproject.toml
demo_app/
__init__.py
cli.py
tests/
test_cli.py
| Поле | Смысл |
|---|---|
name | Имя на PyPI (если публикуете) |
version | SemVer — 1.0.0, 0.1.0 |
description | Краткое описание для PyPI |
requires-python | Минимальная версия Python |
dependencies | Прямые runtime-зависимости |
Шаг 2 — зачем нужен lock-файл
pyproject.toml говорит: "мне подходит requests>=2.31". При установке pip или Poetry разрешает весь граф — requests тянет urllib3, certifi, charset-normalizer и т.д. Без lock разные дни установки могут дать разные минорные версии транзитивных пакетов.
Lock-файл фиксирует точные версии каждого пакета в графе:
| Файл | Инструмент | Коммитить? |
|---|---|---|
poetry.lock | Poetry | Да |
uv.lock | uv | Да |
Команда poetry lock или uv lock пересчитывает lock после изменения pyproject.toml. В CI используют --frozen / --no-update, чтобы не менять lock на лету.
Lock помогает воспроизводимости и аудиту: при обновлении зависимостей diff lock-файла показывает, какие транзитивные пакеты изменились. Для prod-сервисов периодически обновляйте lock и прогоняйте тесты.
Шаг 3 — Poetry пошагово
Установка Poetry
Не ставьте Poetry в системный Python на Linux с PEP 668 — получите externally-managed-environment. Варианты:
# Официальный installer (рекомендуется)
curl -sSL https://install.python-poetry.org | python3 -
# или pipx (изолированно)
pipx install poetry
Проверка:
poetry --version
Документация: python-poetry.org.
Новый проект
poetry new demo-app
cd demo-app
poetry add httpx pydantic
Poetry создаёт:
demo-app/
pyproject.toml
poetry.lock
demo_app/
__init__.py
tests/
__init__.py
test_demo_app.py
README.md
Секция [tool.poetry] в pyproject.toml добавляется автоматически — Poetry расширяет PEP 621 своими полями (группы dev, build backend).
Основные команды
poetry install # venv + все deps из lock
poetry run python -m demo_app
poetry add pytest --group dev
poetry add "django>=5.0,<6"
poetry shell # активировать venv Poetry (устаревающий способ)
poetry env info # путь к .venv
| Команда | Действие |
|---|---|
poetry add flask | Добавить зависимость, обновить lock |
poetry remove flask | Удалить из toml и lock |
poetry update | Обновить все пакеты в рамках ограничений |
poetry lock | Пересчитать lock без установки |
poetry install --no-root | Только deps, без установки самого пакета (CI) |
poetry run pytest | Запуск в venv Poetry |
Dev-зависимости (тесты, линтеры, mypy) — группа [tool.poetry.group.dev.dependencies] или флаг --group dev. Они не попадают в wheel при публикации на PyPI.
Пример dev-группы
poetry add --group dev pytest ruff mypy
В pyproject.toml появится:
[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
ruff = "^0.8"
Работа внутри venv без poetry shell
Современный подход — явный poetry run:
poetry run python script.py
poetry run uvicorn demo_app.main:app --reload
Или активировать venv вручную — путь покажет poetry env info -p.
Миграция с requirements.txt
cd existing-project
poetry init # интерактивно или --no-interaction
poetry add $(cat requirements.txt)
poetry lock
poetry install
Проверьте poetry.lock, прогоните тесты. Удаляйте requirements.txt только когда CI переведён на poetry install. Для legacy можно оставить requirements.txt, сгенерированный из lock:
poetry export -f requirements.txt --output requirements.txt --without-hashes
Шаг 4 — uv пошагово
uv — менеджер пакетов и интерпретаторов на Rust от Astral (те же авторы, что Ruff). Команды короче, установка и sync значительно быстрее pip.
Установка uv
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# Linux/macOS
curl -LsSf https://astral.sh/uv/install.sh | sh
Проверка:
uv --version
Документация: docs.astral.sh/uv.
Новый проект
uv init demo-uv
cd demo-uv
uv add requests httpx
uv run python main.py
Создаётся pyproject.toml, uv.lock и .venv (часто в .venv/ в корне проекта).
| Команда | Действие |
|---|---|
uv add flask | Добавить зависимость и обновить lock |
uv remove flask | Удалить пакет |
uv sync | Привести venv к lock |
uv sync --frozen | CI — упасть, если lock не совпадает с toml |
uv lock | Пересчитать lock |
uv run pytest | Запуск в venv проекта |
uv python install 3.12 | Скачать интерпретатор |
uv python pin 3.12 | Зафиксировать версию в .python-version |
uv и виртуальное окружение
uv создаёт .venv автоматически при uv sync или uv run. Отдельный python -m venv обычно не нужен — см. виртуальные окружения.
uv venv # явно создать .venv
uv sync # установить deps из lock в .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windows
Dev-зависимости в uv
uv add --dev pytest ruff
В pyproject.toml:
[dependency-groups]
dev = [
"pytest>=8.0",
"ruff>=0.8",
]
Установка только runtime:
uv sync --no-dev
uv pip — совместимость с pip-tools
Если команда привыкла к pip-compile:
uv pip compile pyproject.toml -o requirements.txt
uv pip sync requirements.txt
Это мост между старым и новым workflow без полной миграции.
Миграция с requirements через uv
uv init
uv add -r requirements.txt
uv lock
uv sync
Сравните время uv sync с pip install -r requirements.txt на том же наборе — разница особенно заметна в CI.
Шаг 5 — сравнение workflow
| Задача | pip + requirements | Poetry | uv |
|---|---|---|---|
| Зафиксировать все версии | pip freeze (грубо, без разделения prod/dev) | poetry.lock | uv.lock |
| Добавить пакет | Редактировать txt вручную | poetry add | uv add |
| Установить deps | pip install -r | poetry install | uv sync |
| CI install | pip install -r | poetry install --no-interaction | uv sync --frozen |
| Скорость | Средняя | Средняя | Очень высокая |
| Публикация на PyPI | manual / hatchling | poetry publish | uv publish (развивается) |
| Управление Python | pyenv / системный | poetry env use | uv python install |
| Ситуация | Рекомендация |
|---|---|
| Учебный скрипт на 1 файл | venv + pip (39) |
| Библиотека / приложение в команде | Poetry или uv |
| Монорепо, нужна скорость CI | uv |
| Уже есть Poetry в проекте | Оставить Poetry, пока нет причины мигрировать |
| Смешать Poetry и uv в одном репо | Избегать — один lock-файл на проект |
Шаг 6 — что коммитить в git
| Файл | Коммитить? | Почему |
|---|---|---|
pyproject.toml | Да | Источник правды для зависимостей |
poetry.lock / uv.lock | Да | Воспроизводимость |
.venv/ | Нет | Локальное окружение, тяжёлый каталог |
requirements.txt | Только legacy CI | Иначе удалить после миграции |
.python-version | Да (если есть) | Фиксация версии Python для команды |
Шаблон .gitignore для Python — Git в разработке.
.venv/
__pycache__/
*.pyc
dist/
*.egg-info/
Шаг 7 — пример для CI (GitHub Actions)
Poetry
name: tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install poetry
- run: poetry install --no-interaction --no-root
- run: poetry run pytest
Кэш Poetry ускоряет повторные прогоны:
- uses: actions/cache@v4
with:
path: ~/.cache/pypoetry
key: poetry-${{ runner.os }}-${{ hashFiles('poetry.lock') }}
uv
name: tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync --frozen
- run: uv run pytest
setup-uv сам подтянет Python по requires-python и .python-version.
Типичные ошибки
| Симптом | Причина | Что сделать |
|---|---|---|
externally-managed-environment | Установка в системный Python (PEP 668) | Installer Poetry, pipx или uv |
| Lock out of date | Правили toml без lock | poetry lock / uv lock |
| IDE не видит пакеты | Выбран системный Python | Интерпретатор из .venv |
| Конфlict Poetry + uv | Два lock в одном проекте | Один инструмент на репозиторий |
SolverProblemError | Несовместимые версии deps | Ослабить pin или обновить пакет |
| Медленный CI на pip | Нет кэша wheel | uv или cache action |
ModuleNotFoundError после install | Запуск вне venv | poetry run / uv run |
Практический сценарий — учебный REST-сервис
Соберите мини-проект с FastAPI через uv:
uv init notes-api
cd notes-api
uv add fastapi uvicorn
uv add --dev pytest httpx
pyproject.toml после uv add:
[project]
name = "notes-api"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"fastapi>=0.115",
"uvicorn[standard]>=0.32",
]
Запуск:
uv run uvicorn main:app --reload
Тест с httpx:
uv run pytest
Тот же сценарий на Poetry — poetry add fastapi uvicorn и poetry run uvicorn .... Подробнее про API — FastAPI — первая программа.
Как превратить учебный проект в библиотеку
План эволюции
- Один
pyproject.tomlс[project]и lock. - Структура пакета
src/или flat layout с тестами. - Dev-группа: pytest, ruff, mypy.
- CI на
uv sync --frozenилиpoetry install. - Версионирование SemVer и changelog при публикации.
Базовые поля для PyPI
[project]
name = "my-lib"
version = "0.2.0"
description = "Краткое описание"
readme = "README.md"
license = { text = "MIT" }
authors = [{ name = "Author", email = "a@example.com" }]
Публикация Poetry:
poetry build
poetry publish
Подробный разбор pyproject.toml для Poetry
После poetry init или poetry new в файле появляется секция [tool.poetry]:
[tool.poetry]
name = "demo-app"
version = "0.1.0"
description = ""
authors = ["You <you@example.com>"]
readme = "README.md"
packages = [{ include = "demo_app" }]
[tool.poetry.dependencies]
python = "^3.11"
httpx = ">=0.27,<0.28"
[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
ruff = "^0.8"
| Поле | Смысл |
|---|---|
^3.11 | Совместимо с >=3.11,<4.0 (caret) |
>=0.27,<0.28 | Явный диапазон minor |
packages | Какие каталоги войдут в wheel |
group.dev | Не ставится при --only main |
Команда poetry add "django>=5.0,<6" переписывает toml и lock атомарно — не редактируйте lock вручную.
Editable install
При разработке библиотеки:
poetry install
Poetry ставит пакет в venv в режиме editable — изменения в demo_app/ видны без переустановки.
Экспорт для legacy Docker
poetry export -f requirements.txt --without-hashes -o requirements.txt
poetry export -f requirements.txt --without-hashes --only dev -o requirements-dev.txt
Подробный разбор deps.edn для uv
Минимальный pyproject.toml после uv init:
[project]
name = "demo-uv"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = []
Alias и dev-зависимости в uv:
[dependency-groups]
dev = [
"pytest>=8.0",
"ruff>=0.8",
]
[tool.uv.sources]
my-lib = { path = "../my-lib", editable = true }
| Команда uv | Когда |
|---|---|
uv lock --upgrade-package requests | Обновить один пакет |
uv tree | Показать граф зависимостей |
uv pip list | Список в venv |
uv cache clean | Очистить кэш wheel |
Фиксация версии Python
uv python pin 3.12
Создаёт .python-version — CI и collegues получают ту же версию через uv python install.
Пошаговая миграция учебного проекта
Исходник — каталог с requirements.txt:
legacy-bot/
requirements.txt
bot.py
tests/test_bot.py
Шаг A. Создайте venv backup и snapshot:
pip freeze > freeze-before.txt
Шаг B. Инициализация uv:
cd legacy-bot
uv init --name legacy-bot
uv add -r requirements.txt
uv add --dev pytest
uv lock
Шаг C. Проверка:
uv run pytest
uv run python bot.py --help
Шаг D. Обновите CI и README; удалите requirements.txt после зелёного pipeline.
Шаг E. Добавьте в .gitignore только .venv/, commit uv.lock.
| Этап | Критерий готовности |
|---|---|
| Lock создан | uv.lock в git |
| Тесты | uv run pytest green |
| CI | uv sync --frozen |
| Документация | README с uv sync |
SemVer и ограничения версий
| Запись | Интерпретация (Poetry caret) |
|---|---|
^1.2.3 | >=1.2.3,<2.0.0 |
^0.2.3 | >=0.2.3,<0.3.0 |
~1.2.3 | >=1.2.3,<1.3.0 |
* | Любая (опасно в prod) |
Для приложений (не библиотек) lock важнее широких диапазонов в toml — команда ставит из lock.
Docker с uv
FROM python:3.12-slim
COPY /uv /usr/local/bin/uv
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
COPY . .
CMD ["uv", "run", "uvicorn", "main:app", "--host", "0.0.0.0"]
Слои кэшируются: пока lock не менялся, uv sync берёт wheel из cache.
Docker с Poetry
FROM python:3.12-slim
RUN pip install poetry
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-root --only main
COPY . .
CMD ["poetry", "run", "uvicorn", "main:app", "--host", "0.0.0.0"]
Изоляция инструментов — pipx
Poetry и uv не ставьте в system site-packages на Ubuntu 24.04+:
pipx install poetry
pipx install uv
pipx ensurepath
22 — виртуальные окружения объясняет, почему глобальный pip для библиотек — плохая идея.
Расширенный FAQ
| Вопрос | Ответ |
|---|---|
| Можно ли коммитить и poetry.lock и uv.lock? | Нет, один инструмент |
| Как обновить всё? | poetry update / uv lock --upgrade |
| IDE PyCharm | Settings → Python Interpreter → path to .venv |
| VS Code | Command Palette → Python: Select Interpreter |
| Pre-commit | uv run ruff check в hook |
| Private PyPI | [tool.poetry.source] / [[tool.uv.index]] |
Навигация по блоку Python
- Вы здесь: Poetry и uv
- База pip: 39 — зависимости
- venv: 22 — виртуальные окружения
- ML-стек: 392 — Python для ML
- Тесты: 37 — pytest
Шаг 8 — poetry check и аудит
poetry check
poetry show --tree
poetry show --outdated
| Команда | Зачем |
|---|---|
check | Валидность pyproject |
show --tree | Дерево зависимостей |
show --outdated | Что можно обновить |
uv аналоги:
uv tree
uv pip list --outdated
Шаг 9 — группы зависимостей в Poetry
poetry add --group test pytest pytest-cov
poetry add --group lint ruff mypy
poetry install --with test,lint
Optional groups в [tool.poetry.group.test.optional] — ставятся по запросу.
Шаг 10 — scripts в pyproject
PEP 621 entry points:
[project.scripts]
demo-cli = "demo_app.cli:main"
[project.entry-points."demo.plugins"]
myplugin = "demo_app.plugins:register"
Запуск после install:
uv run demo-cli --help
poetry run demo-cli --help
Шаг 11 — editable path dependency
[tool.uv.sources]
local-lib = { path = "../local-lib", editable = true }
[project]
dependencies = ["local-lib"]
Monorepo: несколько пакетов в одном git с path deps.
Шаг 12 — pre-commit hook
.pre-commit-config.yaml:
repos:
- repo: local
hooks:
- id: ruff
name: ruff
entry: uv run ruff check
language: system
pass_filenames: false
Сравнение lock-форматов
| Аспект | poetry.lock | uv.lock |
|---|---|---|
| Формат | TOML proprietary | TOML uv schema |
| Merge conflicts | частые в busy teams | аналогично |
| Cross-tool | export only | import poetry possible |
Выберите один инструмент — merge lock вручную болезненен.
Учебное упражнение — два окружения
- Склонировать один repo в
poetry-demoиuv-demo. - В poetry-demo:
poetry install, замерить время cold install. - В uv-demo:
uv sync, сравнить. - Изменить одну dev-зависимость — сравнить
lockdiff. - Написать один GitHub Actions job для каждого.
Связанные материалы
| Тема | Материал |
|---|---|
| pip и requirements | 39 — зависимости Python |
| venv | 22 — виртуальные окружения |
| pytest | 37 — тестирование Python |
| ML-стек | 392 — Python для ML |
| CPython и PyPI | 11 — архитектура CPython |
Перенесите учебный проект с requirements.txt на uv init && uv add -r requirements.txt и сравните время uv sync с pip install -r. Зафиксируйте lock в git и прогоните тесты в CI с --frozen.
Для боевых сервисов pin-ьте образ Docker на конкретную версию Python, копируйте lock в образ и используйте uv sync --frozen --no-dev или poetry install --only main. Секреты — только через переменные окружения, не в pyproject.toml.
Второй проход — workspaces и аудит (черновик)
uv workspace (монорепо)
[tool.uv.workspace]
members = ["packages/api", "packages/lib"]
uv sync в корне устанавливает весь граф; path-зависимости между членами workspace — без публикации на PyPI.
Аудит CVE
pip install pip-audit
uv export --frozen | pip-audit -r /dev/stdin
В CI — шаг после uv sync --frozen. Diff lock при обновлении показывает транзитивные уязвимости.
Миграция Poetry → uv (краткий чек-лист)
- Ветка, backup
poetry.lock. uv init, перенос[project]иuv addпоpoetry show.- Тесты и CI на
uv sync --frozen. - Удалить
poetry.lockпосле зелёного pipeline.
Один lock на репозиторий — не смешивать инструменты.
FAQ — полный список
1. Poetry или uv?
Poetry — зрелый UX. uv — скорость CI и install.
2. Можно ли два lock в одном проекте?
Нет — один инструмент на репозиторий.
3. Что коммитить?
pyproject.toml + lock. Не .venv/.
4. externally-managed-environment?
Installer Poetry, pipx или uv — не системный pip.
5. Как добавить dev-зависимость?
Poetry: --group dev. uv: --dev.
6. CI frozen install?
uv sync --frozen или poetry install --no-interaction.
7. Миграция с requirements?
uv add -r requirements.txt или poetry add $(cat requirements.txt).
8. Публикация на PyPI?
poetry publish или uv publish.
9. SemVer в pyproject?
10. venv вручную нужен?
uv/poetry создают .venv автоматически — 22.
11. Как pin Python?
uv python pin 3.12 или .python-version.
12. Docker prod?
uv sync --frozen --no-dev в образе.
13. SolverProblemError?
Ослабить pin или обновить конфликтующий пакет.
14. IDE не видит пакеты?
Интерпретатор из .venv.
15. export requirements?
poetry export -f requirements.txt.
16. FastAPI через uv?
uv add fastapi uvicorn — 3432.
17. ML-стек тяжёлый?
См. 392 — torch через uv add.
Упражнения — расширенный набор
- Перенести requirements.txt на uv init && uv add -r.
- Добавить pytest в dev-группу и CI с --frozen.
- Сравнить время uv sync и pip install.
- Создать notes-api на FastAPI через uv.
- Настроить .python-version и requires-python.
- Dockerfile с uv sync --frozen --no-dev.
- poetry export для legacy CI.
- Добавить ruff и mypy в dev.
- Lock diff при обновлении одного пакета.
- Документировать команды в README.
Практикум — дополнительный блок 1 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 1
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 1"
Практикум — дополнительный блок 2 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 2
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 2"
Практикум — дополнительный блок 3 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 3
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 3"
Практикум — дополнительный блок 4 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 4
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 4"
Практикум — дополнительный блок 5 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 5
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 5"
Практикум — дополнительный блок 6 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 6
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 6"
Практикум — дополнительный блок 7 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 7
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 7"
Практикум — дополнительный блок 8 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 8
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 8"
Практикум — дополнительный блок 9 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 9
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 9"
Практикум — дополнительный блок 10 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 10
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 10"
Практикум — дополнительный блок 11 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 11
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 11"
Практикум — дополнительный блок 12 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 12
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 12"
Практикум — дополнительный блок 13 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 13
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 13"
Практикум — дополнительный блок 14 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 14
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 14"
Практикум — дополнительный блок 15 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 15
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 15"
Практикум — дополнительный блок 16 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 16
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 16"
Практикум — дополнительный блок 17 (391)
| Шаг | Действие | Проверка |
|---|---|---|
| 1 | Повторить базовый сценарий из начала статьи | Команда завершается без ошибок |
| 2 | Запустить тесты или curl smoke | Ожидаемый HTTP-код или green test |
| 3 | Зафиксировать результат в README | Шаги воспроизводимы на другой машине |
Troubleshooting — мини-чеклист 17
| # | Вопрос | Если да |
|---|---|---|
| 1 | Версия runtime совпадает с таблицей требований? | Обновить или зафиксировать в документации |
| 2 | Зависимости установлены из lock-файла? | Переустановить без изменения lock |
| 3 | Порт не занят другим процессом? | Сменить порт или завершить процесс |
| 4 | Переменные окружения заданы? | Проверить .env и секреты на хостинге |
| 5 | Тесты проходят локально? | Только после green — деплой |
# Smoke — адаптируйте под свой стек (391)
echo "Smoke block 17"