#!/bin/bash ################################################################################ # Docker Setup Script ################################################################################ # # Description: # Comprehensive automated setup script for Docker development environments. # This script prepares Ubuntu/Debian systems with all necessary tools for # containerized application development and deployment. # # What this script does: # 1. System Updates # - Updates apt package lists # - Upgrades all installed packages to latest versions # - Reports number of packages upgraded # # 2. Docker Installation (if not present) # - Adds Docker's official GPG key and repository # - Installs Docker Engine, CLI, containerd # - Installs Docker Buildx and Compose plugins # - Enables Docker service to start on boot # - Verifies Docker daemon is running # # 3. Docker Group Configuration # - Creates docker group if it doesn't exist # - Adds the current user to docker group # - Enables sudo-less Docker commands (after re-login) # - Sets up proper group permissions # # 4. Docker Compose V2 # - Checks for Docker Compose plugin # - Installs docker-compose-plugin if missing # - Verifies installation and version # # 5. GitHub CLI Installation # - Adds GitHub CLI official repository # - Installs latest version of 'gh' command # - Verifies installation # # 6. Container Directory Setup # - Creates /srv/containers/ directory structure # - Sets ownership to root:docker # - Applies 770 permissions (rwxrwx---) # - Configures ACL for inherited permissions # - Ensures all docker group members can create/manage containers # # 7. Verification & Summary # - Tests Docker access for current user # - Displays installation summary # - Provides next steps for activation # # Requirements: # - Ubuntu 20.04+ or Debian 10+ # - sudo privileges # - Internet connection # # Usage: # Quick install: # curl -sL https://raw.githubusercontent.com/alexisskeates/docker-setup-script/main/docker-setup.sh | sudo bash # # Manual download and run: # curl -O https://raw.githubusercontent.com/alexisskeates/docker-setup-script/main/docker-setup.sh # chmod +x docker-setup.sh # sudo ./docker-setup.sh # # Post-installation: # After running, you must activate docker group membership: # Option 1: Log out and log back in (recommended) # Option 2: Run 'newgrp docker' in current session # # Author: Alexis Keates # Repository: https://github.com/alexisskeates/docker-setup-script # License: MIT # ################################################################################ # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_section() { echo -e "${BLUE}[SECTION]${NC} $1" } # Check if running with elevated privileges if [[ $EUID -ne 0 ]]; then print_error "This script must be run with sudo" print_error "Usage: curl -sL https://raw.githubusercontent.com/alexisskeates/docker-setup-script/main/docker-setup.sh | sudo bash" exit 1 fi # Get the original user who ran sudo if [[ -n "$SUDO_USER" ]]; then ORIGINAL_USER="$SUDO_USER" ORIGINAL_USER_HOME=$(eval echo "~$SUDO_USER") else print_error "Could not determine original user. Please run with sudo, not as root directly." exit 1 fi print_status "Running as: $(whoami) (original user: $ORIGINAL_USER)" echo # ============================================================================ # SECTION 1: System Updates # ============================================================================ print_section "Checking for system updates..." print_status "Updating package lists..." if apt-get update; then print_status "Package lists updated successfully" else print_error "Failed to update package lists" exit 1 fi print_status "Checking for upgradeable packages..." UPGRADABLE=$(apt list --upgradable 2>/dev/null | tail -n +2 | wc -l) if [[ $UPGRADABLE -gt 0 ]]; then print_status "Found $UPGRADABLE upgradeable package(s)" print_status "Upgrading system packages (this may take a few minutes)..." if DEBIAN_FRONTEND=noninteractive apt-get upgrade -y; then print_status "System packages upgraded successfully" else print_warning "Some packages failed to upgrade, but continuing..." fi else print_status "System is already up to date" fi echo # ============================================================================ # SECTION 2: Docker Installation Check # ============================================================================ print_section "Verifying Docker installation..." if ! command -v docker > /dev/null 2>&1; then print_warning "Docker is not installed. Installing Docker..." # Install prerequisites print_status "Installing prerequisites..." apt-get install -y ca-certificates curl gnupg lsb-release # Add Docker's official GPG key print_status "Adding Docker GPG key..." install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg # Set up the repository print_status "Adding Docker repository..." echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null # Update apt and install Docker print_status "Installing Docker Engine..." apt-get update if apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin; then print_status "Docker installed successfully" else print_error "Failed to install Docker" exit 1 fi else print_status "Docker is already installed ($(docker --version))" fi # Enable and start Docker service print_status "Ensuring Docker service is enabled and running..." systemctl enable docker systemctl start docker # Verify Docker daemon is running if docker ps > /dev/null 2>&1; then print_status "Docker daemon is running" else print_error "Docker daemon is not running properly" exit 1 fi echo # ============================================================================ # SECTION 3: Docker Group Setup # ============================================================================ print_section "Setting up Docker group and permissions..." # Check if docker group exists if ! getent group docker > /dev/null 2>&1; then print_warning "Docker group does not exist. Creating it..." if groupadd docker; then print_status "Docker group created successfully" else print_error "Failed to create docker group" exit 1 fi else print_status "Docker group already exists" fi # Check if the original user is in the docker group if ! groups "$ORIGINAL_USER" | grep -q docker; then print_status "Adding user $ORIGINAL_USER to docker group..." if usermod -aG docker "$ORIGINAL_USER"; then print_status "User added to docker group successfully" print_warning "Note: User $ORIGINAL_USER will need to log out and back in for group changes to take effect" print_warning "Or run: newgrp docker" else print_error "Failed to add user to docker group" exit 1 fi else print_status "User $ORIGINAL_USER is already in docker group" fi echo # ============================================================================ # SECTION 4: Docker Compose Installation # ============================================================================ print_section "Checking Docker Compose installation..." # Check if docker compose is available (V2 plugin style) if docker compose version > /dev/null 2>&1; then COMPOSE_VERSION=$(docker compose version --short 2>/dev/null || echo "unknown") print_status "Docker Compose is already installed (version: $COMPOSE_VERSION)" # Also check for old standalone docker-compose elif command -v docker-compose > /dev/null 2>&1; then COMPOSE_VERSION=$(docker-compose version --short 2>/dev/null || echo "unknown") print_status "Docker Compose (standalone) is installed (version: $COMPOSE_VERSION)" print_warning "Consider upgrading to Docker Compose V2 (plugin)" else print_warning "Docker Compose not found. Installing..." # Install Docker Compose plugin (V2) print_status "Installing docker-compose-plugin..." if apt-get install -y docker-compose-plugin; then print_status "Docker Compose plugin installed successfully" # Verify installation if docker compose version > /dev/null 2>&1; then COMPOSE_VERSION=$(docker compose version --short 2>/dev/null || echo "unknown") print_status "Docker Compose version $COMPOSE_VERSION is now available" else print_error "Docker Compose installation verification failed" exit 1 fi else print_error "Failed to install Docker Compose plugin" exit 1 fi fi echo # ============================================================================ # SECTION 5: GitHub CLI Installation # ============================================================================ print_section "Checking GitHub CLI installation..." if command -v gh > /dev/null 2>&1; then GH_VERSION=$(gh --version | head -n1 | awk '{print $3}') print_status "GitHub CLI is already installed (version: $GH_VERSION)" else print_warning "GitHub CLI not found. Installing..." # Add GitHub CLI repository print_status "Adding GitHub CLI repository..." # Install prerequisites apt-get install -y curl gpg # Add GPG key curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg # Add repository echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null # Update and install print_status "Installing GitHub CLI..." apt-get update if apt-get install -y gh; then GH_VERSION=$(gh --version | head -n1 | awk '{print $3}') print_status "GitHub CLI version $GH_VERSION installed successfully" else print_error "Failed to install GitHub CLI" exit 1 fi fi echo # ============================================================================ # SECTION 6: Container Directory Setup # ============================================================================ print_section "Setting up /srv/containers/ directory..." # Create the directory if it doesn't exist if [[ ! -d "/srv/containers" ]]; then print_status "Creating directory /srv/containers/" if mkdir -p /srv/containers; then print_status "Directory created successfully" else print_error "Failed to create directory" exit 1 fi else print_status "Directory /srv/containers/ already exists" fi # Set ownership to root:docker print_status "Setting ownership to root:docker" if chown root:docker /srv/containers; then print_status "Ownership set successfully" else print_error "Failed to set ownership" exit 1 fi # Set permissions: owner (root) has full access, group (docker) has read/write, others have no access print_status "Setting permissions (rwxrwx---)" if chmod 770 /srv/containers; then print_status "Permissions set successfully" else print_error "Failed to set permissions" exit 1 fi # Install ACL if needed if ! command -v setfacl > /dev/null 2>&1; then print_status "Installing ACL package..." apt-get install -y acl > /dev/null 2>&1 fi # Set default ACL for future files and directories if command -v setfacl > /dev/null 2>&1; then print_status "Setting default ACL for future contents" if setfacl -d -m g:docker:rwx /srv/containers && setfacl -m g:docker:rwx /srv/containers; then print_status "ACL set successfully" else print_warning "Failed to set ACL" fi else print_warning "ACL tools not available. Future files may not inherit proper permissions" fi echo # ============================================================================ # SECTION 7: Verification and Summary # ============================================================================ print_section "Setup Summary" echo "Directory details:" ls -lad /srv/containers 2>/dev/null || print_warning "Could not list directory details" echo if command -v getfacl > /dev/null 2>&1; then echo "ACL details:" getfacl /srv/containers 2>/dev/null || print_warning "Could not display ACL details" echo fi # Test Docker access for original user print_status "Testing Docker access for $ORIGINAL_USER..." if sudo -u "$ORIGINAL_USER" docker ps > /dev/null 2>&1; then print_status "✓ Docker access working (group change already effective)" else print_warning "Docker access requires logout/login or 'newgrp docker'" fi echo print_status "✓ System packages updated" print_status "✓ Docker installed and verified" print_status "✓ Docker Compose installed and verified" print_status "✓ GitHub CLI installed and verified" print_status "✓ Docker group configured" print_status "✓ User $ORIGINAL_USER added to docker group" print_status "✓ /srv/containers/ directory created with proper permissions" echo # Final instructions print_section "IMPORTANT: Next Steps" print_warning "To use Docker without sudo, $ORIGINAL_USER needs the docker group to be active." print_warning "Since we just added you to the docker group, you need to either:" echo " 1. Log out and back in to your SSH session, OR" echo " 2. Run: newgrp docker (in current session)" echo print_status "After re-logging or running 'newgrp docker', test with:" echo " • docker --version" echo " • docker compose version" echo " • docker ps" echo " • gh --version" echo print_status "Setup completed successfully at $(date)!"