Skip to content
Tillbaka till Portfolio
DeepDiveInfra – Self-hosted CI/CD- och Kubernetes-labb

DeepDiveInfra – Self-hosted CI/CD- och Kubernetes-labb

Ett self-hosted cloud-native-inspirerat lärandeprojekt med fokus på leveranskedjan runt en medvetet enkel ASP.NET Core-backend. Projektet demonstrerar kod → test → build → Docker → self-hosted deployment → Kubernetes-runtime → observability med Prometheus och Grafana.

Min roll: Ensam utvecklare – leverans- och observability-fokuserat infrastrukturcase
2026

Teknikstack

C# · .NET 10 · ASP.NET Core · Minimal API · SQLite · EF Core · xUnit · GitHub Actions · Docker · Kubernetes · kind · kubectl · Linux · WSL · Prometheus · Grafana · Scalar / OpenAPI

Problem / Kontext

Huvudproblemet var inte avancerad domänlogik. Det handlade om att förstå vad som händer efter att koden är skriven: hur en backend går från källkod till testad build, till container, till self-hosted deployment, till Kubernetes-runtime, till en observerbar workload. Projektet byggdes för att täppa till det gapet genom att arbeta igenom varje lager praktiskt.

Lösning / Arkitektur

Lösningen är ett self-hosted lokalt labb: en Windows-värd med WSL/Linux-verktyg, Docker Desktop, ett kind-kluster, GitHub Actions för build och test, en self-hosted runner för deployment och Prometheus + Grafana för övervakning. ASP.NET Core-API:t använder SQLite och EF Core med automatiska migreringar vid uppstart. Appen i sig hålls medvetet enkel så att infrastruktur och leveranskedja förblir i fokus.

Så fungerar det – Arkitekturflöde

  1. 1Bygg en enkel ASP.NET Core-API med SQLite och EF Core
  2. 2Pusha ändringar till GitHub
  3. 3GitHub Actions återställer, bygger och testar lösningen
  4. 4En self-hosted Linux-runner hämtar deployment-jobbet
  5. 5Docker paketerar API:t som en deploybar image
  6. 6Imagen deployas till ett lokalt kind-baserat Kubernetes-kluster
  7. 7Kubernetes kör workloaden som pods/services
  8. 8Prometheus scrapar applikations- och klustermetrics
  9. 9Grafana visualiserar systemhälsa och runtime-beteende

Mål

  • Förstå hela leveranskedjan från start till slut
  • Jämföra GitHub-hosted och self-hosted runners
  • Deploya en riktig containeriserad backend till Kubernetes
  • Lägga till övervakning och göra systemet observerbart
  • Dokumentera arkitekturbeslut och avvägningar

Utmaningar

  • Förstå gränserna mellan utvecklings-, build-, deploy- och runtime-miljöer
  • Konfigurera self-hosted runnern korrekt på Linux/WSL
  • Hantera stacken Windows + WSL + Docker Desktop + kind
  • Strukturera Kubernetes-manifester och deployment-flödet rent
  • Exponera användbara Prometheus- och Grafana-metrikar utan att överkomplicera projektet

Viktiga tekniska beslut

  • Hålla backend medvetet enkel – värdet ligger i leveranskedjan, inte domänen
  • Använda SQLite eftersom målet är att lära sig leveranskedjan, inte distribuerad datadesign
  • Använda kind för en lokal Kubernetes-lärmiljö
  • Använda Prometheus/Grafana för praktisk observability
  • Hålla projektet self-hosted och lokalt istället för hanterad molntjänst

Resultat / Effekt

  • Fungerande CI/CD-flöde från GitHub-push till deployad Kubernetes-workload
  • Self-hosted deployment-runner i en Linux-miljö
  • Körande ASP.NET Core-API inuti ett kind Kubernetes-kluster
  • Synliga metrikar i Prometheus- och Grafana-dashboards
  • Ett portfolioklart infrastrukturcase som visar förståelse för leverans, deployment och observability

Vad jag lärde mig

Det här projektet klargjorde skillnaden mellan utvecklings-, build-, deploy- och runtime-miljöer — och var problem uppstår mellan dessa lager. Jag lärde mig varför containrar spelar roll som deployerbara artefakter, vad Kubernetes faktiskt hanterar på pod- och tjänstnivå, och hur observability med Prometheus och Grafana gör även ett enkelt system mycket lättare att resonera kring. Den största insikten var att infrastrukturförståelse är en egen kompetens, skild från att skriva applikationskod.

Vad jag skulle förbättra härnäst

  • Lägga till CPU-/minnesanvändningsmetrikar och alertregler
  • Introducera ingress för extern åtkomst till klustret
  • Gå från SQLite till en mer produktionslik datauppsättning
  • Paketera manifester renare med Helm eller liknande approach

Skärmdumpar

Utforska det här projektet