Mer kraftfullt än någon kravspecifikation: ”låt mig bara få se det först”
När jag hamnade som ensam utvecklare i ett SI-projekt för en offentlig myndighet var den största muren inte tekniken. Det var ’osäkerheten’. Den ideala miljön, där designen utgår från en noggrann kravspecifikation, fanns helt enkelt inte. Beställarna, som saknade utvecklingskunskaper, visste ofta inte själva vad de ville ha förrän de fick se skärmen direkt.
”Hm, på bilden förstår jag inte riktigt… kan jag inte få klicka på det på riktigt?”
Varje gång jag byggde en funktion körde jag den lokalt (på min dator), tog skärmdumpar, satte röda anteckningar bredvid och skickade en ’rapportfil (HWP/PPT)’ via mejl. Men med enbart statiska bilder gick det inte att tillfredsställa beställaren.
”Aha, den tidigare funktionen verkar bättre. Kan du återställa den?” ”Vad händer om man trycker på den här knappen? Filma det åt mig.”
Igår var A bäst, idag vill man ha B. Ändra koden lokalt, ny skärmdump, ny rapport: en oändlig loop. Det blev upp och ner: jag lade mer tid på rapportskrivande än på faktisk utveckling.
Då gick det desperat upp för mig: ’jag ska inte sitta och skicka skärmdumpar från min dator, jag behöver en lekplats (utvecklingsserver) där beställaren själv kan gå in, klicka fritt och försöka få sönder allt’.

Möjligheten dyker upp av en slump: en bortglömd server återupptäcks
Just under bolagsdelningen tilldelades vårt team som tur var en oanvänd server (en tom dator). Specifikationerna var inte mycket att hänga i julgranen, men den hade Linux installerat och en publik IP-adress kopplad: en värdefull resurs.
”Chefen, kan jag få använda den här överblivna servern? Jag vill bygga en server för beställarens validering på den.”
Tillstånd beviljat. Jag tömde all teknik jag lärt mig dittills över denna tomma server och började bygga ’mitt lilla infrastrukturimperium’. Det blev en sammanfattning av flera månaders mödosamma arbete (serierna Works on My Machine & The Pipeline).
- GitLab (kodrepo): Jag installerar ett privat repo och förvaltar koden säkert där.
- Docker Registry (imagelager): Jag bygger vårt alldeles egna lager där de byggda Docker-imagesen sparas.
- Portainer (containerhantering): För mig, som är rädd för CLI:t, gör den det möjligt att hantera Docker via ett GUI.
- Nginx (webbserver): Jag sätter en dörrvakt på plats som dirigerar trafiken mellan förfrågningar till frontend och backend.

Lösningen: fullständig separation av miljöer (Dev vs Prod)
Nu hade jag två scener (servrar) till mitt förfogande. För att kunna ta emot beställarens nyckfulla önskemål samtidigt som jag skyddade produktionsservern separerade jag deploystrategin.
- Utvecklingsserver (Development): ’ett fritt experimentlabb’
- Beställaren hinner inte ens fråga ”Är det där klart nu?”
- Så fort kod hamnar på
develop-branchen körs pipelinen direkt och koden deployas automatiskt. - Beställaren kan när som helst gå in på utvecklingsserverns URL, testa funktionerna och ge feedback.
- Produktionsserver (Production): ’en verifierad helgedom’
- Deploy sker bara när beställaren förkunnar ”Den här funktionen är slutgiltigt bestämd!”
- Koden slås ihop (Merge) med
master-branchen, och deploy sker först när jag trycker på knappen ’godkänn deploy’ i GitLab (Manual).
[Code Verification] Skapa ordning med villkorsstyrd deploy
GitLab CI låter dig ange olika deploysökvägar för olika branches. När man uttrycker den strategin i kod ser det ut så här.
stages:
- build
- deploy
# 1. Build (gemensam)
build_job:
stage: build
script:
- ./gradlew build
- docker build -t my-reg/app:$CI_COMMIT_SHA .
- docker push my-reg/app:$CI_COMMIT_SHA
# 2. Deploy till dev-server (automatisk)
# Sa fort kod hamnar pa 'develop'-branchen deployar vi utan att fraga.
deploy_to_dev:
stage: deploy
script:
- ssh user@dev-server "docker service update --image my-reg/app:$CI_COMMIT_SHA app-dev"
only:
- develop
# 3. Deploy till produktion (manuellt godkannande)
# Aven om kod hamnar pa 'master'-branchen sker ingen deploy forran jag trycker pa knappen.
deploy_to_prod:
stage: deploy
script:
- ssh user@prod-server "docker service update --image my-reg/app:$CI_COMMIT_SHA app-prod"
only:
- master
when: manual # Nyckeln! Det kors bara nar 'en person trycker pa knappen'.
Viktiga punkter:
only: - develop: Utvecklingsbranchen deployas alltid automatiskt. Snabbhet är A och O.when: manual: Produktionsbranchen får en säkerhetsspärr där en människa kontrollerar en gång till innan knappen trycks in.
Avslutningsvis: nu är ’jag klarar mig själv’ äntligen komplett
Nu har även jag, som ensam utvecklare, ett komplett system.
- Lokalt (Local): Funktionerna utvecklas på min egen dator.
- Utveckling (Dev): Ett enda
git pushoch fem minuter senare syns ändringen på utvecklingsservern. Beställaren kontrollerar själv. - Produktion (Prod): Bara godkända funktioner samlas ihop och deployas säkert med ett enda klick.
Det där jaget i början av anställningen, som jobbade övertid med skärmklippsverktyget igång och kommenterade Hangul-filer, finns inte längre. När beställaren säger ”kan du ändra det här åt mig?” kan jag svara ”visst, jag har rättat det och lagt upp det på utvecklingsservern, ta en titt” och i lugn och ro dricka mitt kaffe. För systemet jobbar i mitt ställe.
Med detta drar jag ridån för det långa [Re: Booting]-projektet. Från grunderna i datavetenskap, vidare till Linux, Docker och en CI/CD-pipeline. Jag hoppas att den här kunskapen, som byggts upp från grunden genom att envist köra huvudet i väggen, kan bli ett litet ljus för de ’försörjande fullstackutvecklare’ som just nu kämpar ensamma någonstans där ute.


