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