Wprowadzenie
Artykuł jest kontynuacją pierwszego wpisu dotyczącego platformy Docker: .NET Core – wprowadzenie do platformy Docker
W tej części skupimy się na utworzeniu obrazu i uruchomieniu kontenera z naszą aplikacją. Nie będę jednak skupiał się na pierwszym kroku, tj. tworzeniu nowej aplikacji. Jedynym wymaganiem jest utworzenie aplikacji konsolowej w technologii .NET Core, która po uruchomieniu wyświetli:
using System;
namespace sample_app
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Witaj swiecie prosto z Dockera!");
Console.ReadKey();
}
}
}
Jeżeli Docker jest dla Was nowością zapraszam do pierwszej części artykułu, która płynnie wprowadzi Was w podstawy jego użycia. Jeżeli wszystko macie zainstalowane, aplikacja została utworzona, zapraszam do właściwej części wpisu.
Konteneryzacja aplikacja utworzonej w .NET Core
W pierwszym kroku przechodzimy do folderu w którym utworzyliśmy nasz projekt i otwieramy dowolny edytor tekstowy. Musimy utworzyć plik konfiguracyjny dla naszego projektu. Dodajemy poniższe instukcje (szczegółowe wyjaśnienie poniżej) oraz zapisujemy w głównym katalogu projektu pod nazwą Dockerfile - koniecznie bez rozszerzenia.
FROM microsoft/dotnet:2.0-sdk
WORKDIR /sample-app/
# kopiujemy plik .csproj oraz używamy polecenia dotnet restore
COPY *.csproj ./
RUN dotnet restore
# kopiujemy i dokonujemy build'a całej reszty
COPY . ./sample-app
RUN dotnet build -c Release
ENTRYPOINT ["dotnet", "run", "-c", "Release", "--no-build"]
Instrukcje Docker są wykonywane sekwencyjnie co wykorzystamy w kolejnej części artykułu dotyczącej optymalizacji tworzonych obrazów.
Pierwszym poleceniem w pliku konfiguracyjnym jest zawsze FROM.
FROM microsoft/dotnet:2.0-sdk
Instrukcja te iniciuje nowy build oraz definiuje podstawowy obraz dla pozostałych instrukcji. W zależności od ustawionego trybu kontenera dojdzie do pobrania wersji Windows lub Linux. Ta druga charakteryzuje się dużo mniejszym rozmiarem. W naszym przypadku będziemy korzystać z obrazu microsoft/dotnet:2.0-sdk. Jeżeli obraz ten znajduje się na dysku cały proces będzie zdecydowanie szybszy. W pierwszej cześci artykułu korzystaliśmy z polecenia pull, aby pobrać wymagane obrazy na dysk.
Instrukcja WORKDIR ustawia katalog roboczy dla pozostałych instrukcji zawartych w pliku konfiguracynym, tj. RUN, ENTRYPOINT oraz COPY. Jeżeli ten katalog nie istnieje dojdzie do jego utworzenia. W naszym przypadku folderem robocznym jest sample-app.
WORKDIR /sample-app
Instrukcja COPY kopiuje nowe pliki lub katalogi ze ścieżki źródłowej i dodaje je do docelowego systemu plików kontenera. Za pomocą tej instrukcji kopiujemy plik projektu do kontenera:
COPY *.csproj ./
Instrukcja RUN wykonuje wszystkie polecenia w nowej warstwie nad bieżącym obrazem i zatwierdza zmiany. Na tym etapie przygotowaliśmy nasz obraz i jesteśmy gotowi do kolejnego kroku. Polecenie dotnet restore pozwala na pobranie wszystkich niezbędnych zależności:
RUN dotnet restore
Polecenie COPY kopiuje pozostałe pliki do naszego kontenera na nowo utworzoną warstwę.
COPY . ./
Opublikowanie aplikacji odbywa się za pomocą instrukcji RUN z dodatkowymi parametrami. Polecenie dotnet publish kompiluje aplikację, przechodzi przez plik z zależnościami i publikuje wynik tej operacji do domyślnego folderu wynikowego. Za pomocą opcji -c (configuration) konfigurujemy tryp projektu na Release.
RUN dotnet publish -c Release
Ostatnim poleceniem w tym wypadku jest ENTRYPOINT - pozwala na uruchomienie kontenera jako pliku wykonywalnego oraz definiuje jak powinien zachowywać się obraz po uruchomieniu:
ENTRYPOINT ["dotnet", "run", "-c", "Release", "--no-build"]
Dodatkowe parametry konfiguracyjne są niezwykle istotne. Ponownie używamy opcji konfiguracyjnej Release - w przeciwnym wypadku dojdzie do próby uruchomienia w trybie Debug co wiąże się z ponowym budowaniem aplikacji (jest to niepotrzebne ponieważ build) został już zrobiony.
Flaga --no-build używana jest tylko do upewnienia się, że użyjemy kompilacji utworzonej w poprzednim kroku. Jeżeli, z jakiegoś powodu, nie uda się znaleźć tej wersji zastosowana flaga zwróci błąd ponieważ nie będzie w stanie samodzielnie wykonać kompilacji.
Nasz plik Dockerfile pozwala na:
- utworzenie obrazu z naszą aplikacją;
- przekopiowanie niezbędnych zależności do nowo utworzonego obrazu;
- build aplikacji, która działa jako plik wykonywalny.
Budowanie i uruchamianie aplikacji
Plik Dockerfile jest gotowy, poszczególne elementy zostały wyjaśnione.
Z poprzedniego artykułu pamiętacie, że konterem nazywamy działający obraz. Wykonajmy teraz kolejny krok – zbudujemy kontener:
docker build -t sample-app .
Może to być dość długi proces ale każdy krok pośredni będzie doskonale udokumentowany – będziecie na bieżąco z postępem:
Sam obraz również został utworzony:
Możemy teraz przejść do ostatniego kroku (na tym etapie) jakim jest uruchomienie naszego kontenera. Użyjemy do tego poniższego polecenia:
docker run sample-app
Jeżeli wszystko przebiegło pomyślnie na konsoli powinniście zobaczyć: