Files
argparser/docs/podman.md

11 KiB

Podman (OCI Container) Guide

Quick Start

# 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

podman build -t argparse-builder .

Using Containerfile

podman build -f Containerfile -t argparse-builder .

Multi-architecture

podman build --platform linux/amd64,linux/arm64 -t argparse-builder --manifest argparse-builder .

Build with cache

podman build --layers -t argparse-builder .

Rootless Operation

Setup Rootless Podman

# 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)

# 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

# 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

# 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

# Container process
podman top <container> label

# Volume labels
ls -Z ./data

SELinux Troubleshooting

# 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

# 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)

# ~/.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)

# 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

# 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

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

podman generate systemd --new --name argparse-pod > argparse-pod.service

Security Hardening

Read-only Root

podman run -d -p 8080:8080 --read-only argparse-builder

No New Privileges

podman run -d -p 8080:8080 --security-opt=no-new-privileges argparse-builder

Drop Capabilities

podman run -d -p 8080:8080 --cap-drop=ALL argparse-builder

Resource Limits

podman run -d -p 8080:8080 \
    --memory=128m \
    --cpus=0.5 \
    --pids-limit=100 \
    argparse-builder

Combined Hardening

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

# 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

# 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

# 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

# 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

# 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

podman run -d -p 8080:8080 --tmpfs /tmp:rw,size=64m,mode=1777 argparse-builder

Health and Monitoring

Health Check

# 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

# Full inspect
podman inspect argparse-builder

# Specific field
podman inspect --format='{{.State.Health.Status}}' argparse-builder

Registry Operations

Login

# Docker Hub
podman login docker.io

# GitHub Container Registry
podman login ghcr.io

# Private registry
podman login registry.example.com

Tag and Push

# Tag
podman tag argparse-builder ghcr.io/username/argparse-builder:latest

# Push
podman push ghcr.io/username/argparse-builder:latest

Pull

# 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

pip3 install podman-compose

podman-compose.yml

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

podman-compose up -d
podman-compose logs -f
podman-compose down

Kubernetes with Podman

Generate K8s YAML

# From container
podman generate kube argparse-builder > argparse-k8s.yaml

# From pod
podman generate kube argparse-pod > argparse-pod-k8s.yaml

Play Kubernetes YAML

# Create from YAML
podman play kube argparse-k8s.yaml

# Remove
podman play kube --down argparse-k8s.yaml

Migration from Docker

Pull Docker Images

podman pull docker.io/library/nginx

Docker Compatibility

# 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

# Most docker-compose files work with podman-compose
podman-compose -f docker-compose.yml up

Troubleshooting

Permission Denied (Rootless)

# 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

# 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

# Find what's using port
ss -tulpn | grep 8080

# Use different port
podman run -d -p 8081:8080 argparse-builder

Storage Issues

# Check storage
podman system df

# Clean up
podman system prune -a

# Reset storage
podman system reset

Performance Tuning

Storage Driver

# Check current driver
podman info --format '{{.Store.GraphDriverName}}'

# Use overlay (default, best performance)
# Already configured in /etc/containers/storage.conf

Network Performance

# Use host network (best performance, less isolation)
podman run -d --network host argparse-builder

Build Cache

# Use buildah cache
podman build --layers -t argparse-builder .

CI/CD Integration

GitLab CI

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

- 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

# 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