Skip to content

Instantly share code, notes, and snippets.

@darinkishore
Last active May 31, 2025 22:13
Show Gist options
  • Save darinkishore/9b521086c025628165f3a5b9280dbd2c to your computer and use it in GitHub Desktop.
Save darinkishore/9b521086c025628165f3a5b9280dbd2c to your computer and use it in GitHub Desktop.
Fully Automated GPU Development Environment Setup Script - No prompts, installs Fish, Helix, dev tools, Node.js 22, Python/uv, and Claude Code CLI
#!/bin/bash
# Ultimate setup script - fixes workspace permissions too
# Works in minimal containers and GPU platforms
set -e
echo "πŸš€ GPU Dev Environment Setup"
echo "============================"
echo ""
# Check if we're root
if [ "$EUID" -ne 0 ]; then
# Try sudo if available
if command -v sudo &> /dev/null; then
echo "Re-running with sudo..."
exec sudo "$0" "$@"
else
echo "❌ Error: This script must be run as root"
echo " Please run: sudo $0"
exit 1
fi
fi
echo "βœ… Running as root"
echo ""
# Set non-interactive frontend to prevent tzdata prompts
export DEBIAN_FRONTEND=noninteractive
export TZ=UTC
# Minimal bootstrap - just get curl if missing
if ! command -v curl &> /dev/null; then
echo "πŸ“¦ Installing curl..."
apt-get update
apt-get install -y curl ca-certificates
fi
# Create the main setup script
cat << 'SETUP' > /tmp/container-setup.sh
#!/bin/bash
# Robust setup script that works in minimal containers
set -e
echo "πŸš€ Starting dev environment setup..."
# Set non-interactive to prevent prompts
export DEBIAN_FRONTEND=noninteractive
export TZ=UTC
# Configure timezone before installing packages
echo "Setting timezone to UTC..."
ln -fs /usr/share/zoneinfo/UTC /etc/localtime
echo "UTC" > /etc/timezone
echo "πŸ“¦ Installing base packages..."
# Update package list
apt-get update
# Pre-configure tzdata to avoid prompts
apt-get install -y --no-install-recommends tzdata
dpkg-reconfigure --frontend noninteractive tzdata
# Install essential packages first (including sudo)
apt-get install -y \
sudo \
curl \
wget \
ca-certificates \
gnupg \
lsb-release
# Now install all other packages
echo "πŸ“¦ Installing development packages..."
apt-get install -y \
git gh openssh-client \
build-essential pkg-config cmake \
software-properties-common \
fish zsh \
python3 python3-pip python3-venv \
libssl-dev zlib1g-dev libbz2-dev libreadline-dev \
libsqlite3-dev libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev \
unzip jq tmux htop ncdu tree
echo "πŸ‘€ Setting up developer user..."
# Create user if not exists
if ! id -u developer >/dev/null 2>&1; then
useradd -m -s /bin/bash developer # Use bash initially
echo "developer ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# Create necessary directories
mkdir -p /home/developer/.local/bin
mkdir -p /home/developer/.config
chown -R developer:developer /home/developer
fi
# Fix common workspace permissions (RunPod, Paperspace, etc.)
echo "πŸ“ Fixing workspace permissions..."
if [ -d "/workspace" ]; then
chown -R developer:developer /workspace || true
echo "βœ… Fixed /workspace ownership"
fi
# Create common ML directories
mkdir -p /workspace/{code,data,models,outputs} 2>/dev/null || true
chown -R developer:developer /workspace 2>/dev/null || true
# Create setup script for developer user
cat << 'DEVSETUP' > /tmp/developer-setup.sh
#!/bin/bash
set -e
echo "πŸ”§ Installing development tools as developer..."
# Ensure .local/bin exists and is in PATH
mkdir -p ~/.local/bin
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
# Terminal fixes
echo 'export TERM=xterm-256color' >> ~/.bashrc
echo 'export COLORTERM=truecolor' >> ~/.bashrc
# Install mise
echo "Installing mise..."
curl -fsSL https://mise.run | sh
echo 'eval "$($HOME/.local/bin/mise activate bash)"' >> ~/.bashrc
# Source bashrc to get mise in PATH
export PATH="$HOME/.local/bin:$PATH"
# Install uv
echo "Installing uv..."
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install tools using direct downloads
echo "Installing ripgrep and fd..."
cd /tmp
# Ripgrep
if ! command -v rg &> /dev/null; then
curl -LO https://github.com/BurntSushi/ripgrep/releases/download/14.1.0/ripgrep_14.1.0-1_amd64.deb
sudo dpkg -i ripgrep_14.1.0-1_amd64.deb || true
sudo apt-get install -f -y # Fix any dependency issues
fi
# fd
if ! command -v fd &> /dev/null; then
curl -LO https://github.com/sharkdp/fd/releases/download/v9.0.0/fd_9.0.0_amd64.deb
sudo dpkg -i fd_9.0.0_amd64.deb || true
sudo apt-get install -f -y # Fix any dependency issues
fi
# Install Node via mise
echo "Installing Node.js..."
~/.local/bin/mise use -g node@22
~/.local/bin/mise install
# Wait a moment for mise to settle
sleep 2
# Install Claude Code
echo "Installing Claude Code..."
~/.local/share/mise/shims/npm install -g @anthropic-ai/claude-code || \
~/.local/share/mise/shims/npm install -g @anthropic-ai/claude-code --force
# Install Helix editor
echo "Installing Helix editor..."
cd /tmp
curl -LO https://github.com/helix-editor/helix/releases/download/23.10/helix-23.10-x86_64-linux.tar.xz
tar -xf helix-23.10-x86_64-linux.tar.xz
cp helix-23.10-x86_64-linux/hx ~/.local/bin/
mkdir -p ~/.config/helix
cp -r helix-23.10-x86_64-linux/runtime ~/.config/helix/
# Configure git
git config --global init.defaultBranch main || true
git config --global core.editor hx || true
# Setup fish shell if desired
if command -v fish &> /dev/null; then
echo "Setting up fish shell..."
mkdir -p ~/.config/fish
echo 'set -gx PATH $HOME/.local/bin $PATH' >> ~/.config/fish/config.fish
echo '$HOME/.local/bin/mise activate fish | source' >> ~/.config/fish/config.fish
echo 'set -gx TERM xterm-256color' >> ~/.config/fish/config.fish
echo 'set -gx COLORTERM truecolor' >> ~/.config/fish/config.fish
# Change default shell to fish
sudo chsh -s $(which fish) developer || true
fi
# Download helper scripts
echo "Downloading helper scripts..."
mkdir -p ~/.local/bin
curl -fsSL https://gist.githubusercontent.com/darinkishore/ae380a963b96a80edf83c631ce2c8fb6/raw -o ~/.local/bin/setup-env.sh
curl -fsSL https://gist.githubusercontent.com/darinkishore/cfe2ae03d7bdd79258b2254cc5ae6f37/raw -o ~/.local/bin/gh-auth.sh
chmod +x ~/.local/bin/*.sh
# Create workspace README if workspace exists
if [ -d "/workspace" ]; then
cat << 'README' > ~/workspace-readme.md
# GPU Development Workspace
Welcome to your GPU development environment!
## Installed Tools
- **Editor**: Helix (`hx`)
- **Shell**: Fish (with pure prompt)
- **Node.js**: v22 (via mise)
- **Python**: System Python + uv package manager
- **CLI Tools**: ripgrep (`rg`), fd, git, gh, tmux
- **AI Tools**: Claude Code CLI
## Quick Commands
- Check environment: `setup-env.sh`
- Authenticate GitHub: `gh-auth.sh`
- Use Claude Code: `claude --help`
## Common Directories
- `/workspace/code` - Your code projects
- `/workspace/data` - Datasets
- `/workspace/models` - Model weights
- `/workspace/outputs` - Results
## Tips
- Use `uv pip install` for fast Python packages
- Use `mise` to manage tool versions
README
fi
# Clean up
cd ~
rm -rf /tmp/*.deb /tmp/helix-*
echo "βœ… Developer setup complete!"
DEVSETUP
chmod +x /tmp/developer-setup.sh
# Run as developer user
echo "πŸš€ Running developer setup..."
su - developer -c "bash /tmp/developer-setup.sh"
# Cleanup
rm -f /tmp/developer-setup.sh
echo ""
echo "βœ… Setup complete! Your environment is ready."
echo ""
echo "To use your new environment:"
echo " su - developer"
echo ""
echo "Installed tools:"
echo " β€’ Fish shell (default)"
echo " β€’ Helix editor (hx)"
echo " β€’ Development tools (ripgrep, fd)"
echo " β€’ Node.js 22 (via mise)"
echo " β€’ Python with uv"
echo " β€’ Claude Code CLI"
echo ""
if [ -d "/workspace" ]; then
echo "βœ… /workspace permissions fixed - you can write to it!"
fi
SETUP
chmod +x /tmp/container-setup.sh
# Run the setup
echo "πŸš€ Running setup..."
bash /tmp/container-setup.sh
# Cleanup
rm -f /tmp/container-setup.sh
echo ""
echo "πŸŽ‰ All done! Your dev environment is ready."
echo " Run: su - developer"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment