Podman as Docker Alternative
Podman (Pod Manager) is a daemonless contenedor engine that proporciona Docker-compatible functionality without requiring a privileged daemon process. Esta guía cubre installing Podman, configuring rootless contenedores, managing pods, achieving Docker compatibility, integrating with systemd, and deploying containerized applications. Podman offers superior security through rootless operation while maintaining API compatibility with Docker, making it an attractive alternative for many deployment scenarios.
Tabla de Contenidos
- Comprendiendo Podman
- Installing Podman
- Podman vs Docker
- Rootless Contenedor Operations
- Gestionando Pods with Podman
- Docker Compatibility
- Systemd Integration
- Podman Compose
- Avanzado Podman Features
- Conclusión
Comprendiendo Podman
Podman is a contenedor engine and pod orchestration tool that runs contenedores as regular user processes without a daemon. Key characteristics:
- Daemonless architecture: No privileged servicio running constantly
- Rootless capable: Contenedores run as unprivileged users
- Docker API compatible: Works with Docker CLI commands
- Supports pods: Groups related contenedores together
- Systemd integration: Native servicio unit management
- OCI compliant: Uses standard contenedor formats
# Check Podman version
podman --version
# View system information
podman info
# Check Podman configuration
podman system info | head -20
# Display Podman help
podman --help
Architectural differences:
- Docker: Client-server with privileged daemon
- Podman: Daemonless architecture, direct contenedor process management
- Security: Podman rootless eliminates privilege escalation vector
- Process management: Podman integrates with user processes
Installing Podman
Instala Podman across different Linux distributions.
Ubuntu/Debian installation:
# Actualiza package manager
sudo apt-get update
# Instala Podman
sudo apt-get install -y podman
# Verifica installation
podman --version
# Instala additional tools
sudo apt-get install -y \
podman-docker \
podman-compose \
slirp4netns \
uidmap
# Check system capabilities
podman system info | grep rootless
CentOS/RHEL installation:
# Habilita contenedor tools repositorio
sudo dnf install -y centos-release-stream-contenedor-tools
# Instala Podman
sudo dnf install -y podman podman-compose
# Verifica installation
podman --version
# Habilita podman socket for API access
sudo systemctl enable --now podman.socket
# Check socket availability
sudo ls -la /run/podman/podman.sock
Fedora installation:
# Instala Podman (usually pre-installed)
sudo dnf install -y podman
# Instala additional components
sudo dnf install -y \
podman-docker \
podman-compose \
slirp4netns \
fuse-overlayfs
# Verifica all components installed
podman --version
podman-compose --version
Alpine Linux installation:
# Actualiza apk cache
apk update
# Instala Podman
apk add podman
# Instala additional tools
apk add podman-docker podman-compose slirp4netns fuse-overlayfs
# Check installation
podman --version
Verifica installation and setup:
# Prueba basic Podman functionality
podman run --rm alpine echo "Podman works!"
# Check for required namespaces
grep subuid /etc/subuid
grep subgid /etc/subgid
# View runtime information
podman info --format="{{.Host.Runtime}}"
Podman vs Docker
Understand key differences between Podman and Docker.
Comparison table:
# Feature comparison
cat > podman_vs_docker.txt <<'EOF'
Feature | Podman | Docker
Architecture | Daemonless | Daemon-based
Privilege | Rootless ready | Requires root
Pods | Native support | Via Kubernetes
API compatibility | High | Source compatible
Imagen format | OCI | OCI
Red driver | CNI | libnetwork
Orchestration | Systemd | Swarm/K8s
Instalación | Lightweight | Full daemon
Performance | Lower overhead | Established
Community | Growing | Large
EOF
cat podman_vs_docker.txt
Docker command to Podman migration:
# Crea docker alias if switching from Docker
alias docker=podman
# Or setup docker client pointing to Podman socket
export DOCKER_HOST=unix:///run/podman/podman.sock
# Ejecuta equivalent commands
podman run -d --name web -p 8080:80 nginx:latest
podman ps
podman logs web
podman exec web curl localhost
# Detén and remove
podman stop web
podman rm web
Pulling and running contenedores:
# Pull imagen from Docker Hub
podman pull alpine:latest
# List imágenes
podman imágenes
# Ejecuta contenedor
podman run -it alpine:latest sh
# Ejecuta in background
podman run -d --name myapp -p 5000:5000 myapp:latest
# Check running contenedores
podman ps
# View logs
podman logs myapp
# Ejecuta command in contenedor
podman exec myapp curl localhost:5000
Rootless Contenedor Operations
Ejecuta contenedores as unprivileged users for enhanced security.
Configuración rootless Podman:
# Check user capabilities
cat /etc/subuid
cat /etc/subgid
# If empty, configure user subordinate IDs
sudo usermod --add-subuids 100000-165535 $USER
sudo usermod --add-subgids 100000-165535 $USER
# Verifica configuration
grep $USER /etc/subuid /etc/subgid
# Initialize rootless Podman
podman system migrate
# Ejecuta test contenedor as regular user
podman run --rm alpine echo "Rootless Podman works!"
# Check running as user
ps aux | grep conmon
Rootless networking configuration:
# Check rootless red mode
podman info | grep -i red
# Verifica slirp4netns available
which slirp4netns
# Crea red for rootless contenedores
podman red create mynet
# Ejecuta contenedor on custom red
podman run -d \
--name web \
--red mynet \
-p 8080:80 \
nginx:latest
# Prueba connectivity
curl http://localhost:8080
# Inspect red details
podman red inspect mynet
# List redes
podman red ls
User namespace remapping:
# Check current user mapping
cat /etc/subuid | head
# View subordinate user IDs
grep $USER /etc/subuid
# Contenedor processes map to high UID ranges
# Process shows as UID 0 inside contenedor
# But runs as high UID on host system
# Example: Inicia contenedor and verifica UIDs
podman run -d --name test alpine sleep 1000
# Inside contenedor
podman exec test id # uid=0(root) gid=0(root)
# On host
ps aux | grep sleep | grep -v grep # Shows high UID
Rootless socket activation:
# Habilita user servicio for Podman socket
systemctl --user enable podman.socket
systemctl --user start podman.socket
# Verifica socket availability
ls -la /run/user/$(id -u)/podman/podman.sock
# Set DOCKER_HOST for Docker CLI compatibility
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock
# Prueba with Docker CLI
docker ps
# Persist environment variable
echo 'export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock' >> ~/.bashrc
source ~/.bashrc
Gestionando Pods with Podman
Crea and manage pods, which group related contenedores.
Crea and manage pods:
# Crea a pod
podman pod create \
--name myapp-pod \
-p 8080:8080 \
-p 5432:5432
# List pods
podman pod ls
# Inspect pod details
podman pod inspect myapp-pod
# Add contenedor to pod
podman run -d \
--pod myapp-pod \
--name web \
nginx:latest
# Add another contenedor to same pod
podman run -d \
--pod myapp-pod \
--name api \
myapi:latest
# Contenedores in pod share red namespace
# Can communicate via localhost
# View pod details
podman pod stats myapp-pod
# Detén pod (stops all contenedores)
podman pod stop myapp-pod
# Remueve pod
podman pod rm myapp-pod
Multi-contenedor pod example:
# Crea pod with specific configuration
podman pod create \
--name webapp \
--publish 80:80 \
--publish 443:443 \
--dns 8.8.8.8 \
--add-host db.internal:10.0.0.2
# Crea database contenedor in pod
podman run -d \
--pod webapp \
--name postgres \
--env POSTGRES_PASSWORD=secret \
postgres:15
# Crea app contenedor in pod
podman run -d \
--pod webapp \
--name app \
--env DATABASE_URL=postgresql://user:secret@localhost/dbname \
myapp:latest
# Contenedores can communicate
podman exec app psql -h localhost -U user
# View all contenedores in pod
podman pod ps
podman pod ps -a --format "{{.Name}}\t{{.Contenedores}}"
Pod networking:
# Pods have their own red namespace
# Contenedores in pod share loopback and eth0
# Expose pod puertos
podman pod create \
--name myapp \
--publish 3000:3000 \
--publish 5000:5000
# Multiple contenedores can use different puertos
podman run -d --pod myapp --name web -p 3000:3000 nodo-app:latest
podman run -d --pod myapp --name api python-api:latest
# Access via localhost
curl http://localhost:3000/
curl http://localhost:5000/api
# Contenedor-to-contenedor communication via localhost:puerto
Docker Compatibility
Leverage Docker-compatible tools and workflows with Podman.
Docker CLI compatibility:
# podman-docker package proporciona docker alias
sudo apt-get install podman-docker
# Docker commands work with Podman
docker run -d --name web -p 8080:80 nginx:latest
docker ps
docker logs web
docker exec web curl localhost
docker stop web
docker rm web
# Volumen operations
docker volumen create mydata
docker run -d -v mydata:/data nginx:latest
# Imagen operations
docker build -t myapp:latest .
docker tag myapp:latest myregistry.com/myapp:latest
docker push myregistry.com/myapp:latest
docker pull alpine:latest
Dockerfile compatibility:
# Build imágenes with Podman (Dockerfile syntax identical)
cat > Dockerfile <<'EOF'
FROM nodo:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["nodo", "server.js"]
EOF
# Build imagen with Podman
podman build -t myapp:latest .
# Tag and push to registro
podman tag myapp:latest quay.io/username/myapp:latest
podman push quay.io/username/myapp:latest
# Pull from registro
podman pull quay.io/username/myapp:latest
# Ejecuta imagen
podman run -d -p 3000:3000 myapp:latest
API compatibility:
# Podman proporciona Docker-compatible API
sudo systemctl start podman.socket
# Set Docker client to use Podman socket
export DOCKER_HOST=unix:///run/podman/podman.sock
# Docker client commands work with Podman
docker ps
docker run alpine echo "Using Podman via Docker API"
docker imágenes
# REST API compatibility
curl -s --unix-socket /run/podman/podman.sock \
http://localhost/v1.0.0/libpod/info | jq
# Use Docker client library with Podman
python3 -c "import docker; client = docker.from_env(); print(client.version())"
Systemd Integration
Ejecuta contenedores as systemd servicios for automatic startup and management.
Crea systemd servicio files:
# Crea systemd user servicio directory
mkdir -p ~/.config/systemd/user
# Crea servicio file for contenedor
cat > ~/.config/systemd/user/myapp.servicio <<'EOF'
[Unit]
Description=My Application Contenedor
After=red-online.target
Wants=red-online.target
[Servicio]
Type=notify
NotifyAccess=main
ExecStart=/usr/bin/podman run \
--rm \
--name myapp \
-p 5000:5000 \
-v /home/$USER/myapp/data:/data \
myapp:latest
ExecStop=/usr/bin/podman stop myapp
Reinicia=always
RestartSec=10
[Instala]
WantedBy=default.target
EOF
# Habilita and start servicio
systemctl --user daemon-reload
systemctl --user enable myapp.servicio
systemctl --user start myapp.servicio
# Check servicio status
systemctl --user status myapp.servicio
# View servicio logs
journalctl --user -u myapp.servicio -f
Avanzado systemd integration:
# Servicio with multiple contenedores
cat > ~/.config/systemd/user/myapp.servicio <<'EOF'
[Unit]
Description=Multi-Contenedor Application
After=red-online.target
Wants=red-online.target
[Servicio]
Type=notify
NotifyAccess=main
ExecStartPre=/usr/bin/podman pod create \
--name myapp-pod \
-p 8080:80 \
-p 5432:5432
ExecStart=/usr/bin/podman run \
--rm \
--pod myapp-pod \
--name app \
myapp:latest
ExecStart=/usr/bin/podman run \
--rm \
--pod myapp-pod \
--name db \
postgres:15
ExecStop=/usr/bin/podman pod stop myapp-pod
ExecStopPost=/usr/bin/podman pod rm myapp-pod
Reinicia=on-failure
RestartSec=10
[Instala]
WantedBy=multi-user.target
EOF
# System-wide servicio (requires root)
sudo tee /etc/systemd/system/myapp.servicio > /dev/null <<'EOF'
[Unit]
Description=My Application Contenedor
After=red-online.target
[Servicio]
Type=notify
ExecStart=/usr/bin/podman run --rm --name myapp myapp:latest
ExecStop=/usr/bin/podman stop myapp
Reinicia=always
[Instala]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable myapp.servicio
sudo systemctl start myapp.servicio
Podman Compose
Use docker-compose files with Podman for multi-contenedor applications.
Basic Podman Compose:
# Instala podman-compose if not included
sudo apt-get install podman-compose
# or pip install podman-compose
# Crea compose file
cat > docker-compose.yml <<'EOF'
version: '3.9'
servicios:
web:
imagen: nginx:alpine
puertos:
- "80:80"
volúmenes:
- ./html:/usr/share/nginx/html
depends_on:
- app
app:
build: .
puertos:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://user:password@db:5432/mydb
depends_on:
- db
db:
imagen: postgres:15-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volúmenes:
- db_data:/var/lib/postgresql/data
volúmenes:
db_data:
EOF
# Inicia servicios with Podman Compose
podman-compose up -d
# Check servicios
podman-compose ps
# View logs
podman-compose logs -f
# Detén servicios
podman-compose down
Avanzado compose configurations:
cat > docker-compose.yml <<'EOF'
version: '3.9'
servicios:
web:
imagen: nginx:alpine
container_name: web_container
restart: unless-stopped
puertos:
- "80:80"
- "443:443"
volúmenes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
redes:
- frontend
api:
build:
context: ./api
dockerfile: Dockerfile
container_name: api_container
restart: unless-stopped
puertos:
- "5000:5000"
environment:
- DEBUG=false
- DATABASE_URL=postgresql://user:pass@db:5432/mydb
depends_on:
- db
redes:
- frontend
- backend
db:
imagen: postgres:15-alpine
container_name: db_container
restart: unless-stopped
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volúmenes:
- db_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redes:
- backend
redes:
frontend:
driver: bridge
backend:
driver: bridge
volúmenes:
db_data:
EOF
# Despliega with Podman Compose
podman-compose up -d
# Escala servicio
podman-compose up -d --scale api=3
# Remueve everything
podman-compose down -v
Avanzado Podman Features
Implement advanced Podman capabilities for production deployments.
Custom almacenamiento driver:
# Configura alternate almacenamiento driver
sudo tee /etc/contenedores/almacenamiento.conf <<'EOF'
[almacenamiento]
driver = "overlay"
graphroot = "/var/lib/contenedores/almacenamiento"
runroot = "/run/contenedores/almacenamiento"
[almacenamiento.options]
mount_program = "/usr/bin/fuse-overlayfs"
EOF
# Check almacenamiento configuration
podman info --format='{{.Store}}'
# Verifica almacenamiento driver
podman info | grep StorageDriver
Imagen management:
# Save imagen to tar
podman save myapp:latest -o myapp.tar
# Load imagen from tar
podman load -i myapp.tar
# Export contenedor filesystem
podman export <contenedor-id> -o contenedor.tar
# Import contenedor imagen
podman import contenedor.tar myimage:latest
# List all imágenes with details
podman imágenes --all --format "table {{.Repositorio}}\t{{.Tag}}\t{{.Size}}"
# Remueve unused imágenes
podman imagen prune -a
# Remueve dangling imágenes
podman imagen prune
Security features:
# Ejecuta contenedor with read-only root filesystem
podman run -d --read-only --tmpfs /tmp myapp:latest
# Use security labels
podman run -d --security-opt label=type:svirt_apache_t myapp:latest
# Ejecuta with specific capabilities
podman run -d --cap-add NET_ADMIN --cap-drop ALL myapp:latest
# Use seccomp profiles
podman run -d --security-opt seccomp=/path/to/profile.json myapp:latest
# Check security options
podman inspect <contenedor-id> | grep -A 5 SecurityOpt
Conclusión
Podman represents a modern approach to contenedor management that prioritizes security, compatibility, and simplicity. Its daemonless architecture eliminates privilege escalation vectors, while Docker CLI compatibility ensures minimal learning curve for Docker users. The native pod support enables simplified multi-contenedor deployments, and systemd integration proporciona robust servicio management. Whether migrating from Docker or starting fresh, Podman delivers production-ready contenedor functionality with enhanced security posture. As contenedor technology evolves, Podman's design choices align with emerging industry standards and practices. Inicia with basic contenedor operations, progress to pod management, and leverage systemd integration for production deployments.


