Case study

Proxmox Provider dla platformy VPS

System integrujący panel platformy VPS z infrastrukturą Proxmox — automatyczne provisionowanie, cykl życia maszyn i komunikacja w czasie rzeczywistym.

Typ
Software / Infrastructure
Klient
Confidential
Data
lipiec 2026

Problem

Platforma sprzedająca serwery VPS zdecydowała się wdrożyć nowe środowisko wirtualizacji - PVE (Proxmox Virtual Environment). W związku z tym należało zaprojektować usługę, która weźmnie całą odpowiedzialność za zarządzanie cyklem życia maszyn wirtualnych klientów oraz ich monitorowaniem. Wymagana była niezawodność, idempotencja oraz spójność przy jednocześnie rosnącej liczbie klientów.

Kontekst

Warstwa wykonawcza opierała się na Proxmox VE. Panel klienta i panel administracyjny potrzebowały jednego, spójnego sposobu zlecania operacji na maszynach oraz wglądu w ich aktualny stan, a także możliwości monitorowania klastra — najlepiej w czasie rzeczywistym, bez ręcznego odświeżania. W celach administracyjnych wymagane było zarządzanie takimi funkcjami jak sieci wirtualne lub polityki migawek.

Podejście

Zaprojektowałem osobny moduł — „provider" — odpowiedzialny wyłącznie za komunikację z Proxmox i tłumaczenie intencji biznesowych (utwórz maszynę, zmień plan, usuń, uruchom, wykonaj migawkę) na konkretne operacje w infrastrukturze. Panel nigdy nie rozmawia z Proxmox bezpośrednio; zawsze przez jawny kontrakt providera.

Operacje długotrwałe potraktowałem jako zadania asynchroniczne z jawnym cyklem życia: zlecone, w toku, zakończone, błąd. Za ich orkiestrację w obrębie modułu odpowiada mechanizm internal commands processor. Dzięki temu interfejs mógł pokazywać rzeczywisty postęp, a nie tylko „proszę czekać".

Architektura

  • Provider jako granica: cała wiedza o Proxmox zamknięta za jednym kontraktem.
  • Kolejka zadań dla operacji długotrwałych, z idempotentnymi krokami.
  • PostgreSQL jako źródło prawdy o stanie zamówień i maszyn.
  • Redis do koordynacji zadań i cache'owania stanu odpytywanego często.

Implementacja

Kluczowa była idempotentność. Ponowienie zadania po awarii nie mogło tworzyć drugiej maszyny ani pozostawiać systemu w stanie niespójnym. Każdy krok sprawdzał najpierw, czy jego efekt już nie istnieje.

public async Task<Result> Handle(ProvisionVm task, CancellationToken ct)
{
    var existing = await proxmox.FindByTagAsync(task.CorrelationId, ct);
    if (existing is not null)
        return Result.AlreadyDone(existing.VmId); // idempotentnie: brak duplikatu

    var vm = await proxmox.CreateAsync(task.Spec, task.CorrelationId, ct);
    await progress.PublishAsync(task.OrderId, VmState.Provisioned, ct);
    return Result.Ok(vm.VmId);
}

Stan każdego zadania był publikowany na bieżąco, więc panel administracyjny i panel klienta widziały te same, aktualne informacje.

Stack

.NET, ASP.NET Core, PostgreSQL, Redis, Docker oraz API Proxmox VE.

Rezultat

Provisioning maszyn stał się w pełni automatyczny i powtarzalny. Czas realizacji typowego zamówienia skrócił się z minut liczonych ręcznie do operacji wykonywanej bez udziału człowieka. Panele pokazują rzeczywisty stan maszyn na żywo, a operacje można bezpiecznie ponawiać po awarii.

Lessons learned

  • Idempotentność nie jest dodatkiem — przy operacjach na infrastrukturze to warunek bezpieczeństwa.
  • Zamknięcie integracji za jednym kontraktem opłaciło się przy każdej późniejszej zmianie w Proxmox.
  • Komunikacja w czasie rzeczywistym najbardziej pomogła nie klientom, lecz administracji — skróciła czas reakcji na problemy.
Współpraca

Porozmawiajmy o projekcie

Opisz problem albo cel — odezwę się z konkretną propozycją następnego kroku: rozmowy, audytu, zakresu prac lub ofertą.