Zarządzanie Dockerem w C#
Zadanie 1100: Zarządzanie kontenerami Docker w C# (WinForms)
Wstęp
Docker stał się nieodzownym narzędziem w pracy programisty, pozwalając na izolację środowisk bazodanowych i aplikacyjnych. Zamiast instalować MySQL czy PostgreSQL bezpośrednio w systemie, możemy uruchamiać je jako lekkie kontenery. W tym zadaniu nauczymy się, jak napisać aplikację okienkową w C# (Windows Forms), która będzie komunikować się z Docker API, umożliwiając sterowaniem procesami bazodanowymi bezpośrednio z Twojego interfejsu.
Wymagania wstępne
- Docker Desktop zainstalowany i uruchomiony na systemie.
- Visual Studio z zainstalowanym obciążeniem "Programowanie aplikacji klasycznych dla platformy .NET".
- Biblioteka NuGet: Docker.DotNet – jest to oficjalny wrapper na Docker Remote API dla .NET.
Podstawowe pojęcia Docker API
Aplikacja C# komunikuje się z Dockerem za pomocą gniazda (socket) lub endpointu HTTP. Biblioteka Docker.DotNet upraszcza to do poziomu obiektów i metod asynchronicznych.
Inicjalizacja klienta
using Docker.DotNet;
using Docker.DotNet.Models;
// Standardowe połączenie dla Windows (Named Pipes)
DockerClient client = new DockerClientConfiguration(
new Uri("npipe://./pipe/docker_engine"))
.CreateClient();
Przygotowanie obrazów (PostgreSQL i MySQL)
Aby móc uruchamiać kontenery, musimy najpierw pobrać ich obrazy. W kodzie C# możemy to zrobić za pomocą metody Images.CreateImageAsync.
await client.Images.CreateImageAsync(
new ImagesCreateParameters { FromImage = "postgres", Tag = "latest" },
null,
new Progress<JSONMessage>());
await client.Images.CreateImageAsync(
new ImagesCreateParameters { FromImage = "mysql", Tag = "latest" },
null,
new Progress<JSONMessage>());
Operacje na kontenerach
1. Tworzenie i Uruchamianie
Tworząc kontener dla bazy danych, musimy pamiętać o zmiennych środowiskowych (np. hasło roota) oraz mapowaniu portów.
var response = await client.Containers.CreateContainerAsync(new CreateContainerParameters
{
Image = "postgres",
Name = "my-postgres-db",
Env = new List<string> { "POSTGRES_PASSWORD=mojehaslo" },
HostConfig = new HostConfig
{
PortBindings = new Dictionary<string, IList<PortBinding>>
{
{ "5432/tcp", new List<PortBinding> { new PortBinding { HostPort = "5432" } } }
}
}
});
await client.Containers.StartContainerAsync(response.ID, null);
2. Zatrzymywanie
await client.Containers.StopContainerAsync("container_id_lub_nazwa", new ContainerStopParameters());
3. Restartowanie
await client.Containers.RestartContainerAsync("container_id_lub_nazwa", new ContainerRestartParameters());
4. Usuwanie
Pamiętaj, że zazwyczaj nie można usunąć uruchomionego kontenera (należy go najpierw zatrzymać lub użyć flagi Force).
await client.Containers.RemoveContainerAsync("container_id_lub_nazwa", new ContainerRemoveParameters { Force = true });
Zadania do wykonania
Twoim celem jest stworzenie kompletnej aplikacji Windows Forms, która posiada:
- Listę kontenerów: Komponent
ListViewlubDataGridViewwyświetlający aktualnie istniejące kontenery (Nazwa, Obraz, Status). - Przyciski akcji: Start, Stop, Restart, Usuń dla wybranego z listy kontenera.
- Kreator baz danych: Przyciski "Zainstaluj MySQL" oraz "Zainstaluj PostgreSQL", które automatycznie pobiorą obraz i stworzą gotowy do pracy kontener z domyślnymi parametrami.
5 Zadań Dodatkowych (Obowiązkowe)
- Monitorowanie statusu na żywo: Dopisanie Timera (
System.Windows.Forms.Timer), który co 3 sekundy odświeża listę kontenerów i zmienia kolor tła wiersza (np. zielony dla "running", czerwony dla "exited"). - Logi kontenera: Dodanie pola typu
TextBox(Multiline), w którym po kliknięciu na kontener wyświetli się ostatnich 20 linii logów wygenerowanych przez bazę danych (użyjGetContainerLogsAsync). - Statystyki zasobów: Zaimplementuj wyświetlanie zużycia procesora (CPU) i pamięci RAM dla wybranego kontenera w czasie rzeczywistym.
- Zarządzanie Volume: Dodaj opcję w kreatorze, która pozwoli użytkownikowi wybrać folder na dysku lokalnym, który zostanie podmontowany pod
/var/lib/postgresql/data(lub odpowiednik dla MySQL), aby dane bazy nie znikały po usunięciu kontenera. - Weryfikacja dostępności portów: Przed uruchomieniem kontenera, aplikacja powinna sprawdzić, czy port (np. 3306 lub 5432) nie jest już zajęty przez inną usługę w systemie. Jeśli jest – wyświetl
MessageBoxz ostrzeżeniem.