Упаковка вашего приложения в Docker-контейнер имеет множество преимуществ, включая упрощение развёртывания без привязки к конкретному облачному хостингу. В этой статье мы контейнеризируем приложение на .NET Core и развернём его с помощью Docker.
Прежде чем начать, необходимо установить несколько зависимостей. Убедитесь, что у вас установлена последняя версия .NET Core SDK. Вы можете скачать SDK для своей операционной системы на странице проекта.
Чтобы запускать Docker-контейнеры локально, также потребуется установить Docker. Инструкции для вашей операционной системы можно найти на сайте Docker.
Если вы, как и я, используете Visual Studio Code в качестве редактора кода, обратите внимание на расширение Docker.
Если у вас уже есть существующий проект на .NET Core, вы можете использовать его. В противном случае создайте новое пустое приложение ASP.NET Core, открыв командную строку и введя:
«`
dotnet new web -n docker-example
cd docker-example
«`
Это создаст новый каталог с пустым приложением ASP.NET Core и установит все зависимости. Альтернативно вы можете сделать это прямо в Visual Studio, если предпочитаете такой способ. После установки проверим, работает ли приложение, скомпилировав и запустив его:
«`
dotnet run
«`
Когда появится сообщение `Now listening on: http://localhost:5000`, перейдите в браузере по адресу http://localhost:5000, и вы должны увидеть сообщение `Hello World`. Теперь можно остановить приложение, нажав `Ctrl+C` в командной строке.
Теперь, когда у нас есть приложение, его нужно «докеризировать», создав файл `Dockerfile`. `Dockerfile` используется для описания Docker-приложения, также называемого *контейнером*. Он определяет, что необходимо для запуска вашего приложения, включая выбор операционной системы, настройку каталогов, копирование кода приложения в контейнер и т. д.
К счастью, нам не нужно изобретать велосипед для каждого приложения, использующего Docker. Мы всегда можем взять за основу существующий образ. На Docker Hub доступны сотни тысяч контейнерных образов, которые можно использовать в качестве базового.
Для нашего проекта мы будем использовать образ `microsoft/dotnet` в качестве базового. Microsoft предоставляет различные версии этого образа, которые частично обозначаются суффиксами, такими как `runtime` или `sdk`. Образ `sdk` содержит полный .NET Core SDK, что позволяет создавать или собирать приложения. Это полезно для разработки, но не для продакшена. Более лёгкая версия образа помечена тегом `runtime`. Она включает только необходимые компоненты для запуска приложения на .NET Core. В итоге размер контейнера уменьшается до 251 МБ по сравнению с 879 МБ для версии `1.1.1`. В этой статье мы будем использовать образ `runtime`.
Создайте новый файл с именем `Dockerfile` (без расширения) в каталоге вашего проекта .NET Core и добавьте в него следующую строку:
«`
FROM microsoft/dotnet:1.1.1-runtime
«`
Это определит наш базовый образ как версию `1.1.1-runtime` образа `microsoft/dotnet`. Базовый образ возьмёт на себя настройку операционной системы и установку рантайма.
Далее нам нужно скопировать файлы, необходимые для запуска приложения, в папку внутри контейнера. Это можно сделать с помощью команды `COPY` в `Dockerfile`. Мы будем компилировать наше приложение в папку `out` проекта, поэтому нужно скопировать файлы из этой папки в рабочий каталог, который в данном случае называется `/app`. Добавьте следующие строки в ваш `Dockerfile`:
«`
WORKDIR /app
COPY ./out .
«`
Определим, на каком порту будет работать наш сервер ASP.NET Core, установив переменную окружения `ASPNETCORE_URLS`. В нашем случае это порт `5000`. Чтобы иметь возможность обращаться к этому порту извне Docker-контейнера, его также нужно открыть. Добавьте следующие строки в `Dockerfile`:
«`
ENV ASPNETCORE_URLS=http://+:5000
EXPOSE 5000
«`
Наконец, запустим наше .NET-приложение с помощью исполняемого файла `dotnet` и передадим ему DLL с именем нашего приложения (`docker-example.dll`).
Итоговый `Dockerfile` должен выглядеть так:
«`
FROM microsoft/dotnet:1.1.1-runtime
WORKDIR /app
COPY ./out .
ENV ASPNETCORE_URLS=http://+:5000
EXPOSE 5000
ENTRYPOINT [«dotnet», «docker-example.dll»]
«`
Вот и всё — наш `Dockerfile` готов к локальному тестированию.
Прежде чем создать Docker-образ и запустить его локально, сначала нужно скомпилировать проект и опубликовать его в папку `out`, откуда его подхватит Docker-контейнер. Выполните следующую команду в командной строке:
«`
dotnet publish -c Release -o out
«`
После завершения компиляции можно собрать Docker-образ:
«`
docker build -t docker-example .
«`
Эта команда загрузит базовый образ из Docker Hub и выполнит шаги, указанные в `Dockerfile`, упаковав существующую систему в контейнер. Теперь запустим наш контейнер:
«`
docker run -it -p 5000:5000 —rm docker-example
«`
Эта команда запустит наш контейнер `docker-example` в интерактивном режиме, выводя консольные логи. Она также сопоставит открытый порт 5000 контейнера с портом 5000 на локальном хосте, а параметр `—rm` обеспечит удаление Docker-контейнера после остановки приложения с помощью `Ctrl+C`.
Теперь вы снова можете перейти по адресу http://localhost:5000 и увидеть сообщение `Hello World`.
Если всё работает, остановите Docker-контейнер, завершив его работу с помощью `Ctrl+C`.
Наш Docker-контейнер готов, и настало время развернуть его в облаке. Преимущество в том, что этот контейнер можно запускать на различных облачных хостингах, загрузив собранный образ в реестр, например Docker Hub, а затем поручив облачному хостингу, такому как Azure, развернуть соответствующий образ. Однако мы рассмотрим альтернативный вариант.
now.sh — это облачная платформа для хостинга, которая позволяет легко развёртывать Docker-проекты. Её преимущество в том, что вам не нужно собирать образ контейнера на своём компьютере или размещать его в каком-либо реестре. Вместо этого она соберёт контейнер за вас в облаке. Кроме того, она позаботится о масштабировании и размещении на Google Cloud Engine и Amazon Web Services.
Предупреждение заранее: Бесплатный тариф `now` предназначен для проектов с открытым исходным кодом. В рамках этого тарифа вы сможете просматривать исходный код вашего приложения, перейдя по пути `/_src` в развёрнутом проекте. Это означает, что бесплатным тарифом стоит пользоваться только для развёртывания приложений без конфиденциальных данных. Конфиденциальные данные следует хранить в `secrets` и загружать через переменные окружения.
Для начала работы с `now` установите CLI или, альтернативно, приложение *now Desktop* (которое включает CLI) со страницы загрузки now. После установки и регистрации настало время развернуть наше приложение.
После установки CLI всё, что нужно сделать, — это выполнить в командной строке каталога вашего проекта:
«`
now
«`
Вот и всё! Сервис загрузит ваш исходный код, соберёт Docker-образ и развернёт его. Он также скопирует URL вашего приложения в буфер обмена. Обычно он имеет формат: `https://docker-example-xxxxxxxxxx.now.sh`. Во время развёртывания вы также сможете увидеть статус на этой странице.
Если вы внесёте изменения в код приложения, развёртывание новой версии будет таким же простым, как повторная компиляция и запуск команды `now`:
«`
now
«`
`now` будет создавать новый URL при каждом развёртывании. Это означает, что вы можете развернуть новую версию, протестировать её, а затем, когда будете довольны результатом, назначить ей «продакшен»-URL с помощью команды `alias`. Назначение псевдонима выполняется так:
«`
now alias docker-example-xxxxxxxxxx myamazingdockerapp
«`
Это приведёт к сопоставлению вашего развёртывания `docker-example-xxxxxxxxxx` с адресом `https://myamazingdockerapp.now.sh`. На платном тарифе вы также можете использовать собственные домены, и HTTPS настраивается автоматически.
Вот и всё! Мы завершили процесс: перенесли приложение на .NET Core с локального компьютера в облако с помощью Docker!
Что дальше? Вариантов множество, но вы можете изучить:
— Как хранить данные в Google Таблицах с помощью .NET Core
— Как использовать библиотеку Twilio нового поколения с .NET Core
Возможность запускать .NET Core практически где угодно меня очень вдохновляет, и мне хотелось бы узнать о вашем опыте! Дайте знать, если у вас есть вопросы или вы создали что-то крутое и хотите похвастаться. С нетерпением жду ваших работ!
— Email: dkundel@twilio.com
— Twitter: @dkundel
— GitHub: dkundel