Zarządzanie Dockerem w C#

CHash
Priorytet: Normalny Szkic

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

  1. Docker Desktop zainstalowany i uruchomiony na systemie.
  2. Visual Studio z zainstalowanym obciążeniem "Programowanie aplikacji klasycznych dla platformy .NET".
  3. 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:

  1. Listę kontenerów: Komponent ListView lub DataGridView wyświetlający aktualnie istniejące kontenery (Nazwa, Obraz, Status).
  2. Przyciski akcji: Start, Stop, Restart, Usuń dla wybranego z listy kontenera.
  3. 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)

  1. 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").
  2. 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żyj GetContainerLogsAsync).
  3. Statystyki zasobów: Zaimplementuj wyświetlanie zużycia procesora (CPU) i pamięci RAM dla wybranego kontenera w czasie rzeczywistym.
  4. 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.
  5. 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 MessageBox z ostrzeżeniem.