Det korta svaret
Välj Docker om programmet du vill köra kräver det, som Coolify, Dokploy eller Pterodactyl, eller om du vill använda ett projekts compose.yaml och instruktioner som de är. Docker har bredast stöd av de två, och den mesta dokumentationen utgår från det.
Välj Podman utan root för appar du själv kör på en server som syns på internet. Varje app körs under en egen användare, så ett utbrott ur en container ger den användaren och inte root, publicerade portar stannar bakom brandväggen, och systemd sköter uppdateringar och omstarter. Det kräver mer arbete för varje app.
Det här testade vi
Båda kördes på samma VC-P Alloy (2 vCPU, 8 GB) hos Melonslab med Debian 13, samtidigt, uppsatta precis som i våra guider: Podman utan root med Caddy som användaren caddy, och Docker från Dockers eget paketförråd. Servern säkrades först som i säkerhetsguiden, med ufw som bara släppte in portarna 22, 80 och 443.
Appen var Miniflux 2.3.3, en liten flödesläsare skriven i Go, med PostgreSQL 17 för sina data:
- Docker: en
compose.yamli/opt/minifluxmed två tjänster, lösenorden som Compose-hemligheter från filer, och appen publicerad på127.0.0.1:8083. - Podman: en pod under en egen användare,
miniflux, från tre Quadlet-filer, lösenorden sompodman secret, och appen publicerad på127.0.0.1:8084.
Samma Caddy, som körs utan root som caddy, serverade båda över HTTPS med certifikat från Let's Encrypt. I båda lade vi till ett flöde via Minifluxs API över HTTPS och läste tillbaka inläggen. Sedan testade vi en uppdatering, en omstart, brandväggen och ett utbrott ur en container.
| Docker | Podman utan root | |
|---|---|---|
| Version | Docker 29.9.0, Compose 5.6.0 | Podman 5.4.2, från Debian |
| Installation enligt vår guide | 28 sekunder, 35 paket från Dockers paketförråd | 26 sekunder, 46 paket från Debian |
| Containrar för appen | 2 | 3 (med poddens lilla infra-container) |
| Minne, appens containrar | 71 MB | 72 MB |
| Minne, det som kör dem | 178 MB, en gång för servern | 33 MB, för varje apps användare |
| Disk, avbilder och data | 712 MB | 541 MB |
| Port publicerad på alla adresser, ingen regel i ufw | öppen mot internet | stängd av ufw |
| Root i en container, efter ett utbrott | root på servern | appens egen användare |
| Automatiska uppdateringar av avbilder | inte inbyggt | podman auto-update, en gång om dagen |
| Tillbaka efter en omstart | ja, efter en misslyckad start av appen | ja, i rätt ordning |
Minnet är processernas proportionella minne (PSS), i vila, efter en omstart. Disken är /var/lib/docker och /var/lib/containerd för Docker, och användaren minifluxs ~/.local/share/containers för Podman.
Installation
Båda installeras på under en halv minut. Podman är en enda apt install från Debian. Docker kräver några steg till: Dockers signeringsnyckel, dess paketförråd och sedan paketen. Debians eget paket docker.io är äldre, så vår guide använder Dockers.
Sedan skiljer sig hur mycket varje app kräver:
- Docker: en katalog och en
compose.yaml.docker compose up -dstartar appen, som root. - Podman: en Linux-användare med linger påslaget, sedan en
.pod-fil och en.container-fil för varje container, i användarens~/.config/containers/systemd. Du arbetar som användaren medmachinectl shell. Det blir fler filer, och inställningarna heter annat än i Compose:PublishPort=i stället förports:,Secret=i stället försecrets:.
Här är Docker helt enkelt lättare. Ett projekt som levererar en compose.yaml fungerar som det är, medan du själv får skriva om den till Quadlet-filer för Podman.
Compose
Compose-filer fungerar också med Podman utan root. Som användaren miniflux körde vi exakt samma compose.yaml som i Docker-testet, med hemligheter, hälsokontroll och depends_on, på två sätt:
podman compose up -d, med Dockers Compose-tillägg installerat, eftersystemctl --user enable --now podman.socket. Podman lämnar filen till Docker Compose 5.6.0, som pratar med Podmans socket i stället för Docker.podman-compose up -d, från Debians paketpodman-compose, version 1.3.0, utan något från Docker.
Båda startade appen, och den svarade. Men de containrarna får inte det Quadlet ger: ingen systemd-tjänst för varje container, och inga automatiska uppdateringar. Därför använder våra guider Quadlet-filer. Större Compose-filer, med byggsteg, profiler eller funktioner som podman-compose saknar, kan behöva ändras; vi testade bara den här.
Portar och brandväggen
Det här är skillnaden som oftast överraskar. Med ufw som bara släppte in 22, 80 och 443 publicerade vi en testcontainer på port 8080 i Docker och på 8090 i Podman utan root, på alla adresser:
docker run -d --name test -p 8080:80 traefik/whoami
podman run -d --name test -p 8090:80 docker.io/traefik/whoami:v1.11.0
Från en dator någon annanstans på internet svarade port 8080, men inte port 8090. ufw status visade ingen regel för någon av dem.
Docker skickar en publicerad port vidare till containern i sina egna nat-regler, innan ufw:s regler kontrolleras. Dockers dokumentation säger samma sak: trafiken till containern leds om innan den passerar ufw. Podman utan root kan inte ändra serverns brandvägg. Dess publicerade port är en vanlig lyssnande socket som ägs av pasta, som körs som användaren, så ufw behandlar den som vilket program som helst.
Med Docker stänger du sådana portar själv: publicera på 127.0.0.1, eller lägg regler i kedjan DOCKER-USER. Vår Docker-guide har en systemd-tjänst för det; med den slutade port 8080 svara.
Ett utbrott ur en container
Ett utbrott är en bugg, i kärnan eller i containerprogrammen, som låter en process i en container påverka själva servern. Vad den då får beror på vem processen är utanför containern.
Vi använde ingen riktig exploit. I stället gav vi en container det ett utbrott skulle ge den, alla rättigheter och serverns processer, och bad om ett skal i serverns egna namnrymder:
docker run --rm --privileged --pid=host alpine nsenter -t 1 -m -u -i -n -p -- sh -c 'id; head -c 10 /etc/shadow'
I Docker blev skalet root på servern: uid=0(root), med serverns värdnamn och första raden i /etc/shadow. Som användaren miniflux stannade samma kommando i Podman vid nsenter: can't open '/proc/1/ns/ipc': Permission denied.
Vi monterade också hela serverns filsystem i en container, med -v /:/host. Dockers container läste /etc/shadow och skapade en fil i /root, ägd av root. Podmans fick Permission denied för /etc/shadow, /root och användaren caddys hemkatalog, även med --privileged.
Förklaringen syns på servern. I Docker är användar-id:n i en container samma utanför: Miniflux kördes som nobody (65534) och PostgreSQL som 999, samma id:n som på servern, och root i en container är root. I Podman utan root är root i containern användaren miniflux, och alla andra id:n kommer från den användarens eget intervall: PostgreSQL kördes som 166534 och Miniflux som 231069, id:n som inte äger något annat på servern.
Docker har eget skydd mot utbrott, AppArmor- och seccomp-profiler som var påslagna från början, och ett eget läge utan root som vi inte testade. Den som kan köra docker styr servern, så lägg inte till användare i gruppen docker om du inte skulle ge dem root.
Resurser
Appens egna containrar använde lika mycket minne i båda, 71 och 72 MB. Det som kör dem skiljer sig:
- Docker:
dockerdanvände 96 MB,containerd53 MB, en shim per container 22 MB sammanlagt, ochdocker-proxy7 MB, totalt 178 MB. Det kostar en gång, hur många appar du än kör, och ligger kvar i minnet även utan containrar. - Podman: det finns ingen daemon. Varje container har en
conmonpå ungefär en halv megabyte. Användarens nätverkshjälp,pasta, använde 25 MB, och användarens egen systemd och D-Bus 7 MB, totalt 33 MB. Det kostar igen för varje app, eftersom varje app har en egen användare.
Med många små appar närmar sig de två varandra; med en handfull använder Podman mindre. På en Alloy märks ingen av dem.
Dockers avbilder och data tog 712 MB, mot Podmans 541 MB för samma två avbilder. Docker 29 lagrar avbilder i containerds lager, som håller både de nedladdade lagren och de uppackade.
Uppdateringar och säkerhetskopior
Appen. Med AutoUpdate=registry i Quadlet-filerna och användarens podman-auto-update.timer letar Podman en gång om dagen efter en nyare avbild med samma tagg, och startar om appen när den hittar en. För att testa gav vi båda uppsättningarna PostgreSQL 17.10 under taggen 17. podman auto-update uppdaterade till 17.11 på 5 sekunder och startade om podden. Startar den nya containern inte, går Podman tillbaka till den gamla av sig självt.
Docker har inget motsvarande. docker compose pull och docker compose up -d uppdaterade samma container på 15 sekunder, men bara för att vi körde dem. Watchtower, verktyget som länge användes för det här, är arkiverat på GitHub sedan 17 december 2025 och underhålls inte längre.
Själva programmen. Podman kommer från Debian, så de automatiska säkerhetsuppdateringarna från säkerhetsguiden täcker det. Docker kommer från ett eget paketförråd och uppdateras bara automatiskt om du lägger till det, som i Docker-guiden. Vi kontrollerade att Dockers källa då kom med.
Säkerhetskopior fungerar likadant: pg_dump via docker compose exec eller podman exec gav en dump av databasen i båda. Dockers volymer ligger under /var/lib/docker/volumes. Podmans ligger i användarens hemkatalog, men ägs av id:n från användarens intervall, så användaren läser dem via podman unshare eller podman volume export, inte direkt.
Loggar och omstarter
Loggar. Podmans containrar loggar till journalen: journalctl --user -u miniflux-app som användaren. Journalen begränsar sin egen storlek. Docker har egna loggfiler, som du läser med docker compose logs, och de växer utan gräns tills du ställer in rotation i /etc/docker/daemon.json, som Docker-guiden gör.
Omstarter. Båda kom tillbaka av sig själva, och båda webbplatserna svarade inom en minut efter omstarten. Docker startade båda containrarna samtidigt: Miniflux försökte nå databasen innan PostgreSQL var redo, misslyckades med connection refused, och Dockers omstartsregel startade den igen. depends_on med service_healthy gäller bara för docker compose up, inte när Docker startar containrar vid uppstart. Podman startade databasen först och appen när PostgreSQL rapporterade att den var frisk, som Quadlet-filerna säger med Requires=, After= och Notify=healthy. För Miniflux gjorde den extra omstarten ingen skada.
Licens och kostnad
Båda är öppen källkod under Apache License 2.0, enligt projektens kodförråd när vi kontrollerade den 14 oktober 2026. Docker Engine byggs från projektet Moby av Docker, Inc. Podmans webbplats drivs av Podman Container Tools, en del av LF Projects under Linux Foundation. Ingen av dem kostar något på en server. Docker, Inc. säljer abonnemang för Docker Desktop och Docker Hub; Engine, som används här, behöver inget av dem.
Båda använde samma avbilder från Docker Hub här, med dess gränser för hämtningar utan konto. Docker fyller i docker.io för ett kort namn som postgres:17; våra Podman-guider skriver ut varje avbilds hela namn, som docker.io/library/postgres:17.
Vilken ska du välja?
- Docker, om programmet kräver det, om du följer ett projekts egna Compose-instruktioner, eller om du använder Dockers verktyg och ekosystem. Stäng de publicerade portarna som i Installera Docker på Debian, och se gruppen
dockersom root. En VC-P Alloy körde Docker och den här appen med god marginal. - Podman utan root, för appar du själv driftar, med en användare för varje, särskilt där ett utbrott inte får kosta dig servern. Börja med Kör containrar utan root med Podman; våra appguider, som BookStack, bygger alla på den. En VC-P Alloy passar för det också.
Du kan köra båda på samma server, som vi gjorde. Håll isär deras portar, och låt en enda webbserver, som Caddy, ha portarna 80 och 443 för båda.