Skip to content

Instantly share code, notes, and snippets.

@gustavoserafim
Created June 18, 2025 02:36
Show Gist options
  • Select an option

  • Save gustavoserafim/0c04f069bdc3a4c2b123d5f1831c013e to your computer and use it in GitHub Desktop.

Select an option

Save gustavoserafim/0c04f069bdc3a4c2b123d5f1831c013e to your computer and use it in GitHub Desktop.

Revisions

  1. gustavoserafim created this gist Jun 18, 2025.
    250 changes: 250 additions & 0 deletions lxc-setup.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,250 @@
    #!/bin/bash

    # LXC Container Setup Script
    # Description: Installs Git, Docker, Portainer, configures SSH, and optionally sets up GPU access
    # Usage: curl -fsSL https://gist.githubusercontent.com/YOUR_USERNAME/YOUR_GIST_ID/raw/setup.sh | bash

    set -e # Exit on any error

    # Colors for output
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    BLUE='\033[0;34m'
    NC='\033[0m' # No Color

    # Logging functions
    log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
    }

    log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
    }

    log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
    }

    log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
    }

    # Function to check if running as root
    check_root() {
    if [[ $EUID -eq 0 ]]; then
    log_warning "Running as root. This is fine for LXC containers."
    else
    log_info "Running as non-root user: $(whoami)"
    fi
    }

    # Function to update system packages
    update_system() {
    log_info "Updating system packages..."
    apt update && apt upgrade -y
    log_success "System packages updated"
    }

    # Function to install essential packages
    install_essentials() {
    log_info "Installing essential packages..."
    apt install -y curl wget gnupg2 ca-certificates software-properties-common apt-transport-https lsb-release
    log_success "Essential packages installed"
    }

    # Function to install Git
    install_git() {
    log_info "Installing Git..."
    apt install -y git
    git_version=$(git --version)
    log_success "Git installed: $git_version"
    }

    # Function to install Docker
    install_docker() {
    log_info "Installing Docker..."

    # Download and run Docker installation script
    curl -fsSL https://get.docker.com -o get-docker.sh
    sh get-docker.sh

    # Add current user to docker group (if not root)
    if [[ $EUID -ne 0 ]]; then
    usermod -aG docker $USER
    log_info "Added $USER to docker group"
    fi

    # Clean up installation script
    rm get-docker.sh

    # Start and enable Docker service
    systemctl start docker
    systemctl enable docker

    docker_version=$(docker --version)
    log_success "Docker installed: $docker_version"
    }

    # Function to install Portainer
    install_portainer() {
    log_info "Installing Portainer..."

    # Create Portainer data volume
    docker volume create portainer_data

    # Run Portainer container
    docker run -d \
    -p 8000:8000 \
    -p 9443:9443 \
    --name portainer \
    --restart=always \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v portainer_data:/data \
    portainer/portainer-ce:lts

    log_success "Portainer installed and running"
    log_info "Portainer web interface available at: https://$(hostname -I | awk '{print $1}'):9443"
    }

    # Function to configure SSH
    configure_ssh() {
    log_info "Configuring SSH access..."

    # Install OpenSSH server if not already installed
    apt install -y openssh-server

    # Backup original SSH config
    cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup

    # Configure SSH settings
    sed -i 's/#Port 22/Port 22/' /etc/ssh/sshd_config
    sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
    sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
    sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config

    # Start and enable SSH service
    systemctl start ssh
    systemctl enable ssh

    # Show SSH status
    systemctl status ssh --no-pager -l

    log_success "SSH configured and running"
    log_info "SSH access available at: $(hostname -I | awk '{print $1}'):22"
    log_warning "Make sure to set up proper authentication (SSH keys recommended over passwords)"
    }

    # Function to install NVIDIA GPU support
    install_gpu_support() {
    log_info "Installing NVIDIA GPU support..."

    # Update packages
    apt update

    # Add NVIDIA GPG key
    curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

    # Add NVIDIA repository
    curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
    sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
    tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

    # Update package list
    apt update

    # Install NVIDIA container runtime (lightweight)
    apt install -y libnvidia-container1 libnvidia-container-tools nvidia-container-toolkit

    # Configure Docker to use NVIDIA runtime
    nvidia-ctk runtime configure --runtime=docker --set-as-default
    nvidia-ctk config --set nvidia-container-cli.no-cgroups --in-place

    # Restart Docker
    systemctl restart docker

    log_success "NVIDIA GPU support installed"
    log_info "You can test GPU access with: docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi"
    }

    # Function to display summary
    display_summary() {
    log_info "=== Installation Summary ==="
    echo ""
    log_success "✓ System updated"
    log_success "✓ Git installed"
    log_success "✓ Docker installed"
    log_success "✓ Portainer installed"
    log_success "✓ SSH configured"

    if [ "$INSTALL_GPU" = "y" ] || [ "$INSTALL_GPU" = "Y" ]; then
    log_success "✓ NVIDIA GPU support installed"
    fi

    echo ""
    log_info "=== Access Information ==="
    CONTAINER_IP=$(hostname -I | awk '{print $1}')
    echo -e "${BLUE}Container IP:${NC} $CONTAINER_IP"
    echo -e "${BLUE}SSH Access:${NC} ssh root@$CONTAINER_IP (or your configured user)"
    echo -e "${BLUE}Portainer Web UI:${NC} https://$CONTAINER_IP:9443"
    echo ""
    log_warning "Important: Change default passwords and set up proper authentication!"
    echo ""
    log_info "=== Next Steps ==="
    echo "1. Set up SSH key authentication"
    echo "2. Configure Portainer admin account"
    echo "3. Update firewall rules if needed"
    echo "4. Consider setting up a reverse proxy for web services"
    }

    # Main execution
    main() {
    log_info "Starting LXC Container Setup..."
    echo ""

    # Check if running as root
    check_root

    # Ask about GPU support
    echo ""
    read -p "Do you need NVIDIA GPU access in this container? (y/N): " INSTALL_GPU
    echo ""

    # Update system
    update_system

    # Install essential packages
    install_essentials

    # Install Git
    install_git

    # Install Docker
    install_docker

    # Install GPU support if requested
    if [ "$INSTALL_GPU" = "y" ] || [ "$INSTALL_GPU" = "Y" ]; then
    install_gpu_support
    fi

    # Install Portainer
    install_portainer

    # Configure SSH
    configure_ssh

    # Display summary
    echo ""
    display_summary

    log_success "Setup completed successfully!"

    # Suggest reboot if not root (for group membership to take effect)
    if [[ $EUID -ne 0 ]]; then
    echo ""
    log_warning "Please log out and log back in (or reboot) for Docker group membership to take effect."
    fi
    }

    # Run main function
    main "$@"