Magnus Marcus Hansen — softwareudvikler, Slagelse
Jeg bygger .NET-services og driver selv maskinen, de kører på.
Backend i C# og ASP.NET Core, frontend i Angular og udrulning gennem Azure DevOps. Den anden halvdel — databasen, det private pakkefeed, build-runneren, certifikaterne og tunnelen, der overhovedet gør det tilgængeligt udefra — er den, de fleste udviklere sender videre. Den står jeg selv for, på en maskine hjemme hos mig.
Siden, du læser lige nu, bliver serveret af en af kasserne herunder — en container på en Debian-maskine hjemme hos mig, som kun kan nås gennem en tunnel, den selv har åbnet udad.
Besøgende
Cloudflares edge
cloudflared
Debian-maskine med Docker
- Denne sideDu er her
- ConfigService
- BaGet
- Docker-registry
- MSSQL
- GitHub Actions-runner
Nginx Proxy Manager · wildcard-TLS — kun på LAN, aldrig gennem tunnelen
Om mig
Den korte version
Jeg er 28, bor i Slagelse og har arbejdet som softwareudvikler siden 2022 — to år hos Formpipe Software og siden februar 2026 hos Veng ApS. Mest C# og ASP.NET Core i backenden, Angular i frontenden og Azure DevOps ind imellem.
Det, jeg bliver ved med at vende tilbage til, er hele vejen fra kode til noget, der rent faktisk kører. Så den vej har jeg bygget selv i min fritid, hjemme hos mig: MSSQL i Docker, et privat BaGet-feed, som mine egne NuGet-pakker bliver udgivet til og mine services henter fra, et privat Docker-registry, en selvhostet GitHub Actions-runner, Nginx Proxy Manager med et wildcard-certifikat og Cloudflare Tunnel foran det hele.
Det smitter også af på, hvordan jeg er at arbejde sammen med. Jeg holder pipelinen grøn, skriver ned, hvad jeg finder ud af, og retter hellere det, der bliver ved med at gå i stykker, end jeg går uden om det.
Erfaring
Hvor jeg har arbejdet
2026–nu
Programmør, it-konsulent og udvikler
2024–2026
Jobsøgende
Det var i den periode, jeg byggede det meste af mine egne systemer: homelab-platformen og den Debian-maskine, den kører på, ConfigService og TokenForge, som er udgivet på et privat pakkefeed, og resten af mine private services.
2022–2024
Softwareudvikler
To år på et produktteam, delt mellem selve produktet og de værktøjer, der fik det ud til kunderne.
- Medansvarlig for det interne Azure DevOps på et af produkterne: build- og release-pipelines, agents og det, der gik galt i dem.
- Udvikler på produktets deployment-værktøj, som bliver brugt til at rulle produktet ud hos kunderne.
- Del af det almindelige udviklingsteam og af et forbedringsteam, der tog fat i det, som sinkede alle andre.
2016–2018
IT-supporter, skolepraktik
Second-line support og helpdesk under IT-supporteruddannelsen.
- Tog imod sager i helpdesken og det, første linje sendte videre: arbejdsstationer, brugerkonti, printere og netværk.
2013–2014
Servicemedarbejder
Butiksarbejde ved siden af skolen — varer, kasse og kunder.
Uddannelse
Vejen hertil
2019–2022
Datamatiker
To et halvt år på datamatikeruddannelsen. Jeg var i ti ugers praktik hos Formpipe, blev ansat der efter endt uddannelse og gik ud med 12 i afgangskarakter.
2018–2019
HF Enkeltfag
Enkeltfag på HF, taget for at få adgangsgrundlaget til datamatikeruddannelsen.
2015–2018
IT-supporter
IT-supporteruddannelsen, afsluttet med svendeprøve og 12 i begge dele af den.
Infrastruktur
Maskinen, siden kommer fra
Én Debian-maskine hjemme, en håndfuld containere og en tunnel ud. Jeg har selv sat det op og holder det kørende. Der er ingen åbne porte ind — alt kommer ind gennem Cloudflare.
- Besøgende
- Alle, der åbner siden her, hvor de så end sidder.
- Cloudflares edge
- DNS, TLS og caching foran det hele. Intet når maskinen uden at komme forbi her.
- cloudflared
- Ringer ud til Cloudflare og holder forbindelsen åben. Routeren videresender ingenting indad.
- Denne side
- Next.js-containeren, der serverer den side, du læser.
- ConfigService
- Central konfiguration. Alle andre services spørger den om deres indstillinger, når de starter.
- BaGet
- Privat NuGet-feed. Mine egne pakker bliver udgivet hertil, og mine services henter dem herfra.
- Docker-registry
- Privat image-registry. CI lægger images op i det, og Compose henter dem ned igen.
- MSSQL
- Databasen bag mine services, i sin egen container med et persistent volume.
- GitHub Actions-runner
- Selvhostet runner. Den bygger mine images og ruller dem ud på den samme maskine.
Nginx Proxy Manager står ved siden af det hele med wildcard-certifikatet til alt det, jeg åbner over LAN'et. Den er ikke et led i vejen ovenfor: intet af det, den serverer, går gennem tunnelen, så det kan ikke nås udefra.
Projekter
Det, jeg har bygget
Seks projekter, jeg har bygget i min fritid, fordi jeg selv havde brug for dem — ikke som portfolio-projekter. Jeg driver dem også selv.
Repositorierne er private: det er personlige systemer med mine egne data og adgangsnøgler, så der er ingen links til dem. Det eneste open source-projekt, der indgår, er den udvidelse, StreamScout er forket fra, og den er krediteret.
ConfigService
Ét krypteret sted til alle mine indstillinger og hemmeligheder.
- Problem
- Hver service havde sin egen kopi af de samme indstillinger og lå med sine hemmeligheder i klartekst, så én ændring betød, at flere skulle rulles ud igen.
- Løsning
- En ASP.NET Core-API krypterer værdierne med en hovednøgle, som den får ved opstart og aldrig gemmer sammen med data. Hver app har sin egen nøgle, der ligger hashet og kan skiftes ud, og der er roller til admin, redaktør og læser. En Angular-klient redigerer det hele.
- Resultat
- Hver service henter sin konfiguration i ét kald ved opstart, og et baggrundsjob tjekker hvert minut de apps, der har et health check sat op, så jeg kan se, hvilke der lever.
- Teknologi
TokenForge
To NuGet-pakker, så login kun skal løses én gang.
- Problem
- Hver ny service startede forfra på det samme arbejde — udstede tokens, hashe kodeord, sætte policies op — skrevet en anelse forskelligt hver gang.
- Løsning
- TokenForge.Core udsteder access- og refresh-tokens, hasher kodeord med BCrypt, har færdige adgangspolicies plus en API-nøgle i en header til kald mellem services. TokenForge.OAuth giver Discord-login på de samme tokens, tjekker medlemskab af serveren og kobler Discord-roller på app-roller.
- Resultat
- En ny service har login, der virker, efter én pakke og en håndfuld indstillinger, og en baggrundsservice kan kalde den med en nøgle i stedet for et brugerlogin.
- Teknologi
DiscordEconomy
Økonomi- og leaderboardsystem til en Discord-server.
- Problem
- En server ville have, at det talte for noget at være aktiv, og de bots, man kan leje sig til, er lukkede og svære at bygge videre på.
- Løsning
- Fire C#-projekter, ingen frontend: alt kører fra slash-kommandoer — /balance, /leaderboard, /shop — og botten kalder API'et med egen nøgle. Taletid tælles pr. session med et dagligt loft, tid med mikrofon eller lyd slået fra tæller ikke med, og en genstart midtvejs bliver samlet op igen.
- Resultat
- Mønter, XP, taletid og beskeder har hvert sit leaderboard, overførsler mellem medlemmer ender i ét regnskab, kaldenavne holdes synkroniseret, og satserne kommer fra ConfigService.
- Teknologi
JobApplicationManager
Jobopslag fra indbakken, fulgt helt frem til afsendt ansøgning.
- Problem
- Jobagent-mails hober sig op hurtigere, end jeg kan nå at læse dem, og fristen i én af dem er væk, så snart mailen ruller ud af syne.
- Løsning
- En mailagent holder en IMAP-forbindelse åben og læser hver agentmail, så snart den lander — én profil pr. afsender, og den kan finde ud af danske datoer. Ud af det kommer et opslag med frist. Derfra følger jeg det, genererer en ansøgnings-PDF og sender den af sted.
- Resultat
- Opslagene kommer ind med deres frister, og den samme app fører et opslag helt frem til afsendt ansøgning, mens Angular-klienten opdaterer sig live undervejs.
- Teknologi
StreamScout
Et fork af Twitch Lurker, der følger NoPixel og Kick.
- Problem
- Den oprindelige udvidelse dækkede Twitch og YouTube; jeg ville have Kick i stedet og NoPixel GTA V RP-streams fundet ud fra, hvad der rent faktisk bliver spillet.
- Løsning
- Jeg delte det op i fire npm-workspaces — en fælles kerne, et komponentbibliotek, udvidelsen og et Next.js-site — smed YouTube ud, hentede Kick ind via deres offentlige API og byggede NoPixel-genkendelsen ovenpå. Man logger ind på sitet med Twitch eller Kick, og det kører i egen container.
- Resultat
- Én udvidelse og ét site viser, hvem der er live på Twitch og Kick, med faner til kategorier, dem jeg følger, og NoPixel.
- Teknologi
- Forket fra
- Twitch Lurker
WorkSummary
Et års kalenderposter, talt sammen måned for måned.
- Problem
- Mit arbejdsmønster fandtes kun som kalenderposter, så jeg måtte tælle i hånden, hvor mange kontordage, hjemmearbejdsdage, sygedage og egne fridage der lå i en måned.
- Løsning
- En lille ASP.NET Core-API tager et års kalenderposter, matcher hver enkelt på titlen og tæller dem sammen pr. måned i kontordage, hjemmearbejdsdage, sygedage og egne fridage. Hver måned har desuden et flag for, om den er indberettet til SKAT.
- Resultat
- Ét kald svarer på, hvordan en måned rent faktisk så ud, og om den er indberettet endnu, i stedet for at jeg tæller kalenderposter.
- Teknologi
Kompetencer
Det, jeg arbejder med
Ingen procenter og ingen søjler. Det første er det, jeg griber til uden at tænke over det; det andet er det, jeg kan arbejde i, når opgaven kræver det.
Bruger dagligt
Kan arbejde i
Kontakt
Tag fat i mig
Jeg bor i Slagelse og er åben for backend- og fullstack-arbejde i .NET — i nærheden eller remote. En mail er den mest direkte vej ind til mig; LinkedIn og GitHub virker også.
- [email protected]
- linkedin.com/in/magnum43434
- GitHub
- github.com/magnum43434
- Bor i
- Slagelse, Danmark