GuiderBörja härPodman utan root

Kör containrar utan root med Podman på Debian

Podman på Debian 13 där varje app körs under en egen användare utan privilegier, startar som systemd-tjänst vid uppstart, uppdateras automatiskt och nås över HTTPS via en gemensam Caddy.

Testad på Podman 5.4 på Debian 13 (trixie) på en server hos Melonslab Steg 4 av 4 för nybörjare Uppdaterad 25 september 2026

Rekommenderad server för guiden

VC-S Micro · 2 vCPU · 8 GB Minne · 250 GB Lagring

Månadsvis, ingen bindningstid 7 dagars öppet köp

90 kr/mån

Beställ nu
På den här sidan

Det här sätter du upp

Podman kör containrar ungefär som Docker, men utan en bakgrundstjänst som körs som root. Här körs containrarna som vanliga användare, så kallat rootless, och varje app får en egen användare:

  • Root inne i en container är appens användare utanför, så den som tar sig ut ur en container får inte fler rättigheter på servern än den användaren har.
  • Varje användare har ett eget intervall av användar-id:n, så en apps containrar kan inte läsa en annan apps filer.

Bara en app kan äga port 80 och 443, så de går till Caddy, en webbserver med en egen användare. Caddy hämtar HTTPS-certifikat för varje webbplats på servern och skickar varje besökare vidare till rätt app, som lyssnar på en lokal port som inte går att nå från internet.

Appguiderna bygger på den här: Nextcloud, Matrix, Vaultwarden, Actual Budget, Stalwart, en mailserver, Forgejo, en Git-server, Helium-tjänsterna, för webbläsaren Helium, Headscale, en styrserver för Tailscale, Hermes Agent, en AI-agent, FreeRADIUS, för inloggning på wifi, authentik, en gemensam inloggning för alla dina appar, ERPNext, för bokföring och fakturering, Zabbix, för att övervaka dina servrar, Uptime Kuma, för att övervaka dina webbplatser, Linkwarden, för bokmärken, Immich, för bilder, Home Assistant, för ditt smarta hem, AdGuard Home, för att blockera annonser och spårare, Minecraft, en spelserver, Portainer, ett webbgränssnitt för dina containrar, OpenClaw, en AI-assistent, Plausible och Umami, för webbstatistik, n8n, för automatisering, Paperless-ngx, för dokument, Jellyfin och Navidrome, för film och musik, SearXNG, en privat sökmotor, Open WebUI, en AI-chatt, BookStack, en wiki, Stirling-PDF, för PDF-verktyg, ntfy, för pushnotiser, Garage, för S3-lagring, Prometheus och Grafana, för övervakning, RustDesk, för fjärrskrivbord, och k3s, en liten Kubernetes som körs utan root bakom samma Caddy. Varje steg nedan har körts på en nyinstallerad server hos Melonslab med Debian 13.

Innan du börjar

Du behöver en server med Debian 13 och root-åtkomst. Är den ny, säkra den först.

1. Installera Podman

apt update
apt install -y podman systemd-container

Med Podman följer pasta, som kopplar rootless-containrar till nätverket. systemd-container innehåller machinectl, som du använder för att arbeta som varje apps användare.

2. Tillåt port 80 och 443

Linux reserverar portarna under 1024 för root. Tillåt vanliga användare att använda portarna från 80 och uppåt, så att Caddy kan lyssna på dem:

echo "net.ipv4.ip_unprivileged_port_start = 80" > /etc/sysctl.d/50-unprivileged-ports.conf
sysctl --system

Inställningen gäller även IPv6.

3. Skapa en användare för Caddy

Varje app börjar på samma sätt, med en egen användare. För Caddy:

useradd -m -s /bin/bash caddy
loginctl enable-linger caddy

Debian ger varje ny användare ett eget intervall av 65 536 extra användar-id:n, som Podman använder till användarna inne i containrarna; cat /etc/subuid listar varje användares intervall. enable-linger startar användarens tjänster vid uppstart, utan att någon loggar in.

4. Arbeta som användaren

machinectl shell caddy@

machinectl shell startar en riktig inloggningssession för användaren, vilket systemctl --user och Podman behöver. exit tar dig tillbaka till root.

5. Kör Caddy som en tjänst

Podmans Quadlet gör om en kort fil som beskriver en container till en systemd-tjänst. Som caddy skapar du katalogen för de här filerna:

mkdir -p ~/.config/containers/systemd

Skapa ~/.config/containers/systemd/caddy.container:

[Unit]
Description=Caddy, the web server in front of every app

[Container]
ContainerName=caddy
Image=docker.io/library/caddy:2
Network=host
Volume=%h/Caddyfile:/etc/caddy/Caddyfile:ro
Volume=caddy-data:/data
AutoUpdate=registry

[Service]
Restart=always

[Install]
WantedBy=default.target

Och ~/Caddyfile, Caddys konfiguration:

{
    admin off
}

# One block per site. The app guides add theirs below.
:80 {
    respond "Caddy is running"
}

Starta den:

systemctl --user daemon-reload
systemctl --user start caddy

Öppna http://203.0.113.10 (din servers adress) i en webbläsare. "Caddy is running" betyder att Caddy svarar på port 80 som användaren caddy.

Vad raderna gör:

  • Network=host sätter Caddy på serverns eget nätverk, så att den ser varje besökares riktiga IP-adress och når apparna på 127.0.0.1. Det är den enda containern som nås direkt från internet.
  • admin off stänger av Caddys admingränssnitt, som annars skulle låta vilken användare som helst på servern ändra dess konfiguration. Ändringar i Caddyfile gäller då när du startar om Caddy.
  • Image skrivs ut helt, med registret, så att det inte råder något tvivel om var avbilden kommer ifrån.
  • AutoUpdate=registry låter Podman uppdatera containern när en nyare avbild publiceras (steg 6).
  • WantedBy=default.target startar den vid uppstart. Tjänster som skapas från Quadlet-filer kan inte slås på med systemctl enable; den här raden gör det i stället.

6. Håll containrarna uppdaterade

systemctl --user enable --now podman-auto-update.timer

En gång om dagen letar Podman efter en nyare avbild för varje container med AutoUpdate=registry och startar om dem som har ändrats. Om en container inte startar med den nya avbilden går Podman tillbaka till den förra. Timern gäller per användare, så slå på den som varje apps användare. Så här ser du vad den skulle uppdatera just nu:

podman auto-update --dry-run

7. Så passar en app in

Varje appguide följer samma mönster:

  1. Som root skapar du appens användare med de två raderna från steg 3 och byter till den med machinectl shell.
  2. Som den användaren kör du appen, i en pod eller som en enskild container, och publicerar en port på bara 127.0.0.1, till exempel PublishPort=127.0.0.1:8081:80. Guiderna ger varje app en egen port.
  3. Som caddy lägger du till ett block för appens adress i ~/Caddyfile och startar om Caddy med systemctl --user restart caddy. Caddy hämtar certifikatet själv.

Två saker gäller för varje app bakom Caddy:

  • Inne i appens pod eller container ser Caddys anslutningar ut att komma från serverns egen IPv4-adress, 203.0.113.10 i de här exemplen. Det är så pasta vidarebefordrar lokala anslutningar, och därför är det den adressen appen ska lita på som proxy för att få fram besökarens riktiga adress.
  • Inne i podden tillhör serverns egen adress själva podden, så en app som anropar sin egen publika adress skulle nå sig själv i stället för Caddy. AddHost=cloud.example.com:host-gateway i poddfilen skickar det namnet till servern i stället.

8. Vardagliga kommandon

Som användaren som äger containern:

podman ps                        # containrar som körs
systemctl --user status caddy    # tjänsten
journalctl --user -u caddy       # dess logg
systemctl --user restart caddy   # starta om den

Felsökning

systemctl --user visar "Failed to connect to user scope bus". Du bytte användare med su eller sudo, som inte startar någon inloggningssession. Använd machinectl shell caddy@ från steg 4.

Caddy startar inte, och loggen visar "bind: permission denied". Steg 2 saknas eller har inte lästs in; sysctl net.ipv4.ip_unprivileged_port_start ska skriva ut 80. När det är åtgärdat kör du systemctl --user reset-failed caddy, så att systemd kan starta Caddy igen: systemd ger upp efter några misslyckade starter.

Alla besökare har samma IP-adress i appen. Kontrollera att appen litar på serverns egen IPv4-adress som proxy (steg 7). Containrar som är kopplade till ett Podman-nätverk (Network= i filen) har det ännu sämre: deras portar går genom en vidarebefordrare som byter ut besökarens adress mot sin egen, vilket är skälet till att appguiderna använder poddar i stället.

apt väntar på ett lås direkt efter serverns första uppstart. Servern installerar sina första uppdateringar. Vänta en minut och försök igen.

Kör det på din egen server

VC-S Micro

90 kr/mån

vCPU
2
Minne
8 GB
Lagring
250 GB
Trafik
10 TB
Standard
HDD · RAID 10
  • Full root-åtkomst
  • Nativt /64 IPv6
  • RAID-skyddad lagring
  • Malmö, Sverige
  • Månadsvis, ingen bindningstid
  • 7 dagars öppet köp
Alla guider