Инструменты для разработки

Visual Studio 2017 RC

Непревзойденная производительность для любого способа разработки, любого приложения и любой платформы

Visual Studio Community 2015

Бесплатная среда разработки

Visual Studio Enterprise 2015

Комплексное решение для рабочих групп

Дополнительное ПО и SDK

Выберите необходимые инструменты.

ASP.NET Core + Docker: готовим вместе

Дата публикации: 09.03.2016



Кам нам известно, ASP.NET Core, можно(и даже нужно) запускать не только на Windows, но так же на Mac и Linux. Что это нам дает? Например можем запаковать наше приложение со всеми его зависимостями в docker контейнер и удобно разворачивать его на тестовых\рабочих средах. Мы не будем рассматривать о том  что такое docker и как его  устанавливать, а вместо этого попробуем собрать образ с ASP.NET Core.

Подготавлием тестовое приложение

У нас есть выбор на чем запускать наше первое ASP.NET Core приложение: на mono или на coreclr. Я выберу второй вариант, так как это модно, стильно, молодежно. 

По традиции созданим пустой ASP.NET Core проект:



После создания зайдем в файл project.json, он должен содержать следующие поля:

....
 "dependencies": {
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel --server.urls http://*:5004"
  } ,
....




Нас интересует секция  commands, а именно команда web. При её выполнении запускается kestrel вэб сервер, который будет доступен по 5004 порту.(???) 

Давайте проверим запускается ли наше приложение локально: для этого сначала убедимся что у нас есть нужная версия DNX, и она выставлена по умолчанию для использования. 

Выполняем

dnvm list






Если у вас выбрана версия с рантаймом clr, то необходимо переключится на coreclr командой:

dnvm use 1.0.0-rc1-final -r coreclr -p




Если у вас отсутствует версия coreclr, то её легко установить выполнив

dnvm upgrade -r coreclr




Давайте уже запускать наше приложение: перейдем в папку где его создали и выполним. 

> dnu restore
> dnx web




Первая команда устанавливает зависимости, вторая собсвенно запускает наше приложение. Теперь если перейдем по адресу http://localhost:5004, то увидим приветственное сообщение. Все, мы готовы паковать наше приложени в контейнер.

Создаем докер образ

Для того чтобы докер собрал нам образ(image), нам надо рассказать ему[докеру] как это сделать по средством комманд записанных в докер файле. 

Докер создает обзар(image) читая команды из Dockerfile. Создами Dockerfile в корне проекта (хоть это и не много противоречит лучшим практикам по написанию Dockerfile) содержащего команды:

FROM microsoft/aspnet:1.0.0-rc1-update1-coreclr

COPY . /app
WORKDIR /app
RUN ["dnu", "restore"]

EXPOSE 5004
ENTRYPOINT ["dnx", "-p", "project.json", "web"]




FROM — Указываем базовый образ на основе которого мы будем строить собственный
COPY — Копируем все из папки (.) в файловую систему контейнера, в папку /app
WORKDIR — Задаем рабочую папку относительно которой будут выполнятся команды RUN, CMD, ENTRYPOINT, COPY и ADD следующите за этой командой в докерфайле 

RUN — Устанавливаем все зависимости для нашего приложения. RUN делаеть чуть больше, чем просто вылонение команды, вот  тутописано подробнее
EXPOSE — Говорим докеру, что в нашем образе есть сервис который будет слушать 5004 порт (который мы указали в файлеproject.json)

ENTRYPOINT — Указываем команду которая выполнится при старте контейнера. Отличия от  CMD

Теперь соберем наш образ:

docker build -t first-aspnet-app .




Через некоторое время, когда наш образ собрался, запустим его:

docker run -d -p 80:5004 first-aspnet-app



-d — переключает запущенный контейнер в бэкграунд, иначене ввод/вывод вэб сервера был бы приаттачен к нашему шеллу.
-p — маппит порт хостовой машины на exposed порт контейнера. Т.е все запросы пришедшие на 80 порт будут проброшены на порт 5004

Теперь если пройти по адресу http://localhost:80 мы увидим приветственное сообщение. Так как я с докером работаю в windows среде, то взаимодействую не напрямую, а через docker-machine, поэтому мне надо обраться на ip адресс docker-machine, который можно узнать не хитрой командой

docker-machine ip



В моем случае проверить приложение надо по адресу http://192.168.99.100:80 (80 порт можно и не указывать).

Вуаля, работает!




Создаем правильный докер образ

Однако не все так гладко, конечно же в докере есть и подводные камни. Один большой такой подводный булыжник это проблема PID 1или зобми процесс, подробнее  тут. Ребята из phusion(создатели phusion passenger) позаботились о нас и сделали образ phusion/baseimage решающий много проблем, который мы и будем использовать для создания образа с ASP.NET Core. 

Методом честного копирования команд из  Docker файла от Microsoft полчим свой:

FROM phusion/baseimage:latest

ENV DNX_VERSION 1.0.0-rc1-update1
ENV DNX_USER_HOME /opt/DNX_BRANCH

ENV DNX_RUNTIME_ID ubuntu.14.04-x64

RUN apt-get -qq update && apt-get -qqy install unzip curl libicu-dev libunwind8 gettext libssl-dev libcurl3-gnutls zlib1g && rm -rf /var/lib/apt/lists/*

RUN curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_USER_HOME=$DNX_USER_HOME DNX_BRANCH=v$DNX_VERSION sh
RUN bash -c "source $DNX_USER_HOME/dnvm/dnvm.sh \
    && dnvm install $DNX_VERSION -alias default -r coreclr \
    && dnvm alias default | xargs -i ln -s $DNX_USER_HOME/runtimes/{} $DNX_USER_HOME/runtimes/default"

RUN LIBUV_VERSION=1.4.2 \
    && apt-get -qq update \
    && apt-get -qqy install autoconf automake build-essential libtool \
    && curl -sSL https://github.com/libuv/libuv/archive/v${LIBUV_VERSION}.tar.gz | tar zxfv - -C /usr/local/src \
    && cd /usr/local/src/libuv-$LIBUV_VERSION \
    && sh autogen.sh && ./configure && make && make install \
    && rm -rf /usr/local/src/libuv-$LIBUV_VERSION \
    && ldconfig \
    && apt-get -y purge autoconf automake build-essential libtool \
    && apt-get -y autoremove \
    && apt-get -y clean \
    && rm -rf /var/lib/apt/lists/*

ENV PATH $PATH:$DNX_USER_HOME/runtimes/default/bin

COPY . /app
WORKDIR /app
RUN ["dnu", "restore"]

EXPOSE 5004
ENTRYPOINT ["dnx", "web"]



Что делать даль нам уже известно:

docker build -t aspnetcore-phusion .

и

docker run -d -p 80:5004 aspnetcore-phusion



Если вы как и я не останавливали контейнер созданный в начале статьи, то докер сообщит нам что 80 порт уже занят:

docker: Error response from daemon: failed to create endpoint loving_kowalevski on network bridge: Bind for 0.0.0.0:80 failed: port is already allocated.



Остановим наш ранее запущенный контейнер и запустим новый

docker stop loving_kowalevski
docker run -d -p 50:5004 aspnetcore-phusion


Каждый раз, когда мы запускаем контейнер докер генерируем ему рандомное имя. Как именно — можно посмотреть  тут.


Заключение

В этой короткой обзорной статье мы создали пару контейнеров с простым ASP.NET Core приложением. Конечно в реальности приложения обычно сложнее, и контейнеров больше. 

На мой взгляд, приложения ASP.NET Core запускающиеся на coreclr пока еще не production ready, так как не все привычные нам библиотке могу запускаться на coreclr. Например для mongodb еще нет драйвера, а autofac еще в альфе. Конечно, можно найти выход в mono, но мы тут с вами про coreclr. Однако прогресс не стоит на месте, библиотеки портируются, и в скором времени мы увидим настоящие кроссплатформенные приложения на ASP.NET Core.

Автор статьи: Вячеслав Бобик

Данный материал написан участником сообщества. В статье представлено мнение автора, которое может не совпадать с мнением корпорации Microsoft. Microsoft не несет ответственности за проблемы в работе аппаратного или программного обеспечения, которые могли возникнуть после использования материалов данной статьи.