Docker

Introduktion till Docker

Container, image, registry och Compose — de fyra begreppen resten av serien vilar på

Hoppa till

Var vi är

Det här är första delen i Docker-serien, och den förutsätter ingenting mer än att du sett en terminal förut. Har du läst Linux-delarna känner du igen filsystemet och rättigheterna som dyker upp här och där.

Den här delen ger överblicken: fyra begrepp som resten av serien bygger vidare på. Vi skriver inga egna filer än — det gör vi i nästa del.

Vad Docker är

Docker är ett verktyg som paketerar en applikation med allt den behöver för att köra, och startar paketet i en container med isolerade processer, filsystem och nätverk.

Allt applikationen är beroende av — programkod, bibliotek, körtid, inställningar — följer med i paketet. Teamet kör därmed samma paketerade beroenden och grundinställningar.

Värdsystem, processorarkitektur, externa tjänster och körparametrar kan fortfarande skilja sig. Poängen är att de viktiga skillnaderna blir synliga och kan testas.

Docker är inte ett operativsystem och inte ett programmeringsspråk. Det är ett paketerings- och körverktyg, och det ligger ovanpå det operativsystem du redan har.

Vad en container är

En container är en körande applikation som är isolerad från resten av systemet.

Isolerad betyder att containern har sitt eget filsystem, sina egna processer och sitt eget nätverksutrymme. Isoleringen skiljer körmiljöer åt, men är inte ensam en fullständig säkerhetsgräns.

När Lisa börjar i teamet räknar hon med en dag av installationer innan hon kan köra e-handelssystemet. I stället kör hon ett kommando och har samma miljö som alla andra — samma Node-version, samma databas, samma inställningar.

Vad containers faktiskt löser
  • Alla i teamet arbetar med samma paketerade beroenden, vilket minskar “det funkar på min dator”.
  • En ny utvecklare är igång på minuter i stället för timmar.
  • Imagen gör versionsvalen synliga och möjliga att granska.
  • Projekten stör inte varandra. Två projekt kan använda olika Node-versioner på samma dator.

Containerns livscykel

En container är inte antingen igång eller borta. Den går genom fyra lägen, och docker ps visar bara ett av dem.

Created — skapad men inte startad. Running — processen kör. Exited — processen är klar eller kraschad, men containern finns kvar med sitt filsystem och sina loggar. Removed — borta på riktigt.

Det förklarar det som förvirrar mest första veckan. docker ps listar bara Running. En container som gjort sitt och avslutat ser ut att ha försvunnit, men ligger kvar som Exited tills någon tar bort den.

docker ps      # bara det som kör
docker ps -a   # allt som finns

Det är också därför docker run på samma image två gånger ger två containrar. Kommandot skapar alltid en ny; det återanvänder aldrig en gammal.

Container vs virtuell maskin

Den här jämförelsen är den som får containrar att klicka, och den är värd att ta ordentligt.

En virtuell maskin härmar en hel dator. Den kör ett eget operativsystem ovanpå ditt, med egen kärna, egna drivrutiner och egen systemstart. Den är därför ofta större och långsammare att starta än en container.

En container delar operativsystemets kärna med din dator och isolerar bara processerna och filsystemet. Den startar därför ofta snabbare, men storlek och starttid beror på imagen och miljön.

Priset för skillnaden är att containrar inte kan köra vilket operativsystem som helst — de delar ju kärnan. En Linux-container behöver en Linux-kärna, och det är därför Docker Desktop på macOS och Windows i tysthet kör en liten Linux-maskin i bakgrunden.

App Gäst-OS Hypervisor Värd-OS App Docker Värd-OS finns inte Virtuell maskin Container
Skillnaden är rutan som inte finns. Containern delar värdens kärna i stället för att bära en egen.

Vad en image är

En image är den färdiga, oföränderliga ritningen som en container startas ur.

I imagen ligger filsystemet som containern ska se: operativsystemets grunddelar, applikationens kod, dess bibliotek och beskedet om vad som ska köras vid start.

En image byggs en gång och ändras sedan aldrig. Vill du ändra något bygger du en ny.

Image vs container

De två blandas ihop hela tiden, och skillnaden återkommer i varje senare del.

Imagen är ritningen. Den ligger still, tar plats på disken och går att dela med andra.

Containern är en körande kopia av ritningen. Den startas, stoppas och kastas.

Från en enda image kan du starta hur många containrar du vill, och alla startar från samma image. Det är samma förhållande som mellan en klass och ett objekt, eller mellan ett recept och en portion.

ImageEn färdig, oföränderlig ritning. Ligger still.docker runContainerEn körande kopia av ritningen.
Imagen är receptet, containern är portionen. Från samma image kan du starta hur många containrar du vill.

Images består av lager

En image byggs inte i ett stycke utan i lager. När Docker bygger imagen skapar de flesta Dockerfile-instruktioner ett lager.

Lagren är skrivskyddade och återanvänds mellan images. Har du tio images som alla utgår från node:22-alpine lagras det lagret en gång, inte tio.

Det är också därför en image på 900 MB inte tar 900 MB extra plats när du redan har en liknande. Hur lagren byggs och varför ordningen mellan dem spelar roll tar vi i nästa del.

Var images ligger på din maskin

Images sparas i Dockers eget lager på disken, inte som filer du kan bläddra bland.

docker images
docker system df

docker images listar dem med storlek. docker system df sammanfattar vad Docker tar upp totalt: images, stoppade containrar, volymer och byggcache.

Talet växer fortare än man tror. Varje bygge lämnar lager, och varje Exited container ligger kvar med sitt filsystem. Det är därför en utvecklarmaskin plötsligt har tiotals gigabyte i Docker, och docker system prune är kommandot som städar.

Storleken i docker images är dessutom inte additiv. Två images som delar basen räknas var för sig, men lagren finns bara en gång på disken.

amd64 vs arm64

En image är byggd för en processorarkitektur, och det märks först när den inte är det.

amd64 är Intel och AMD — nästan alla servrar. arm64 är Apple Silicon, Raspberry Pi och en växande del av molnet.

Kör du på en nyare Mac är din värd arm64. De flesta officiella images finns för båda, och Docker väljer rätt automatiskt. Problemet uppstår med en image som bara finns för en av dem:

WARNING: The requested image's platform
(linux/amd64) does not match the detected host
platform (linux/arm64/v8)

Meddelandet är brutet här; det kommer på en rad. Containern startar ändå — Docker Desktop emulerar den andra arkitekturen, långsamt. På en Linux-server utan emulering får du i stället exec format error, vilket ser ut som en trasig fil men betyder fel arkitektur.

Vill du välja medvetet finns --platform linux/amd64 på både pull och run.

Vad ett registry är

Ett registry är en tjänst som lagrar images så att andra kan hämta dem.

Docker Hub är det mest kända. Företag använder ofta ett eget: GitHub Container Registry, Azure Container Registry eller motsvarande.

Det är samma förhållande som mellan Git och GitHub. Verktyget bygger lokalt; registryt är platsen där resultatet delas.

Utan registry

Varje utvecklare bygger sina egna versioner lokalt.

Ingen kan vara säker på att de testar exakt samma bygge, och skillnaderna märks först när något går sönder.

Med registry

Teamet laddar upp, versionerar och hämtar images från ett ställe.

Den som testar en ändring testar precis det bygge som senare rullas ut i produktion.

Skillnaden är inte bekvämlighet — det är om teamet kan lita på att de testar samma sak.

Registry, repository och tagg

Tre ord som ofta används om vartannat, men som betyder olika saker.

Registryt är servern som lagrar images — docker.io, ghcr.io.

Repositoryt är den namngivna samlingen av en images alla versioner — node, postgres, mitt-foretag/searchapi.

Taggen är versionen inuti repositoryt — 22-alpine, v2, latest.

Fullständigt skrivs det registry/repository:tagg. Utelämnar du registryt antar Docker att du menar Docker Hub, och utelämnar du taggen antar den latest. Att latest inte betyder “senaste stabila” tar vi i nästa del.

:v1 :v2 :latest Registry · ghcr.io Repository · searchapi
Registryt är hyllan, repositoryt är sektionen, taggarna är lådorna.

Vad Docker Compose är

Docker Compose startar flera containrar tillsammans utifrån en fil som beskriver dem.

E-handelssystemet består av tre delar: en frontend, ett API och en databas. Var och en kör i sin egen container, och de måste kunna hitta varandra.

services:
  webshop:
    build: ./frontend
    ports:
      - "3000:3000"

  api:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      DATABASE_URL: postgres://user:pw@db:5432/shop

  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pw
      POSTGRES_DB: shop

Hela miljön startar med docker compose up, och den startar likadant hos alla i teamet.

Docker vs Docker Compose

Docker kör en container i taget. Varje docker run är ett eget kommando med sina egna flaggor för portar, miljövariabler och nätverk.

Docker Compose läser en fil som beskriver flera containrar och startar dem tillsammans, med nätverket redan uppsatt.

Compose ersätter inte Docker — det använder Docker. Det du vinner är att uppsättningen ligger i en fil du kan versionshantera, i stället för i ett kommando någon måste komma ihåg.

Starta för hand

Varje del startas separat, i rätt ordning, med rätt flaggor.

Varje tjänst behöver konfigureras för att hitta de andra.

Flera terminalfönster måste hållas öppna.

docker compose up

Allt startar med ett kommando, i ordning.

Tjänsterna är redan konfigurerade att prata med varandra.

Uppsättningen ligger i en fil som granskas som all annan kod.

Samma system, samma tjänster — men bara det ena sättet går att upprepa utan att tänka.

Vad det här betyder i ditt arbete

Du kommer att köra docker compose up varje morgon och docker build varje gång du ändrat något som ska paketeras. De två kommandona bär det mesta av vardagen.

Du kommer också att läsa andras Dockerfiles och Compose-filer i merge requests. Det är där de fyra begreppen betalar sig: du behöver kunna se på en rad om den rör imagen eller containern, bygget eller körningen.

Registry-drift, imagesignering och säkerhetsskanning är oftast någon annans ansvar. De blir dina den dag du äger utrullningen — och då är det ändå samma fyra begrepp, bara med fler krav på sig.

Vanliga nybörjarförväxlingar

En container är inte en virtuell maskin. Den delar operativsystemets kärna och startar ofta snabbare.

En image är inte en container. Imagen ligger still; containern är den körande kopian.

Docker Hub är inte Docker. Registryt lagrar images; Docker bygger och kör dem.

Docker Compose ersätter inte Docker. Det använder Docker för att starta flera containrar samtidigt.

Att en container stoppar betyder inte att den är borta. Den ligger kvar tills den tas bort.

Prova själv

Alla kommandon nedan är ofarliga och kräver bara att Docker Desktop är igång.

docker run hello-world

Docker hämtar en liten image från Docker Hub, startar en container ur den och skriver ut ett meddelande. Fråga sedan vilka containrar som körs:

docker ps

Listan är tom. Det är inte ett fel — hello-world skrev sitt meddelande och avslutade direkt, och docker ps visar bara containrar som körs just nu. Fråga i stället efter alla:

docker ps -a

Nu syns containern, med status Exited. Den finns kvar tills du tar bort den, vilket är precis poängen med förväxlingen ovan.

Titta slutligen på imagen den startades ur:

docker images

Två saker som kan förvirra: docker ps utan -a är den vanligaste anledningen till att folk tror att en container “försvann”. Första körningen tar längre tid eftersom imagen hämtas — därefter går den på en bråkdel av tiden.

Kom ihåg
  • En container är en isolerad, körande applikation. Den delar värdens kärna — den är ingen VM.
  • En image är den oföränderliga ritningen. Samma image startar containrar från samma grund.
  • Images består av lager som återanvänds mellan images.
  • Ett registry lagrar images. registry/repository:tagg är det fullständiga namnet.
  • Docker Compose startar flera containrar utifrån en fil, med nätverket redan på plats.
Kolla att du hänger med
Vad är skillnaden mellan en image och en container?
Imagen är den färdiga ritningen — oföränderlig och stillastående. Containern är en körande kopia av den. Från en image kan du starta hur många containrar du vill, och de börjar från samma grund.
Vad är den avgörande skillnaden mellan en container och en virtuell maskin?
Den virtuella maskinen kör ett eget operativsystem med egen kärna. Containern delar värdens kärna och isolerar processer och filsystem. Containern startar ofta snabbare och blir ofta mindre, men storlek och starttid beror på imagen och miljön.
Du kör en container som avslutas direkt. docker ps visar ingenting. Är containern borta?
Nej. docker ps visar bara containrar som körs just nu. Den stoppade containern finns kvar och syns med docker ps -a, tills du tar bort den.
Vad betyder de tre delarna i ghcr.io/mitt-foretag/searchapi:v2?
ghcr.io är registryt — servern som lagrar imagen. mitt-foretag/searchapi är repositoryt — samlingen av den imagens versioner. v2 är taggen — den specifika versionen.
Varför löser containers problemet "det funkar på min dator"?
För att kod, bibliotek, versioner och grundinställningar ligger paketerat i imagen. Teamet börjar från samma grund i stället för att varje dator byggs för hand. Värdsystem och externa tjänster kan fortfarande skilja sig.
Vad tillför Docker Compose som docker run inte gör?
Compose beskriver flera containrar i en fil, startar dem tillsammans och sätter upp nätverket åt dig. Uppsättningen blir något du versionshanterar i stället för ett kommando någon måste komma ihåg.

Snabb sammanfattning

  • Docker paketerar en applikation med allt den behöver och kör paketet i en isolerad miljö.
  • En container är en isolerad, körande applikation med eget filsystem och eget nätverksutrymme.
  • En container delar värdens kärna. En virtuell maskin kör en egen — det är den viktiga skillnaden.
  • En image är den oföränderliga ritningen en container startas ur.
  • Imagen ligger still, containern kör. Samma image ger containrar med samma grund.
  • Images består av skrivskyddade lager som återanvänds mellan images.
  • Ett registry lagrar images. Förhållandet är samma som mellan Git och GitHub.
  • registry/repository:tagg — utelämnad tagg blir latest, utelämnat registry blir Docker Hub.
  • Docker Compose startar flera containrar utifrån en fil och sätter upp nätverket åt dig.
  • Compose ersätter inte Docker. Det använder Docker.

Nästa del

Hittills har Lisa kört images som någon annan byggt. I nästa del skriver hon receptet själv: hur en Dockerfile byggs rad för rad, och varför ordningen mellan raderna avgör om bygget tar sekunder eller minuter.