Skip to content

Instantly share code, notes, and snippets.

@pythoninthegrass
Last active August 10, 2025 08:22
Show Gist options
  • Save pythoninthegrass/38981d90300d1b6a50f128a494b36aa6 to your computer and use it in GitHub Desktop.
Save pythoninthegrass/38981d90300d1b6a50f128a494b36aa6 to your computer and use it in GitHub Desktop.
Install custom python versions in unraid
#!/usr/bin/env bash
# Modular Python installer with Docker fallback
set -e
# Help function
halp() {
cat << EOF
Usage: $(basename "$0") [version]
Installs Python with Docker fallback if source compilation fails.
Arguments:
version Python version to install (default: 3.14.0rc1)
Examples:
./install_python.sh # Installs 3.14.0rc1
./install_python.sh 3.13.0 # Installs 3.13.0
./install_python.sh 3.12.4 # Installs 3.12.4
./install_python.sh 3.15.0a1 # Installs 3.15.0a1
Options:
-h, --help Show this help message
EOF
}
# Check for help argument
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
halp
exit 0
fi
# Configuration - modularized
PYTHON_VERSION="${1:-3.14.0rc1}" # Use argument or default
PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1-2)
PYTHON_BASE_VERSION=$(echo "$PYTHON_VERSION" | sed 's/[a-z].*//') # Remove rc/a/b suffixes
INSTALL_DIR="/usr/local/python${PYTHON_MAJOR//./}"
SOURCE_URL="https://www.python.org/ftp/python/${PYTHON_BASE_VERSION}/Python-${PYTHON_VERSION}.tgz"
DOCKER_TAG="${PYTHON_VERSION}-slim"
log_info() {
echo "[INFO] $1"
}
log_error() {
echo "[ERROR] $1"
}
# Download Python source
log_info "Downloading Python $PYTHON_VERSION source..."
cd /tmp
wget -O "Python-$PYTHON_VERSION.tgz" "$SOURCE_URL" || {
log_error "Source not available. Using Docker approach..."
# Alternative: Use Docker to compile
log_info "Building in Docker container..."
docker run --rm -v /usr/local:/host-usr-local python:${DOCKER_TAG} sh -c "
cp -r /usr/local/bin/python* /host-usr-local/bin/ 2>/dev/null || true
cp -r /usr/local/lib/python${PYTHON_MAJOR} /host-usr-local/lib/ 2>/dev/null || true
cp -r /usr/local/lib/libpython* /host-usr-local/lib/ 2>/dev/null || true
cp -r /usr/local/include/python${PYTHON_MAJOR} /host-usr-local/include/ 2>/dev/null || true
"
# Update library cache
echo "/usr/local/lib" >> /etc/ld.so.conf.d/python${PYTHON_MAJOR//./}.conf
ldconfig
if command -v python${PYTHON_MAJOR} &> /dev/null; then
log_info "Python $PYTHON_VERSION installed via Docker"
python${PYTHON_MAJOR} --version
exit 0
fi
log_error "Docker method failed"
exit 1
}
# Extract and install
log_info "Installing..."
mkdir -p "$INSTALL_DIR"
tar -xzf "Python-$PYTHON_VERSION.tgz" -C "$INSTALL_DIR" --strip-components=1
# Create symlinks
ln -sf "$INSTALL_DIR/bin/python${PYTHON_MAJOR}" /usr/local/bin/python${PYTHON_MAJOR}
ln -sf "$INSTALL_DIR/bin/pip${PYTHON_MAJOR}" /usr/local/bin/pip${PYTHON_MAJOR}
# Update library paths
echo "$INSTALL_DIR/lib" > /etc/ld.so.conf.d/python${PYTHON_MAJOR//./}.conf
ldconfig
log_info "Python $PYTHON_VERSION installed successfully"
python${PYTHON_MAJOR} --version
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment