homelab infrastructure services
at fix-docker-install 216 lines 5.9 kB view raw
1#!/bin/bash 2 3# Simplified rootless Docker installation for tinsnip 4# Eliminates complex systemd detection and environment management 5 6set -euo pipefail 7 8SERVICE_USER="${1:-}" 9 10log() { 11 echo "[Docker Install] $*" 12} 13 14error() { 15 log "ERROR: $*" >&2 16 exit 1 17} 18 19usage() { 20 echo "Usage: $0 <service_user>" 21 echo " service_user: User to install rootless Docker for (e.g., gateway-prod)" 22 exit 1 23} 24 25install_dependencies() { 26 log "Installing rootless Docker dependencies..." 27 28 sudo apt-get update -qq >/dev/null 2>&1 || error "Failed to update package lists" 29 sudo apt-get install -y uidmap dbus-user-session fuse-overlayfs slirp4netns >/dev/null 2>&1 || error "Failed to install Docker dependencies" 30 31 log "Dependencies installed" 32} 33 34install_rootless_docker() { 35 local username="$1" 36 37 log "Installing rootless Docker for user: $username" 38 39 # Check if already installed 40 if sudo -u "$username" -i bash -c "command -v docker &>/dev/null"; then 41 log "Docker already installed for $username" 42 return 0 43 fi 44 45 # Install rootless Docker 46 sudo -u "$username" -i bash << 'EOF' 47# Download and install rootless Docker 48curl -fsSL https://get.docker.com/rootless | sh 49 50# Add Docker to PATH in .bashrc (simple approach) 51if ! grep -q 'export PATH=$HOME/bin:$PATH' ~/.bashrc 2>/dev/null; then 52 echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc 53fi 54 55# Source the new PATH 56export PATH=$HOME/bin:$PATH 57 58# Test Docker installation 59if command -v docker >/dev/null 2>&1; then 60 echo "Docker binary installed successfully" 61else 62 echo "ERROR: Docker binary not found after installation" 63 exit 1 64fi 65EOF 66 67 if [[ $? -ne 0 ]]; then 68 error "Failed to install Docker for $username" 69 fi 70 71 log "Rootless Docker installation completed for $username" 72} 73 74setup_docker_environment() { 75 local username="$1" 76 77 log "Setting up Docker environment for $username" 78 79 # Create Docker runtime directory 80 sudo -u "$username" -i bash -c 'mkdir -p "$HOME/.docker/run"' 81 82 # Create simple Docker configuration 83 sudo -u "$username" tee "/home/$username/.docker/daemon.json" > /dev/null << 'EOF' 84{ 85 "log-driver": "json-file", 86 "log-opts": { 87 "max-size": "10m", 88 "max-file": "3" 89 }, 90 "storage-driver": "overlay2" 91} 92EOF 93 94 # Set up environment variables in service .env file 95 local service_env_file="/mnt/$username/.env" 96 97 if [[ -f "$service_env_file" ]]; then 98 log "Adding Docker environment to service .env file" 99 100 # Remove existing Docker variables 101 sudo -u "$username" bash -c "grep -v '^XDG_RUNTIME_DIR=\|^DOCKER_HOST=\|^PATH=' '$service_env_file' > '${service_env_file}.tmp' 2>/dev/null || touch '${service_env_file}.tmp'" 102 sudo -u "$username" bash -c "mv '${service_env_file}.tmp' '$service_env_file'" 103 104 # Add Docker environment variables 105 sudo -u "$username" bash -c "cat >> '$service_env_file' << 'DOCKER_EOF' 106 107# Docker rootless environment 108XDG_RUNTIME_DIR=/home/$username/.docker/run 109DOCKER_HOST=unix:///home/$username/.docker/run/docker.sock 110PATH=/home/$username/bin:\$PATH 111DOCKER_EOF" 112 113 log "Docker environment added to $service_env_file" 114 else 115 log "WARNING: Service .env file not found at $service_env_file" 116 fi 117} 118 119start_docker_daemon() { 120 local username="$1" 121 122 log "Starting Docker daemon for $username" 123 124 sudo -u "$username" -i bash << 'EOF' 125# Set up environment 126export XDG_RUNTIME_DIR="$HOME/.docker/run" 127export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock" 128export PATH="$HOME/bin:$PATH" 129 130# Kill any existing dockerd processes 131pkill -f dockerd-rootless || true 132sleep 2 133 134# Start Docker daemon 135nohup dockerd-rootless.sh > "$HOME/.docker/docker.log" 2>&1 & 136sleep 5 137 138# Wait for socket 139for i in {1..10}; do 140 if [[ -S "$XDG_RUNTIME_DIR/docker.sock" ]]; then 141 echo "Docker socket created successfully" 142 break 143 fi 144 echo "Waiting for Docker socket... ($i/10)" 145 sleep 2 146done 147 148# Test Docker 149if docker version >/dev/null 2>&1; then 150 echo "Docker daemon started successfully" 151else 152 echo "ERROR: Docker daemon failed to start properly" 153 cat "$HOME/.docker/docker.log" 2>/dev/null || echo "No log file found" 154 exit 1 155fi 156EOF 157 158 if [[ $? -ne 0 ]]; then 159 error "Failed to start Docker daemon for $username" 160 fi 161 162 log "Docker daemon started successfully" 163} 164 165verify_installation() { 166 local username="$1" 167 168 log "Verifying Docker installation for $username..." 169 170 local service_env_file="/mnt/$username/.env" 171 172 if sudo -u "$username" bash -c "source '$service_env_file' 2>/dev/null && docker version >/dev/null 2>&1"; then 173 log "Docker verification successful!" 174 local docker_version 175 docker_version=$(sudo -u "$username" bash -c "source '$service_env_file' 2>/dev/null && docker --version") 176 log "Installed: $docker_version" 177 else 178 error "Docker verification failed for $username" 179 fi 180} 181 182main() { 183 # Validate parameters 184 if [[ -z "$SERVICE_USER" ]]; then 185 usage 186 fi 187 188 # Check if user exists 189 if ! id "$SERVICE_USER" &>/dev/null; then 190 error "User $SERVICE_USER does not exist. Create the user first." 191 fi 192 193 log "Installing rootless Docker for service user: $SERVICE_USER" 194 195 # Install dependencies 196 install_dependencies 197 198 # Install rootless Docker 199 install_rootless_docker "$SERVICE_USER" 200 201 # Setup Docker environment 202 setup_docker_environment "$SERVICE_USER" 203 204 # Start Docker daemon 205 start_docker_daemon "$SERVICE_USER" 206 207 # Verify installation 208 verify_installation "$SERVICE_USER" 209 210 log "" 211 log "Rootless Docker installation complete!" 212 log "User: $SERVICE_USER" 213 log "To test: sudo -u $SERVICE_USER bash -c 'source /mnt/$SERVICE_USER/.env && docker run hello-world'" 214} 215 216main "$@"