# 🚀 Podman Deployment Guide - Turmli Bar Calendar This guide provides instructions for deploying the Turmli Bar Calendar application using Podman, a daemonless container engine that's a drop-in replacement for Docker. ## 📋 Table of Contents - [Why Podman?](#-why-podman) - [Prerequisites](#-prerequisites) - [Quick Start](#-quick-start) - [Deployment Options](#-deployment-options) - [Commands Reference](#-commands-reference) - [Rootless Podman](#-rootless-podman) - [Systemd Integration](#-systemd-integration) - [Differences from Docker](#-differences-from-docker) - [Troubleshooting](#-troubleshooting) ## 🎯 Why Podman? Podman offers several advantages over Docker: - **Daemonless**: No background service consuming resources - **Rootless**: Can run containers without root privileges - **Systemd Integration**: Native systemd service generation - **Docker Compatible**: Uses the same commands and image format - **Better Security**: Each container runs in its own user namespace - **Lower Resource Usage**: No daemon means less memory overhead ## 📦 Prerequisites ### Install Podman #### On Fedora/RHEL/CentOS: ```bash sudo dnf install podman ``` #### On Ubuntu/Debian: ```bash sudo apt-get update sudo apt-get install podman ``` #### On Arch Linux: ```bash sudo pacman -S podman ``` ### Optional: Install podman-compose ```bash pip install podman-compose # or sudo dnf install podman-compose # Fedora sudo apt-get install podman-compose # Ubuntu/Debian ``` ## 🚀 Quick Start 1. **Clone the repository**: ```bash git clone https://github.com/yourusername/turmli-bar-calendar-tool.git cd turmli-bar-calendar-tool ``` 2. **Deploy with the Podman script**: ```bash ./deploy-podman.sh start ``` 3. **Access the application**: Open http://localhost:8000 in your browser ## 🛠️ Deployment Options ### Option 1: Using the Deploy Script (Recommended) The `deploy-podman.sh` script automatically detects whether you have Podman or Docker installed and uses the appropriate tool. ```bash # Start the application (builds and runs) ./deploy-podman.sh start # Check status ./deploy-podman.sh status # View logs ./deploy-podman.sh logs # Stop the application ./deploy-podman.sh stop # Restart the application ./deploy-podman.sh restart # Clean up everything ./deploy-podman.sh clean ``` ### Option 2: Using podman-compose If you have `podman-compose` installed: ```bash # Start with podman-compose podman-compose -f podman-compose.yml up -d # Stop with podman-compose podman-compose -f podman-compose.yml down # View logs podman-compose -f podman-compose.yml logs -f ``` ### Option 3: Direct Podman Commands ```bash # Build the image podman build -f Containerfile -t turmli-calendar . # Run the container podman run -d \ --name turmli-calendar \ -p 8000:8000 \ -e TZ=Europe/Berlin \ -v ./calendar_cache.json:/app/calendar_cache.json:Z \ --restart unless-stopped \ turmli-calendar # Check logs podman logs -f turmli-calendar # Stop and remove podman stop turmli-calendar podman rm turmli-calendar ``` ## 📋 Commands Reference ### Environment Variables - `PORT`: Port to expose (default: 8000) - `TZ`: Timezone (default: Europe/Berlin) Example: ```bash PORT=8080 TZ=America/New_York ./deploy-podman.sh start ``` ### deploy-podman.sh Commands | Command | Description | |---------|------------| | `build` | Build the container image | | `start` | Build and start the application | | `stop` | Stop the application | | `restart` | Restart the application | | `logs` | Show application logs (follow mode) | | `status` | Check application status and health | | `clean` | Remove containers and images | | `systemd` | Generate systemd service (Podman only) | | `help` | Show help message | ## 👤 Rootless Podman Podman can run containers without root privileges, which is more secure. ### Setup Rootless Podman 1. **Enable lingering for your user** (allows services to run without being logged in): ```bash loginctl enable-linger $USER ``` 2. **Configure subuid and subgid** (usually already configured): ```bash # Check if already configured grep $USER /etc/subuid /etc/subgid ``` 3. **Run containers as your regular user**: ```bash # No sudo needed! podman run -d --name test alpine sleep 1000 podman ps podman stop test ``` ## 🔧 Systemd Integration Podman can generate systemd service files for automatic startup. ### Generate and Install Systemd Service 1. **Start the container first**: ```bash ./deploy-podman.sh start ``` 2. **Generate systemd service**: ```bash ./deploy-podman.sh systemd ``` 3. **Enable and start the service**: ```bash # For user service (rootless) systemctl --user daemon-reload systemctl --user enable container-turmli-calendar.service systemctl --user start container-turmli-calendar.service # Check status systemctl --user status container-turmli-calendar.service ``` ### For System-wide Service (requires root) ```bash # Generate for system sudo podman generate systemd --name --files --new turmli-calendar # Move to system directory sudo mv container-turmli-calendar.service /etc/systemd/system/ # Enable and start sudo systemctl daemon-reload sudo systemctl enable container-turmli-calendar.service sudo systemctl start container-turmli-calendar.service ``` ## 🔄 Differences from Docker ### Key Differences 1. **No Daemon**: Podman doesn't require a background service 2. **Rootless by Default**: Can run without root privileges 3. **Systemd Integration**: Native systemd service generation 4. **SELinux Labels**: Use `:Z` flag for volumes with SELinux 5. **User Namespaces**: Better isolation between containers ### Command Compatibility Most Docker commands work with Podman: ```bash # Docker command docker build -t myapp . docker run -d -p 8000:8000 myapp # Podman equivalent (same syntax!) podman build -t myapp . podman run -d -p 8000:8000 myapp ``` ### Compose Differences The `podman-compose.yml` includes Podman-specific options: - `userns_mode: keep-id` - Maintains user ID in container - Volume `:Z` flag - SELinux relabeling - Modified healthcheck - Uses Python instead of curl ## 🐛 Troubleshooting ### Build Issues on ARM/Raspberry Pi If you encounter build failures on ARM architectures (like Raspberry Pi), the issue is likely due to packages requiring compilation (pydantic-core, uvloop, httptools, watchfiles). These require gcc, make, and Rust/cargo to compile. **Solutions:** 1. **Use the ARM-optimized Dockerfile** (Recommended): ```bash # The deploy-podman.sh script automatically detects ARM and uses Dockerfile.arm ./deploy-podman.sh build ``` 2. **Use pre-built multi-arch images** if available: ```bash # Pull a pre-built image instead of building podman pull docker.io/yourusername/turmli-calendar:arm ``` 3. **Build with the multi-stage Dockerfile** (slower but works): ```bash # This installs build tools in a separate stage podman build -f Dockerfile -t turmli-calendar . ``` 4. **Use the simplified requirements** for ARM: ```bash # Copy ARM requirements cp requirements-arm.txt requirements.txt podman build -t turmli-calendar . ``` ### Common Issues and Solutions #### 1. Build Fails with "no acceptable C compiler found" This happens when building on systems without development tools. **Solution for containers:** ```bash # Use the multi-stage Dockerfile which includes build tools podman build -f Dockerfile -t turmli-calendar . ``` **Solution for host system:** ```bash # Install build tools sudo apt-get install build-essential # Debian/Ubuntu sudo dnf install gcc make # Fedora ``` #### 2. Permission Denied on Volume Mount ```bash # Add :Z flag for SELinux systems -v ./calendar_cache.json:/app/calendar_cache.json:Z ``` #### 3. Container Can't Bind to Port ```bash # Check if port is already in use podman port turmli-calendar ss -tlnp | grep 8000 # Use a different port PORT=8080 ./deploy-podman.sh start ``` #### 4. Rootless Podman Can't Bind to Privileged Ports (< 1024) ```bash # Allow binding to port 80 (example) sudo sysctl net.ipv4.ip_unprivileged_port_start=80 ``` #### 5. Container Not Starting After Reboot ```bash # Enable lingering for rootless containers loginctl enable-linger $USER # Use systemd service ./deploy-podman.sh systemd systemctl --user enable container-turmli-calendar.service ``` #### 6. DNS Issues in Container ```bash # Check Podman's DNS configuration podman run --rm alpine cat /etc/resolv.conf # Use custom DNS if needed podman run --dns 8.8.8.8 --dns 8.8.4.4 ... ``` #### 7. ARM/Raspberry Pi Specific Issues **Memory constraints during build:** ```bash # Increase swap space temporarily sudo dd if=/dev/zero of=/swapfile bs=1G count=2 sudo mkswap /swapfile sudo swapon /swapfile # Build with limited parallelism CARGO_BUILD_JOBS=1 podman build -t turmli-calendar . # Clean up swap after build sudo swapoff /swapfile sudo rm /swapfile ``` **Use lighter alternatives:** ```bash # Check architecture ./deploy-podman.sh info # Build with ARM-optimized Dockerfile podman build -f Dockerfile.arm -t turmli-calendar . ``` ### Debugging Commands ```bash # Inspect container podman inspect turmli-calendar # Check container processes podman top turmli-calendar # Execute command in running container podman exec -it turmli-calendar /bin/bash # Check Podman system info podman system info # Clean up unused resources podman system prune -a ``` ## 📝 Additional Notes ### Security Benefits - **No Root Daemon**: Unlike Docker, Podman doesn't require a root daemon - **User Namespaces**: Each container runs in isolated user namespace - **Seccomp Profiles**: Default security profiles for system calls - **SELinux Support**: Better integration with SELinux policies ### Resource Usage Podman typically uses less resources than Docker: - No daemon = ~50-100MB less RAM - Faster container startup - Lower CPU overhead ### Migration from Docker To migrate from Docker to Podman: 1. Install Podman 2. Use the same Dockerfile/Containerfile 3. Replace `docker` with `podman` in commands 4. Adjust volume mounts (add `:Z` for SELinux) 5. Use `podman-compose` instead of `docker-compose` ## 📚 Resources - [Podman Documentation](https://docs.podman.io/) - [Podman vs Docker](https://podman.io/whatis.html) - [Rootless Podman Tutorial](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md) - [Podman Compose](https://github.com/containers/podman-compose) ## 🤝 Support If you encounter any issues specific to Podman deployment, please: 1. Check the troubleshooting section above 2. Review Podman logs: `podman logs turmli-calendar` 3. Check Podman events: `podman events --since 1h` 4. Open an issue with the error details