#!/usr/bin/env bash # Container Runtime Detection & Configuration # Detects and uses available container runtime: podman-in-podman > podman > docker-in-docker > docker set -euo pipefail # Color codes RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Export these for use in calling scripts export CONTAINER_RUNTIME="" export COMPOSE_CMD="" export CONTAINER_SOCKET="" export INSIDE_CONTAINER="" # Detect if we're inside a container detect_container_env() { if [[ -f /.dockerenv ]] || [[ -f /run/.containerenv ]]; then INSIDE_CONTAINER="true" else INSIDE_CONTAINER="false" fi } # Find available container runtime detect_runtime() { local runtime_priority=( "podman" "docker" ) for runtime in "${runtime_priority[@]}"; do if command -v "$runtime" &>/dev/null; then CONTAINER_RUNTIME="$runtime" # Get compose command if command -v "${runtime}-compose" &>/dev/null; then COMPOSE_CMD="${runtime}-compose" elif [[ "$runtime" == "docker" ]] && command -v docker-compose &>/dev/null; then COMPOSE_CMD="docker-compose" elif [[ "$runtime" == "podman" ]] && command -v podman-compose &>/dev/null; then COMPOSE_CMD="podman-compose" elif [[ "$runtime" == "podman" ]]; then # Fallback: podman has built-in compose COMPOSE_CMD="podman compose" else COMPOSE_CMD="$runtime compose" fi return 0 fi done return 1 } # Setup DinD (Docker in Docker) socket setup_dind_socket() { local runtime="$1" case "$runtime" in podman) # Podman socket location if [[ -S "$XDG_RUNTIME_DIR/podman/podman.sock" ]]; then CONTAINER_SOCKET="$XDG_RUNTIME_DIR/podman/podman.sock" elif [[ -S "/run/podman/podman.sock" ]]; then CONTAINER_SOCKET="/run/podman/podman.sock" elif [[ -S "/run/user/$(id -u)/podman/podman.sock" ]]; then CONTAINER_SOCKET="/run/user/$(id -u)/podman/podman.sock" fi ;; docker) # Docker socket location if [[ -S "/var/run/docker.sock" ]]; then CONTAINER_SOCKET="/var/run/docker.sock" elif [[ -S "/run/docker.sock" ]]; then CONTAINER_SOCKET="/run/docker.sock" fi ;; esac } # Get mount flags for DinD get_dind_mount_flags() { local runtime="$1" if [[ -z "$CONTAINER_SOCKET" ]]; then return fi case "$runtime" in podman) echo "-v $CONTAINER_SOCKET:/run/podman/podman.sock" ;; docker) echo "-v $CONTAINER_SOCKET:/var/run/docker.sock" ;; esac } # Initialize runtime init_runtime() { detect_container_env if ! detect_runtime; then echo -e "${RED}❌ Error: No container runtime found (podman or docker required)${NC}" >&2 return 1 fi setup_dind_socket "$CONTAINER_RUNTIME" # Export for subshells export CONTAINER_RUNTIME export COMPOSE_CMD export CONTAINER_SOCKET export INSIDE_CONTAINER return 0 } # Display status show_status() { echo -e "${BLUE}Container Runtime Detection:${NC}" echo " Runtime: ${GREEN}$CONTAINER_RUNTIME${NC}" echo " Compose: ${GREEN}$COMPOSE_CMD${NC}" echo " Inside Container: ${GREEN}$INSIDE_CONTAINER${NC}" if [[ -n "$CONTAINER_SOCKET" ]]; then echo " Socket: ${GREEN}$CONTAINER_SOCKET${NC}" fi } # Main execution if [[ "${1:-}" == "init" ]]; then init_runtime elif [[ "${1:-}" == "status" ]]; then init_runtime show_status elif [[ "${1:-}" == "runtime" ]]; then init_runtime echo "$CONTAINER_RUNTIME" elif [[ "${1:-}" == "compose" ]]; then init_runtime echo "$COMPOSE_CMD" elif [[ "${1:-}" == "socket" ]]; then init_runtime echo "$CONTAINER_SOCKET" else init_runtime fi