Bästa praxis för Docker i produktion — multi-stage builds, säkerhetshärdning, image-optimering, health checks och registreringsstrategier.
Docker har på ett decennium gått från en banbrytande teknik till en självklar del av den moderna infrastrukturen. 2026 är containrar standarden för att paketera, distribuera och köra applikationer — och Docker är fortfarande det vanligaste verktyget för att bygga och hantera containrar. Men att köra Docker i produktion kräver en helt annan disciplin än att köra Docker på din utvecklingsmaskin.
I den här guiden går vi igenom de best practices som svenska DevOps-team måste känna till för att använda Docker i produktion på ett säkert, effektivt och underhållbart sätt. Vi täcker multi-stage builds, image-optimering, Dockerfile-praxis, säkerhetshärdning, secrets-hantering, och jämför Docker med Podman.
Varför Docker i produktion kräver mer än utveckling
På din utvecklingsmaskin är större images, root-användare och ooptimerade lager mest en irritation — saker går lite långsammare, men det fungerar. I produktion blir varje megabyte image-storlek en kostnad, varje säkerhetsproblem en risk, och varje långsam uppstart en påverkan på användarna. Produktion kräver att du tänker på saker som reproducerbarhet, spårbarhet och underhållbarhet på ett helt annat sätt.
För svenska företag som hostar i Azure, AWS eller på egen infrastruktur är skillnaderna i kostnad mellan en optimerad 80 MB-image och en ooptimerad 1,2 GB-image betydande — både i lagringskostnad, överföringstid och deployment-hastighet.
Multi-stage builds — bygg rent, leverera litet
Multi-stage builds är den enskilt viktigaste tekniken för att minska image-storlek. Idén är enkel: du använder flera FROM-uttryck i samma Dockerfile, där tidigare stadier innehåller byggverktyg och senare stadier bara kopierar över det som behövs för att köra applikationen.
| 1 | FROM node:22-alpine AS build |
| 2 | WORKDIR /app |
| 3 | COPY package*.json ./ |
| 4 | RUN npm ci |
| 5 | COPY . . |
| 6 | RUN npm run build |
| 7 | |
| 8 | FROM node:22-alpine AS production |
| 9 | WORKDIR /app |
| 10 | COPY --from=build /app/dist ./dist |
| 11 | COPY --from=build /app/node_modules ./node_modules |
| 12 | COPY --from=build /app/package.json ./ |
| 13 | CMD ["node", "dist/index.js"] |
Resultatet: slutmålet innehåller varken TypeScript-källkod, dev-dependencies eller byggverktyg som webpack och TypeScript-kompilatorn. För en typisk Node.js-applikation minskar det image-storleken från 1,5 GB till under 200 MB. För Go- eller Rust-applikationer kan du till och med använda scratch som bas-image för en slutstorlek på under 10 MB.
Optimera bildstorlek — från GB till MB
Förutom multi-stage builds finns flera tekniker för att minimera dina images. Välj minimala bas-images: alpine (5 MB), distroless (Google, cirka 10 MB), eller slim-varianter. Undvik att installera onödiga paket — en Docker-container ska bara innehålla precis det som krävs för att köra applikationen. Slå ihop RUN-kommandon för att minska antalet lager: varje RUN, COPY och ADD skapar ett nytt lager, och färre lager innebär mindre storlek.
Rensa alltid cache och temporära filer i samma lager som du installerar dem. Om du kör apt-get install eller apk add, rensa pakethanterarens cache i samma RUN-kommando. För npm, kör npm cache clean --force direkt efter installationen.
Dockerfile best practices
Utöver multi-stage finns flera viktiga regler för att skriva produktionsredo Dockerfiles. Ordningen på kommandon spelar roll: lägg saker som ändras sällan (systemberoenden, npm-paket) tidigt i Dockerfilen, och saker som ändras ofta (källkod) sent. Detta utnyttjar Docker layer caching maximalt och gör att byggen går mycket snabbare — särskilt i CI/CD-miljö.
Använd specifika versionstaggar för bas-images, inte latest. FROM node:22-alpine är bra, FROM node:latest är en säkerhetsrisk eftersom du inte vet vad du får. Överväg att använda digest-hash för maximal reproducerbarhet: FROM node:22-alpine@sha256:a7c86a.... Och undvik att köra som root — skapa en dedikerad användare i Dockerfilen.
.dockerignore — vad du inte ska packa med
.dockerignore är förmodligen den mest underskattade filen i Docker-ekosystemet. Utan en .dockerignore skickar du hela ditt projekt som build context till Docker daemon — inklusive node_modules, .git, loggfiler och hemligheter. Detta gör byggen långsammare och ökar risken att du av misstag inkluderar .env-filer med känslig data.
En bra .dockerignore innehåller som minimum: node_modules, .git, .env, .env.local, dist (om du bygger i multi-stage), *.log, .DS_Store, .idea, .vscode. För svenska företag som hostar på Azure eller AWS bör du också ignorera Terraform- eller Pulumi-state-filer om de ligger i repot.
Health checks — låt orkestreringen veta hur det går
En container kan vara igång men ändå vara ur funktion — till exempel om applikationen startat men inte kan ansluta till databasen. Health checks låter Docker och din orkestreringsplattform (Kubernetes, ECS, Nomad) kontinuerligt kontrollera att applikationen faktiskt fungerar.
| 1 | HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1 |
Din applikation bör exponera en dedikerad health-endpoint som inte bara returnerar 200 utan faktiskt validerar att kritiska tjänster (databas, cache, externa API:er) svarar. I Kubernetes kan du kombinera livenessProbe (starta om om containern hängt sig) med readinessProbe (ta bort från service om appen inte är redo) för finare kontroll.
Loggning i produktion
Docker samlar automatiskt stdout och stderr från din container, men default loggdrivern (json-file) kan orsaka problem i produktion. Loggarna växer obegränsat och kan fylla upp din disk. Konfigurera log rotation antingen i Docker daemon eller i din container-orkestrering.
| 1 | logging: |
| 2 | driver: "json-file" |
| 3 | options: |
| 4 | max-size: "10m" |
| 5 | max-file: "3" |
Ännu bättre: använd en central logglösning. Skicka loggar direkt till Azure Monitor, AWS CloudWatch, Grafana Loki eller Datadog via loggdrivrar. Skriv loggar i JSON-format för enkel maskinparsning och se till att varje loggpost innehåller korrelations-ID så att du kan följa en request genom hela systemet.
Köra som non-root user
Detta är en av de viktigaste säkerhetsåtgärderna du kan vidta. Som standard körs containrar som root i Docker. Om en angripare lyckas ta sig ur containern (genom en container escape-sårbarhet) har de root-åtkomst till din host om containern kördes som root.
Skapa alltid en dedikerad användare i din Dockerfile och växla till den innan applikationen startar:
| 1 | RUN addgroup -S appgroup && adduser -S appuser -G appgroup |
| 2 | USER appuser |
Kombinera detta med att göra alla filer som applikationen skriver till read-only där så är möjligt, och använd readOnlyRootFilesystem: true i Kubernetes-säkerhetskontexten för maximal begränsning.
Secrets management — aldrig i Dockerfilen
En av de vanligaste misstagen är att hårdkoda API-nycklar och lösenord i Dockerfiler. Hemligheter hör inte hemma i images — en image som innehåller en API-nyckel i ett lager kan extraheras av vem som helst som har tillgång till image-registryt, även om lagret senare tas bort med ett nytt lager.
Använd Docker BuildKit för att skicka hemligheter vid byggtid:
| 1 | RUN --mount=type=secret,id=npmrc,required=true cp /run/secrets/npmrc ~/.npmrc && npm ci |
För runtime-hemligheter använder du Docker Swarm secrets, Kubernetes Secrets, eller en extern secrets manager som Azure Key Vault, AWS Secrets Manager eller HashiCorp Vault. Ladda bara in hemligheter som miljövariabler vid container-start, inte vid byggtid.
Image tagging-strategi
En genomtänkt image-tagging-strategi är avgörande för spårbarhet och rollback-möjligheter. Undvik att använda latest — den säger ingenting om vad som faktiskt körs. Använd istället en kombination av semantisk versionering och git commit SHA: app:v1.2.3-a1b2c3d. Detta gör att du exakt vet vilken kod som finns i en specifik image.
För svenska team som använder GitHub Actions eller Azure DevOps är det vanligt med en strategi där varje merge till main genererar en image taggad med både version från git tag och commit SHA. Vid produktion-deployment använder du den specifika SHAn i stället för en rörlig tagg. Detta ger dig full spårbarhet och möjlighet att omedelbart rulla tillbaka till föregående image.
Registry management
Valet av container-registry påverkar både prestanda, kostnad och säkerhet. GitHub Container Registry (GHCR) passar bra om du redan använder GitHub för CI/CD. Azure Container Registry (ACR) och Amazon ECR erbjuder tight integration med respektive molnplattform. Docker Hub är enkelt men har rate limits att ta hänsyn till.
Oavsett val: konfigurera image retention policies så att gamla images automatiskt rensas. En typisk policy är att behålla de senaste 100 versionerna och ta bort images äldre än 90 dagar. Agera proaktivt på sårbarhetsscanning — de flesta registries erbjuder automatisk scanning med CVE-databaser.
Docker vs Podman i produktion
Podman har vuxit i popularitet som ett alternativ till Docker, särskilt i enterprise-miljöer som kräver rootless-containrar som standard. Podman är daemonless, vilket innebär att det inte finns någon central daemon som måste köras som root — varje container är en separat process som kan köras under användarens UID. Detta ger en mindre attackyta jämfört med Docker.
För svenska företag som redan har en etablerad Docker-baserad pipeline är det sällan värt att migrera till Podman — skillnaderna är marginella för de flesta användningsfall. Men för nya projekt i Kubernetes-miljöer där containrar ändå körs i poddar, är Podman ett intressant alternativ för build-steget tack vare sina rootless-egenskaper. Kompatibiliteten är hög — Podman kan köra Docker-images och accepterar Docker-kommandon via alias.
Säkerhetsskanning och sårbarhetshantering
Automatiserad sårbarhetsscanning av dina images bör vara en obligatorisk del av CI/CD-pipelinen. Använd docker scout (inbyggt i Docker Desktop 2026) eller trivy (open source från Aqua Security) för att skanna images på kända sårbarheter innan de deployas.
Integrera scanning i din CI/CD-pipeline: bygg image → skanna → om kritisk sårbarhet upptäcks → blockera deployment och meddela teamet. För svenska bolag under NIS2 är detta inte bara best practice utan i många fall ett regulatoriskt krav. Sätt upp policies för vilka sårbarhetsnivåer som är acceptabla och automatisera re-mediation med renovate- eller dependabot-liknande verktyg.
Slutsats
Docker i produktion handlar om disciplin. Multi-stage builds, minimala bas-images, icke-root-användare, health checks och en genomtänkt tagging-strategi är inte avancerade tekniker — men de gör skillnaden mellan en containermiljö som är säker, kostnadseffektiv och underhållbar, och en som är riskfylld, dyr och svår att felsöka. Börja med grunderna, implementera scanning i pipelinen och bygg vidare därifrån. Din framtida jag — och dina användare — kommer att tacka dig.
Vill du ha hjälp att optimera er Docker-användning i produktion? Jag erbjuder konsultation inom containerstrategi, CI/CD och molninfrastruktur — läs mer här eller boka ett samtal.
“Skillnaden mellan en ooptimerad 1,2 GB image och en optimerad 80 MB image är inte bara lagringsutrymme — det är säkerhet, hastighet och kostnad i produktion.”
- Simon Axelsson
Vanliga frågor
- Vad är skillnaden mellan Docker och Podman i produktion?
- Podman är daemonless och kör som standard rootless, vilket ger en mindre attackyta. Docker har en central daemon som körs som root, men är mer väletablerad med bättre ekosystem och verktyg. För de flesta team är skillnaden marginell i praktiken. Podman är främst relevant för organisationer med strikta säkerhetskrav som vill ha rootless-containrar som standard.
- Hur minskar jag storleken på mina Docker-images mest effektivt?
- Använd multi-stage builds för att separera bygg- och runtime-miljöer. Välj minimala bas-images som alpine eller distroless. Slå ihop RUN-kommandon för att minska antalet lager. Rensa alltid cache och temporära filer i samma lager som du installerar dem. För Go och Rust kan du använda scratch som bas-image för images under 10 MB.
- Varför är det viktigt med health checks i produktion?
- En container kan vara igång men ändå vara ur funktion — till exempel om applikationen startat men inte kan ansluta till databasen. Health checks låter orkestreringsplattformen kontinuerligt verifiera att applikationen faktiskt svarar och fungerar, och automatiskt starta om containrar som blivit ohälsosamma. Detta är avgörande för hög tillgänglighet.
- Ska jag använda Docker Compose i produktion?
- Docker Compose är utmärkt för utveckling och testmiljöer, men för produktion rekommenderar vi en riktig orkestreringsplattform som Kubernetes, Amazon ECS eller Azure Container Apps. Docker Compose saknar självläkning, skalning, rolling updates och avancerad nätverkskontroll som krävs i produktion.
- Hur hanterar jag hemligheter på ett säkert sätt i Docker?
- Använd Docker BuildKit med --mount=type=secret för hemligheter som behövs vid byggtid. För runtime-hemligheter, använd Kubernetes Secrets, Azure Key Vault, AWS Secrets Manager eller HashiCorp Vault. Ladda in hemligheter vid container-start, aldrig i Dockerfilen. Undvik att kopiera .env-filer in i images.
