Что нужно сделать перед прохождением блока:
- Установить Docker Desktop для своей системы (для Linux необязательно), можно другой движок (OrbStack на MacOS, colima, Rancher Desktop). Для Windows понадобится ещё WSL, но можно делать всё на виртуалке с Linux).
Классический вопрос с собеседования - в чём разница виртуальной машины и контейнера/Docker? Ответ, как всегда, можно посмотреть на Wiki, нас же интересует, как пользоваться Docker.
Всё начинается с написания Dockerfile. Dockerfile - "инструкция" по сборке образа, из которого будет запускаться контейнер. Образ - готовый и упакованный набор ПО, готовый к развёртыванию.
Образ состоит из слоёв. Слой - команда, результат выполнения которой можно переиспользовать, например, результат команды
RUN dotnet build. Не всякая команда создаёт слой (вообще, только четыре команды могут это делать: FROM, RUN, COPY, и ADD).
Все команды можно посмотреть здесь.
У образа может быть базовый образ, с которого начинается сборка (задаётся командой FROM). Это часто бывает удобно, потому что не нужно заново устанавливать всё ПО, необходимое для работы.
Пример базовых образов - mcr.microsoft.com/dotnet/aspnet:8.0 и mcr.microsoft.com/dotnet/sdk:8.0.
Заметим, что название образа (или, по-другому, тег) чаще всего состоит из названия пользователя/организации, названия самого образа и версии. Версия может задаваться в произвольном формате, но всегда она следует после :.
Давай попробуем собрать свой образ!
Для начала добавь в репозиторий файл Dockerfile (это стандартное название файла). Работать будем с текущим проектов WebApp. Теперь нужно сделать следующее:
- Добавить базовый образ (адрес - mcr.microsoft.com/dotnet/aspnet:8.0-alpine);
- Выставить наружу порт приложения (обычно 8080);
- restore Nuget-пакетов (тут уже нужен новый базовый образ, да, их может быть несколько, -- mcr.microsoft.com/dotnet/sdk:8.0);
- Билд для проверки того, что приложение билдится;
- Паблиш приложения (в виде exe либо dll, со вторым будет проще выполнять дальнейшие действия);
- Выставить приложение в качестве entry-point контейнера.
Для первого используй команду FROM, для второго - EXPOSE, для остальных - WORKDIR, RUN и, возможно, COPY. Для последнего пункта - ENTRYPOINT.
Проверь сборку контейнера командой docker build . либо запуском файла в Rider. Если нет ошибок, можно двигаться дальше.
После сборки контейнера скопируй id полученного образа (он будет в логах сборки или в Rider), после чего выполни команду
docker run <id_образа>. Если на предыдущем этапе всё сделано правильно, увидишь логи запуска приложения dotnet.
Если у тебя MacOS, этот пункт выполнить целиком не получится из-за бага в Docker для MacOS, который не даёт полноценно пробрасывать порты между хостом и контейнером.
Останови контейнер и выполни команду docker run -p 50121:8080 <id_образа>. Вместо 50121 может быть произвольный свободный порт в твоей системе.
Если всё ок, по адресу http://localhost:50121/WeatherForecast откроется результат выполнения запроса к методу API нашего приложения.
Бывает нужно посмотреть, что лежит внутри контейнера, выполнить какие-нибудь команды (например, проверить сетевую связность). В этом помогут следующие команды.
Останови контейнер, если он был запущен. Теперь выполни команду docker run -it mcr.microsoft.com/dotnet/sdk:8.0 /bin/bash. Затем установи ping с помощью apt update && apt install iputils-ping -y. После установки пропингуй любой адрес. Контейнер после этого не останавливай.
Во втором инстансе терминала напиши docker ps, чтобы посмотреть список запущенных контейнеров. Найди свой из предыдущего шага (либо выполни пункт заново), затем выполни команду docker attach <container_id>. Проверь, что команда ping доступна.
Выполни команду из пункта 2.1, но подключи что-нибудь через -v:путь_с_хоста:/путь/в/контейнере. Проверь в контейнере, что файл/директория есть в файловой системе.