# Podman (OCI Container) Guide ## Quick Start ```bash # Build podman build -t argparse-builder . # Run rootless podman run -d -p 8080:8080 argparse-builder # Run with SELinux podman run -d -p 8080:8080 --security-opt label=type:container_t argparse-builder ``` ## Podman vs Docker | Feature | Podman | Docker | | ------- | ------------------- | ----------------- | | Daemon | Daemonless | Requires daemon | | Root | Rootless by default | Needs root/group | | SELinux | Native support | Additional config | | Systemd | Native integration | Third-party | | OCI | Full compliance | Mostly compliant | ## Build Commands ### Standard Build ```bash podman build -t argparse-builder . ``` ### Using Containerfile ```bash podman build -f Containerfile -t argparse-builder . ``` ### Multi-architecture ```bash podman build --platform linux/amd64,linux/arm64 -t argparse-builder --manifest argparse-builder . ``` ### Build with cache ```bash podman build --layers -t argparse-builder . ``` ## Rootless Operation ### Setup Rootless Podman ```bash # Install sudo dnf install podman # Configure subuid/subgid (automatic on most systems) grep $(whoami) /etc/subuid grep $(whoami) /etc/subgid # Run rootless podman run -d -p 8080:8080 argparse-builder # Verify podman ps ``` ### Port Binding < 1024 (Rootless) ```bash # Option 1: Use high port and forward podman run -d -p 8080:8080 argparse-builder sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 # Option 2: Set sysctl sudo sysctl net.ipv4.ip_unprivileged_port_start=80 # Option 3: Use systemd socket activation # See systemd section below ``` ## SELinux Configuration ### Run with SELinux ```bash # Default (uses process label) podman run -d -p 8080:8080 argparse-builder # Specific label podman run -d -p 8080:8080 --security-opt label=type:container_t argparse-builder # Disable SELinux for container (not recommended) podman run -d -p 8080:8080 --security-opt label=disable argparse-builder ``` ### Volume Mounts with SELinux ```bash # Auto-label volume (recommended) podman run -d -p 8080:8080 -v ./data:/data:Z argparse-builder # Shared label (multiple containers) podman run -d -p 8080:8080 -v ./data:/data:z argparse-builder # Private label (single container) podman run -d -p 8080:8080 -v ./data:/data:Z argparse-builder ``` ### Check SELinux Context ```bash # Container process podman top label # Volume labels ls -Z ./data ``` ### SELinux Troubleshooting ```bash # Check denials sudo ausearch -m avc -ts recent # Generate policy sudo ausearch -m avc | audit2allow -M my-argparse sudo semodule -i my-argparse.pp # Check booleans getsebool -a | grep container ``` ## Systemd Integration ### Generate Systemd Unit ```bash # Create container podman run -d --name argparse-builder -p 8080:8080 argparse-builder # Generate unit file podman generate systemd --new --name argparse-builder > ~/.config/systemd/user/argparse-builder.service # Enable and start systemctl --user daemon-reload systemctl --user enable --now argparse-builder ``` ### Systemd Unit (Manual) ```ini # ~/.config/systemd/user/argparse-builder.service [Unit] Description=Argparse Builder Container Wants=network-online.target After=network-online.target [Service] Restart=always ExecStartPre=/usr/bin/podman pull argparse-builder:latest ExecStart=/usr/bin/podman run \ --rm \ --name argparse-builder \ -p 8080:8080 \ --security-opt label=type:container_t \ argparse-builder:latest ExecStop=/usr/bin/podman stop -t 10 argparse-builder ExecStopPost=/usr/bin/podman rm -f argparse-builder [Install] WantedBy=default.target ``` ### System-wide Service (requires root) ```bash # Generate for system sudo podman generate systemd --new --name argparse-builder > /etc/systemd/system/argparse-builder.service # Enable and start sudo systemctl daemon-reload sudo systemctl enable --now argparse-builder ``` ## Pod Management ### Create Pod ```bash # Create pod with port mapping podman pod create --name argparse-pod -p 8080:8080 # Run container in pod podman run -d --pod argparse-pod argparse-builder # List pods podman pod ps # Inspect pod podman pod inspect argparse-pod ``` ### Pod with Multiple Containers ```bash podman pod create --name argparse-stack -p 8080:8080 -p 9090:9090 # Application podman run -d --pod argparse-stack argparse-builder # Monitoring (example) podman run -d --pod argparse-stack prom/prometheus ``` ### Pod Systemd Service ```bash podman generate systemd --new --name argparse-pod > argparse-pod.service ``` ## Security Hardening ### Read-only Root ```bash podman run -d -p 8080:8080 --read-only argparse-builder ``` ### No New Privileges ```bash podman run -d -p 8080:8080 --security-opt=no-new-privileges argparse-builder ``` ### Drop Capabilities ```bash podman run -d -p 8080:8080 --cap-drop=ALL argparse-builder ``` ### Resource Limits ```bash podman run -d -p 8080:8080 \ --memory=128m \ --cpus=0.5 \ --pids-limit=100 \ argparse-builder ``` ### Combined Hardening ```bash podman run -d -p 8080:8080 \ --read-only \ --security-opt=no-new-privileges \ --cap-drop=ALL \ --security-opt label=type:container_t \ --memory=128m \ --cpus=0.5 \ argparse-builder ``` ## Networking ### Port Mapping ```bash # Basic podman run -d -p 8080:8080 argparse-builder # Different host port podman run -d -p 3000:8080 argparse-builder # Specific interface podman run -d -p 127.0.0.1:8080:8080 argparse-builder ``` ### Custom Network ```bash # Create network podman network create argparse-net # Run with network podman run -d --network argparse-net -p 8080:8080 argparse-builder # Inspect network podman network inspect argparse-net ``` ### DNS ```bash # Custom DNS podman run -d -p 8080:8080 --dns=8.8.8.8 argparse-builder # Add hosts podman run -d -p 8080:8080 --add-host=api.local:192.168.1.100 argparse-builder ``` ## Storage and Volumes ### Named Volume ```bash # Create volume podman volume create argparse-data # Use volume with SELinux podman run -d -p 8080:8080 -v argparse-data:/data:Z argparse-builder # Inspect volume podman volume inspect argparse-data ``` ### Bind Mount ```bash # Auto-label (Z) podman run -d -p 8080:8080 -v ./logs:/app/logs:Z argparse-builder # Shared label (z) - multiple containers podman run -d -p 8080:8080 -v ./shared:/shared:z argparse-builder ``` ### tmpfs Mount ```bash podman run -d -p 8080:8080 --tmpfs /tmp:rw,size=64m,mode=1777 argparse-builder ``` ## Health and Monitoring ### Health Check ```bash # Check health status podman healthcheck run argparse-builder # View logs podman logs argparse-builder # Stats podman stats argparse-builder # Top processes podman top argparse-builder ``` ### Inspect Container ```bash # Full inspect podman inspect argparse-builder # Specific field podman inspect --format='{{.State.Health.Status}}' argparse-builder ``` ## Registry Operations ### Login ```bash # Docker Hub podman login docker.io # GitHub Container Registry podman login ghcr.io # Private registry podman login registry.example.com ``` ### Tag and Push ```bash # Tag podman tag argparse-builder ghcr.io/username/argparse-builder:latest # Push podman push ghcr.io/username/argparse-builder:latest ``` ### Pull ```bash # Pull image podman pull ghcr.io/username/argparse-builder:latest # Pull specific platform podman pull --platform linux/arm64 ghcr.io/username/argparse-builder:latest ``` ## Podman Compose ### Install ```bash pip3 install podman-compose ``` ### podman-compose.yml ```yaml version: "3" services: argparse-builder: build: . ports: - "8080:8080" restart: unless-stopped security_opt: - label=type:container_t - no-new-privileges read_only: true cap_drop: - ALL resources: limits: cpus: "0.5" memory: 128M ``` ### Usage ```bash podman-compose up -d podman-compose logs -f podman-compose down ``` ## Kubernetes with Podman ### Generate K8s YAML ```bash # From container podman generate kube argparse-builder > argparse-k8s.yaml # From pod podman generate kube argparse-pod > argparse-pod-k8s.yaml ``` ### Play Kubernetes YAML ```bash # Create from YAML podman play kube argparse-k8s.yaml # Remove podman play kube --down argparse-k8s.yaml ``` ## Migration from Docker ### Pull Docker Images ```bash podman pull docker.io/library/nginx ``` ### Docker Compatibility ```bash # Use docker command (alias) alias docker=podman # Docker socket emulation podman system service --time=0 unix:///tmp/podman.sock export DOCKER_HOST=unix:///tmp/podman.sock ``` ### Convert docker-compose ```bash # Most docker-compose files work with podman-compose podman-compose -f docker-compose.yml up ``` ## Troubleshooting ### Permission Denied (Rootless) ```bash # Check subuid/subgid grep $(whoami) /etc/subuid /etc/subgid # Verify user namespaces podman unshare cat /proc/self/uid_map # Reset storage podman system reset ``` ### SELinux Denials ```bash # Check denials sudo ausearch -m avc -ts recent | grep podman # Temporary permissive mode (troubleshooting) sudo setenforce 0 # Re-enable sudo setenforce 1 ``` ### Port Already in Use ```bash # Find what's using port ss -tulpn | grep 8080 # Use different port podman run -d -p 8081:8080 argparse-builder ``` ### Storage Issues ```bash # Check storage podman system df # Clean up podman system prune -a # Reset storage podman system reset ``` ## Performance Tuning ### Storage Driver ```bash # Check current driver podman info --format '{{.Store.GraphDriverName}}' # Use overlay (default, best performance) # Already configured in /etc/containers/storage.conf ``` ### Network Performance ```bash # Use host network (best performance, less isolation) podman run -d --network host argparse-builder ``` ### Build Cache ```bash # Use buildah cache podman build --layers -t argparse-builder . ``` ## CI/CD Integration ### GitLab CI ```yaml build: image: quay.io/podman/stable services: - podman:dind script: - podman build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA . - podman push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA ``` ### GitHub Actions ```yaml - name: Build with Podman run: | podman build -t argparse-builder . podman tag argparse-builder ghcr.io/${{ github.repository }}:latest podman push ghcr.io/${{ github.repository }}:latest ``` ## Best Practices 1. **Use Rootless** - Run as regular user by default 2. **SELinux** - Keep enabled, use :Z/:z for volumes 3. **Systemd** - Use `podman generate systemd` for services 4. **Security** - Use `--read-only`, `--cap-drop=ALL`, labels 5. **OCI** - Use Containerfile (compatible with Dockerfile) 6. **Pods** - Group related containers in pods 7. **Health Checks** - Include in Containerfile 8. **Resources** - Set limits with `--memory`, `--cpus` ## Quick Reference ```bash # Build podman build -t name . # Run podman run -d -p 8080:8080 name # SELinux volume podman run -v ./data:/data:Z name # Systemd podman generate systemd --new name # Rootless podman run --userns=keep-id name # Pod podman pod create -p 8080:8080 podman run --pod podname name ```