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 infrastrukturprojekt för lärande. Själva applikationen är en medvetet enkel ASP.NET Core-backend. Poängen är leveranskedjan: CI/CD med GitHub Actions, Docker, en self-hosted runner, lokal Kubernetes med kind, och 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

Problemet jag ville lösa handlade inte om 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 deployad workload i Kubernetes, till något man faktiskt kan övervaka. Jag byggde det här projektet för att arbeta igenom varje lager själv istället för att bara läsa om det.

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 på min lokala maskin
  • Self-hosted deployment-runner konfigurerad i en Linux/WSL-miljö
  • ASP.NET Core-API körande inuti ett kind Kubernetes-kluster
  • Metrikar synliga i Prometheus- och Grafana-dashboards
  • Ett konkret infrastrukturcase som visar att jag förstår leveranskedjan bortom att bara skriva kod

Vad jag lärde mig

Det här projektet gjorde skillnaden mellan utvecklings-, build-, deploy- och runtime-miljöer konkret för mig. Jag lärde mig varför containrar spelar roll som deployment-artefakter, vad Kubernetes faktiskt hanterar på pod- och tjänstnivå, och hur Prometheus och Grafana gör även ett enkelt system lättare att förstå. Största insikten: 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