Знакомая история: нужно завернуть проект в контейнер, лезешь в интернет за Dockerfile, копируешь первый похожий - и понеслось. Базовый образ не тот, версия рантайма наугад, всё в один слой, multi-stage забыт. Контейнер то не собирается вовсе, то собирается, но весит лишние полгигабайта компиляторами и dev-зависимостями, которые в проде не нужны.
Generic-Dockerfile из интернета почти всегда не про твой проект. Он не знает, на каком ты языке, какие у тебя зависимости и где точка входа. Он знает абстрактный “Node-проект” или “Python-сервис вообще” - а у тебя конкретный репозиторий с конкретной версией в package.json и своим портом. Отсюда и боль: правишь чужой шаблон под себя руками, гадаешь, почему слой такой жирный, и заново гуглишь, как сделать кеш зависимостей.
А ведь рутина железно повторяемая: посмотреть стек, выбрать правильный базовый образ, разнести сборку и рантайм по стадиям, не сбрасывать кеш на каждой правке. Ровно та работа, которую стоит один раз описать и отдать ассистенту.
В чём идея
Скил - это короткая инструкция для ИИ-ассистента: как называется, когда применять и что сделать. Ассистент читает её сам и, когда твоя просьба попадает под описание (“сделай Dockerfile”, “заверни в контейнер”, “образ слишком большой”), подхватывает скил без напоминаний.
Но фокус этого урока не в самом факте скила, а в ПРИЁМЕ. Слабый скил выдаёт шаблон: “вот тебе типовой Dockerfile”. Сильный скил сначала ЧИТАЕТ твой проект, а уже потом пишет вывод под него. Это и есть разница между “контекстно-слепым” и “контекстно-осознанным” (docker-aware) поведением.
Первым шагом скил не угадывает, а смотрит на файлы-маркеры: package.json - значит Node, и версию берём из engines; pyproject.toml или requirements.txt - Python; go.mod - Go; pom.xml - JVM; Cargo.toml - Rust. Находит точку входа и порт, который слушает приложение. И только теперь, зная реальный стек, выбирает базовый образ под нужную версию рантайма и пишет multi-stage Dockerfile: стадия сборки отдельно от стадии запуска, в финальный образ едет только артефакт и прод-зависимости. Плюс мелочи, на которых обычно спотыкаются: слой зависимостей ставится ДО копирования исходников (иначе кеш сбрасывается на каждой правке кода), добавляется .dockerignore, непривилегированный пользователь и реальный порт в EXPOSE.
Почему это взлетает? Потому что современная LLM прекрасно читает код и отлично знает best practices Docker. Ей не хватало одного - дисциплины порядка: сперва изучи проект, потом пиши. Скил ровно это и закрепляет: “не выдавай шаблон, пока не понял стек”.
Отдельная честная оговорка для РФ. Сам Docker универсален, но базовые образы из Docker Hub у нас тянутся нестабильно. Это не ломает приём: скил пишет ванильный FROM, а подмену реестра на зеркало или приватный (например, реестр Cloud.ru) выносим в один параметр. Логика сборки от этого не меняется - меняется только источник образа.
Как себе сделать
Не пиши Dockerfile руками и не подгоняй чужой шаблон. Отдай задачу своему ассистенту - Claude Code, Codex, Cursor, Gemini, любому. Он сам прочитает проект и соберёт образ под него. Просто скопируй промпт:
Создай мне скил, который заворачивает проект в Docker, но сначала ЧИТАЕТ репозиторий, а не выдаёт шаблон.
Срабатывай на просьбы вроде "сделай Dockerfile", "заверни проект в контейнер", "образ слишком большой", "контейнер не собирается".
Первым делом определи стек по файлам-маркерам (package.json, pyproject.toml, requirements.txt, go.mod, pom.xml, Cargo.toml), найди точку входа и порт - не угадывай.
Базовый образ выбирай под версию рантайма из проекта (slim или alpine, не latest), пиши multi-stage Dockerfile: стадия build отдельно от runtime, слой зависимостей до копирования исходников ради кеша, плюс .dockerignore и непривилегированный пользователь.
Если сервисов несколько или нужна база - собери docker-compose.yml. Для РФ подмену реестра у FROM на зеркало или приватный реестр оставь одним параметром.
По запросу подними сборку и почини ошибки до зелёной.
Как понять, что заработало: открой любой свой проект и напиши ассистенту по-человечески “заверни этот проект в контейнер”. Если он сам, без подсказок, сначала назовёт твой стек и версию (например “Node 20, точка входа server.js”), а потом отдаст multi-stage Dockerfile под него - приём поймался, скил живой. Сравни размер с тем, что давал старый шаблон: разница обычно в разы.
И всё. Завернуть проект в контейнер - это больше не “найди шаблон и помучайся”. Один раз описал приём - дальше ассистент сам читает репозиторий и пишет образ под конкретный стек.
Смотреть полностью
- VK Видео: https://vk.com/video-233222565_456239066
Коротко
- VK Клипы: https://vk.com/clip-233222565_456239067
- Telegram: https://t.me/chernovdev/2141
