--- name: podman description: Manage containers using Podman, the daemonless container engine. Run rootless containers, create pods, manage images, and use Docker-compatible commands. Use when working with Podman or requiring rootless container operations. license: MIT metadata: author: devops-skills version: "1.0" --- # Podman Run and manage containers without a daemon using Podman's rootless container engine. ## When to Use This Skill Use this skill when: - Running containers without root privileges - Managing containers on systems without Docker - Creating pod-based container groups - Using systemd for container management - Working in security-conscious environments ## Prerequisites - Podman installed (4.x+) - For rootless: user namespaces enabled - Basic container concepts understanding ## Key Differences from Docker | Feature | Docker | Podman | |---------|--------|--------| | Architecture | Client-daemon | Daemonless | | Root required | Default | Optional (rootless) | | Pod support | No | Yes (Kubernetes-style) | | Systemd integration | Limited | Native | | Socket | docker.sock | podman.sock (optional) | ## Basic Commands ### Container Operations ```bash # Run container (identical to Docker) podman run -d --name webserver -p 8080:80 nginx # List containers podman ps -a # Stop and remove podman stop webserver podman rm webserver # Execute command podman exec -it webserver /bin/sh # View logs podman logs -f webserver ``` ### Image Management ```bash # Pull image podman pull docker.io/library/nginx:latest # List images podman images # Build image podman build -t myapp:latest . # Push to registry podman push myapp:latest registry.example.com/myapp:latest # Remove image podman rmi nginx:latest ``` ## Rootless Containers ### Setup ```bash # Check user namespace support cat /proc/sys/user/max_user_namespaces # Enable if needed (as root) echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/userns.conf sudo sysctl -p /etc/sysctl.d/userns.conf # Configure subuid/subgid for user sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER # Verify podman unshare cat /proc/self/uid_map ``` ### Running Rootless ```bash # Run as regular user (no sudo) podman run -d --name myapp -p 8080:80 nginx # Check user namespace mapping podman unshare id # Verify non-root podman top myapp user ``` ### Port Considerations ```bash # Rootless cannot bind to ports < 1024 by default # Use ports >= 1024 podman run -d -p 8080:80 nginx # Or enable unprivileged ports (as root) echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/ports.conf sudo sysctl -p /etc/sysctl.d/ports.conf ``` ## Pods ### Creating Pods ```bash # Create pod podman pod create --name mypod -p 8080:80 -p 5432:5432 # Add containers to pod podman run -d --pod mypod --name web nginx podman run -d --pod mypod --name db postgres:15 # List pods podman pod ps # Containers share network namespace podman exec web curl localhost:5432 ``` ### Pod Management ```bash # Start/stop pod (affects all containers) podman pod start mypod podman pod stop mypod # Remove pod and containers podman pod rm -f mypod # View pod details podman pod inspect mypod # Generate Kubernetes YAML from pod podman generate kube mypod > mypod.yaml ``` ## Systemd Integration ### Generate Systemd Unit ```bash # Generate unit file for container podman generate systemd --new --name myapp > ~/.config/systemd/user/container-myapp.service # For pod podman generate systemd --new --name mypod --files # Reload systemd systemctl --user daemon-reload # Enable and start systemctl --user enable --now container-myapp.service ``` ### Quadlet (Podman 4.4+) ```ini # ~/.config/containers/systemd/webapp.container [Container] Image=docker.io/library/nginx:latest PublishPort=8080:80 Volume=webapp-data:/usr/share/nginx/html [Service] Restart=always [Install] WantedBy=default.target ``` ```bash # Reload to generate service systemctl --user daemon-reload # Start the service systemctl --user start webapp ``` ## Compose Compatibility ### Using Podman Compose ```bash # Install podman-compose pip install podman-compose # Run compose file podman-compose up -d # Or use Docker Compose with Podman socket systemctl --user enable --now podman.socket export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock docker-compose up -d ``` ### Native Podman Kube ```bash # Play Kubernetes YAML podman kube play deployment.yaml # Stop and remove podman kube down deployment.yaml ``` ## Networking ### Network Management ```bash # Create network podman network create mynetwork # Run on network podman run -d --network mynetwork --name app myapp # Connect container to network podman network connect mynetwork existing-container # List networks podman network ls # Inspect network podman network inspect mynetwork ``` ### DNS Resolution ```bash # Containers on same network can resolve by name podman run -d --network mynetwork --name db postgres:15 podman run -d --network mynetwork --name app \ -e DATABASE_HOST=db myapp ``` ## Storage ### Volume Management ```bash # Create volume podman volume create mydata # Use volume podman run -d -v mydata:/data myapp # List volumes podman volume ls # Inspect volume podman volume inspect mydata # Rootless volumes location ls ~/.local/share/containers/storage/volumes/ ``` ### Bind Mounts ```bash # Bind mount with SELinux label podman run -v ./data:/app/data:Z myapp # Z = private label (single container) # z = shared label (multiple containers) ``` ## Registry Configuration ### Configure Registries ```bash # Edit registries.conf # ~/.config/containers/registries.conf ``` ```toml unqualified-search-registries = ["docker.io", "quay.io"] [[registry]] prefix = "docker.io" location = "docker.io" [[registry.mirror]] location = "mirror.gcr.io" ``` ### Authentication ```bash # Login to registry podman login docker.io # Login to private registry podman login registry.example.com # Credentials stored in # ~/.config/containers/auth.json ``` ## Building Images ### Buildah Integration ```bash # Podman uses Buildah for builds podman build -t myapp:latest . # Build with specific format podman build --format docker -t myapp . # Multi-stage build podman build --target production -t myapp:prod . ``` ### Buildah Commands ```bash # Create container from scratch buildah from scratch buildah copy working-container ./app /app buildah config --entrypoint '["/app/main"]' working-container buildah commit working-container myapp:minimal ``` ## Common Issues ### Issue: Permission Denied **Problem**: Cannot access files in mounted volumes **Solution**: Use `:Z` or `:z` suffix for SELinux, or check ownership ### Issue: Cannot Connect to Container **Problem**: Port not accessible in rootless mode **Solution**: Use ports >= 1024 or configure unprivileged port start ### Issue: Slow Image Pulls **Problem**: Images download slowly **Solution**: Configure registry mirrors in registries.conf ### Issue: Systemd Service Fails **Problem**: Container doesn't start via systemd **Solution**: Enable lingering: `loginctl enable-linger $USER` ## Best Practices - Use rootless mode for enhanced security - Leverage pods for related containers - Generate systemd units for production - Use Quadlet for declarative container services - Configure SELinux labels for bind mounts - Enable user lingering for persistent services - Use podman auto-update for automatic updates - Alias `docker` to `podman` for compatibility ## Related Skills - [docker-management](../docker-management/) - Docker fundamentals - [kubernetes-ops](../../orchestration/kubernetes-ops/) - K8s orchestration - [container-hardening](../../../security/hardening/container-hardening/) - Security