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=hostsä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 offstä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.Imageskrivs ut helt, med registret, så att det inte råder något tvivel om var avbilden kommer ifrån.AutoUpdate=registrylåter Podman uppdatera containern när en nyare avbild publiceras (steg 6).WantedBy=default.targetstartar den vid uppstart. Tjänster som skapas från Quadlet-filer kan inte slås på medsystemctl 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:
- Som root skapar du appens användare med de två raderna från steg 3 och byter till den med
machinectl shell. - 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 exempelPublishPort=127.0.0.1:8081:80. Guiderna ger varje app en egen port. - Som
caddylägger du till ett block för appens adress i~/Caddyfileoch startar om Caddy medsystemctl --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.10i 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-gatewayi 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.