Wdrażanie do kontenera i Docker Hub - Budowanie przykładowej API w kursie C#
Publikowanie aplikacji .NET Core w kontenerze Docker to kluczowa umiejętność dla współczesnych programistów. Kontenery oferują niezmienną infrastrukturę, łatwą dystrybucję i lekkie środowiska uruchomieniowe. W tym dogłębnym przewodniku przeprowadzimy krok po kroku przez proces wdrażania przykładowego API do kontenera Docker, a następnie przesuniemy go do Docker Hub, zgodnie z krokami przedstawionymi w obszernym wideoporadniku Tima Corey'a: "Deploying to a Container and Docker Hub – Building a Sample API in C#."
Przyjrzyjmy się krok po kroku procesówi, odniesienia do konkretnych znaczników czasowych ułatwią śledzenie. Ten przewodnik obejmuje użycie poleceń takich jak dotnet publish, polecenie docker run, oraz terminów jak obraz bazowy, obraz uruchomieniowy i obraz kontenera—wszystkie ważne pojęcia dotyczące wdrażania aplikacji .NET za pomocą Dockera.
Tworzenie i rozumienie przykładowego API
Na początku filmu Tim podkreśla przydatność przykładowej aplikacji przy nauce programowania webowego. Aplikacja zawiera punkty końcowe takie jak /courses i /health, symuluje rzeczywiste problemy jak pogorszone testy sprawdzające zdrowie i została zaprojektowana do uruchamiania zarówno na lokalnej maszynie, jak i zdalnym serwerze.
Jest to aplikacja .NET Core (dokładniej minimalne API ASP.NET Core), którą można łatwo uruchomić i przetestować przy użyciu kontenerów Docker.
Konfiguracja Dockera lokalnie
Tim sprawdza, czy Docker jest zainstalowany na jego lokalnej maszynie, używając Docker Desktop. Zauważa, że możliwe jest publikowanie bezpośrednio na Docker Hub bez Dockera zainstalowanego lokalnie, ale dla celów demonstracyjnych rozpoczyna od wdrożenia lokalnego.
Pokazuje dwa wcześniej zainstalowane obrazy Dockera:
-
Osobiste narzędzie do napisów
- Oficjalny obraz bazowy ASP.NET Core od Microsoftu: mcr.microsoft.com/dotnet/aspnet
Ten obraz bazowy ma około 328 MB i działa jako fundament dla naszego obrazu kontenera. Microsoft hostuje te obrazy w MCR (Microsoft Container Registry) i obsługują one zarówno kontenery Linuksa, jak i Windowsa. Dla tego projektu, docelowym systemem operacyjnym jest Linux.
Publikowanie do kontenera lokalnie
Tim przechodzi do folderu projektu API i uruchamia następujące polecenie w linii komend:
dotnet publish -p:PublishProfile=DefaultContainer
dotnet publish -p:PublishProfile=DefaultContainer
To polecenie używa wbudowanego wsparcia dla kontenerów w .NET 8 i .NET 9, eliminując potrzebę pliku Dockerfile. Proces publikacji wybiera odpowiedni obraz uruchomieniowy i buduje autonomiczny obraz kontenera.
Oto, co dzieje się "pod maską":
-
Plik projektu (.csproj) jest używany do budowy API
-
Zależności są przywracane za pomocą polecenia dotnet restore
-
Wyniki trafiają do folderu publikacji
- Generowany jest plik DLL i osadzany w kontenerze
Powstały obraz ma około 333 MB (tylko o 5 MB więcej niż bazowy).
Uruchamianie obrazu z Dockerem
Gdy obraz zostanie utworzony, Tim używa Docker Desktop do uruchomienia kontenera. Wewnątrz, aplikacja nasłuchuje na porcie 8080. Tim mapuje to na losowy port hosta, wpisując 0 w konfiguracji portu.
Kontener uruchamia się z losową nazwą (np. elegant_hoover), a przeglądarka otwiera się, wyświetlając działające API z "Hello World" jako domyślną odpowiedzią.
Przeglądając /courses i /health, Tim potwierdza, że API działa. Punkt końcowy sprawdzania kondycji jest przydatny do symulacji scenariusza w środowisku produkcyjnym.
Aby zobaczyć działające kontenery, możesz użyć polecenia docker ps w CLI. Tim usuwa działający kontener i obraz później, aby zademonstrować czyszczenie.
Tworzenie repozytorium Docker Hub
Następnie Tim przechodzi do części wdrożenia w chmurze. Loguje się do swojego konta Docker Hub i tworzy publiczne repozytorium o nazwie thesampleapi.
Tu zostanie wepchnięty obraz Dockera, aby inni mogli go pobrać używając:
docker pull timcorey/thesampleapi:latest
docker pull timcorey/thesampleapi:latest
Konfiguracja projektu do Docker Hub
W pliku projektu API Tim dodaje metadane, aby określić, gdzie i jak publikować obraz Dockera. Dodaje następujący blok kodu:
<ContainerRegistry>docker.io</ContainerRegistry>
<ContainerRepository>timcorey/thesampleapi</ContainerRepository>
<ContainerImageTags>1.0.0;latest</ContainerImageTags>
<ContainerRegistry>docker.io</ContainerRegistry>
<ContainerRepository>timcorey/thesampleapi</ContainerRepository>
<ContainerImageTags>1.0.0;latest</ContainerImageTags>
-
ContainerRegistry: Określa Docker Hub jako docelowy rejestr.
-
ContainerRepository: Ścieżka do repozytorium Docker Hub.
- ContainerImageTags: Oznacza obraz w celu wersjonowania i najnowszego wydania.
To przygotowuje obraz na przyszły wieloetapowy proces budowy, chociaż na razie Tim trzyma się prostych rozwiązań.
Publikacja na Docker Hub
Tim ponownie uruchamia to samo polecenie publikacji:
dotnet publish -p:PublishProfile=DefaultContainer
dotnet publish -p:PublishProfile=DefaultContainer
Na początku wstawka kończy się niepowodzeniem, bo zapomniał zapisać pliku .csproj. Po zapisaniu i ponownym uruchomieniu polecenia, obraz udaje się przesłać na Docker Hub.
W Docker Hub pojawiają się zarówno tagi latest, jak i 1.0.0 pod repozytorium thesampleapi. Te tagi zapewniają elastyczność przy pobieraniu konkretnych wersji.
Pobieranie obrazu z Docker Hub
Tim pokazuje, jak pobrać obraz z dowolnej maszyny z zainstalowanym Dockerem:
docker pull timcorey/thesampleapi:latest
docker pull timcorey/thesampleapi:latest
Dzięki cachingowi warstw Dockera, obraz szybko pobiera się, ponieważ większość z niego już istnieje z obrazu bazowego.
Aby uruchomić obraz:
docker run -p 0:8080 timcorey/thesampleapi:latest
docker run -p 0:8080 timcorey/thesampleapi:latest
To mapuje losowy port hosta na wewnętrzny port 8080.
Tworzenie nowej wersji obrazu
Aby zademonstrować wersjonowanie, Tim edytuje plik .csproj, aby:
<ContainerImageTags>1.0.1;latest</ContainerImageTags>
<ContainerImageTags>1.0.1;latest</ContainerImageTags>
Następnie ponownie uruchamia polecenie publikacji:
dotnet publish -p:PublishProfile=DefaultContainer
dotnet publish -p:PublishProfile=DefaultContainer
Teraz repozytorium Docker Hub pokazuje trzy tagi:
-
1.0.0
-
1.0.1
- latest (teraz wskazuje 1.0.1)
Tim wyjaśnia, że pomimo wielu tagów, Docker nie przechowuje duplikatów warstw, optymalizując użycie dysku dzięki oddzielnym warstwom.
Używanie obrazu Dockera do lokalnego rozwoju
Tim podkreśla, że gdy obraz jest na Docker Hub, możesz uruchomić go w dowolnym momencie na dowolnej maszynie, używając:
docker pull timcorey/thesampleapi:latest
docker pull timcorey/thesampleapi:latest
Następnie skorzystaj z polecenia docker run, aby go uruchomić. Gdy skończysz, posprzątaj za pomocą:
docker ps # Get container ID
docker stop <id> # Stop the container
docker rm <id> # Remove the container
docker rmi <image> # Remove the image
docker ps # Get container ID
docker stop <id> # Stop the container
docker rm <id> # Remove the container
docker rmi <image> # Remove the image
Wyjaśnia, że czyni to idealnym rozwiązaniem dla rozwoju na żądanie i testowania bez nadmuchiwania lokalnej maszyny.
Co dalej?
Tim kończy, wspominając o kolejnym kroku: wdrażaniu tego samego API na Virtual Private Server (VPS). Przeprowadzi przez proces mapowania domeny i konfigurowania kontenera, aby był publicznie dostępny.
Wnioski: Od lokalnego budowania do wdrożenia w chmurze
Korzystając z przewodnika wideo Tima Corey'a, we've:
-
Zbudowaliśmy API .NET Core za pomocą dotnet new console
-
Użyliśmy dotnet restore i dotnet publish do budowy i wdrożenia
-
Stworzyliśmy kontener Docker bez potrzeby dla przykładowego pliku Dockerfile
-
Przesłaliśmy obraz kontenera na Docker Hub
-
Pobieraliśmy i uruchamialiśmy kontener za pomocą docker run
-
Zarządzaliśmy tagami i odrębnymi warstwami obrazu
- Przygotowaliśmy się do środowisk produkcyjnych używając wersjonowanych obrazów
Ten przepływ pracy, skoncentrowany wokół Dockera i .NET, jest idealny do budowy skalowalnych, testowalnych i udostępnialnych aplikacji.
