DEV Community

abbazs
abbazs

Posted on • Edited on

A setup script to install developer applications like docker, vscode, git, etc in debian based linux.

Here is a bash script that I've been working to install some of the applications that I install after setting up a new system:

Save the contents to a file named setup.sh anywhere, change the file permission and execute it.

#!/bin/bash VPNROOT="/usr/local/vpnclient" VPNCLIENT="$VPNROOT/vpnclient" # Function to handle errors handle_error() { # Print error message in red color and bold font local line_number=$1 local error_message=$2 echo -e "\033[1;31mError at line $line_number: $error_message\033[0m" exit 1 } # Enable error handling set -e # Trap errors and call the handle_error function trap 'handle_error ${LINENO} "Script execution failed"' ERR # Function to print colored text print_color() { local color=$1 shift local text=$@ echo -e "\033[${color}m${text}\033[0m" } # Function to check if a package is already installed package_installed() { command -v "$1" &>/dev/null } # Function to check if the SoftEtherVPN Client is installed softether_vpnclient_installed() { # Check if the file exists and if the command can be executed successfully if [ -f $VPNCLIENT ]; then return 0 else return 1 fi } add_microsoft_gpg() { if [ ! -f /etc/apt/trusted.gpg.d/microsoft.gpg ]; then # Check if the URL is reachable if ! curl --silent --head --fail https://packages.microsoft.com/keys/microsoft.asc >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://packages.microsoft.com/keys/microsoft.asc" fi curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor >microsoft.gpg sudo install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/ sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge-dev.list' sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/code stable main" > /etc/apt/sources.list.d/vscode.list' sudo rm microsoft.gpg sudo aptitude update || handle_error ${LINENO} "Failed to update aptitude" fi } # Dictionary to store application names and their installation status declare -A apps=( ["nvm"]="NVM" ["code"]="Visual Studio Code" ["microsoft-edge-stable"]="Microsoft Edge" ["google-chrome-stable"]="Google Chrome" ["docker"]="Docker" ["pyenv"]="Pyenv" ["poetry"]="Poetry" ["softether-vpnclient"]="SoftEtherVPN Client" ) # Dictionary to store installed applications installed_apps=() # Dictionary to store not installed applications not_installed_apps=() # Iterate over the dictionary and check installation status for app in "${!apps[@]}"; do echo "Checking $app" if package_installed "$app"; then installed_apps+=("$app") elif [ "$app" == "softether-vpnclient" ] && softether_vpnclient_installed; then installed_apps+=("$app") else not_installed_apps+=("$app") fi done # Display installation summary print_color 41 "---------------------" print_color 45 "Installation Summary:" print_color 41 "---------------------" if [ "${#installed_apps[@]}" -gt 0 ]; then print_color 45 "Installed applications:" print_color 41 "-----------------------" for app in "${installed_apps[@]}"; do echo -e "\e[1;32m[${apps[$app]}] $app\e[0m" done print_color 41 "-----------------------" fi if [ "${#not_installed_apps[@]}" -gt 0 ]; then print_color 45 "Not installed applications:" print_color 41 "---------------------------" for app in "${not_installed_apps[@]}"; do echo -e "\e[1;33m[${apps[$app]}] $app\e[0m" done print_color 41 "---------------------------" fi # Prompt user for installation read -p "Do you want to install any missing applications? (y/n): " choice if [[ $choice =~ ^[Yy]$ ]]; then # Check if aptitude is installed if ! package_installed aptitude; then echo "aptitude package manager not found. Installing aptitude..." sudo apt-get update || handle_error ${LINENO} "Failed to update packages" sudo apt-get install -y aptitude || handle_error ${LINENO} "Failed to install aptitude" sudo aptitude update || handle_error ${LINENO} "Failed to update aptitude" sudo aptitude install -y apt-transport-https \ ca-certificates \ curl \ software-properties-common \ gnupg \ git \ build-essential \ libbz2-dev \ libffi-dev \ liblzma-dev \ libncursesw5-dev \ libreadline-dev \ libsqlite3-dev \ libssl-dev \ libxml2-dev \ libxmlsec1-dev \ llvm \ tk-dev \ xz-utils \ zlib1g-dev \ jq \ meld || handle_error ${LINENO} "Failed to install required packages" fi # Install microsoft gpg certificates add_microsoft_gpg # Install missing applications for app in "${not_installed_apps[@]}"; do echo "Installing ${apps[$app]}..." # Add installation steps for each application here # Example: Install NVM if [ "$app" == "nvm" ]; then # Add NVM installation steps here if ! curl --silent --head --fail https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh" fi curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi # Example: Install Visual Studio Code if [ "$app" == "code" ]; then sudo aptitude install -y code echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi # Check if the app is "microsoft-edge-stable" if [ "$app" == "microsoft-edge-stable" ]; then # Add Microsoft Edge installation steps here sudo aptitude install -y $app || handle_error "[${apps[$app]}] Failed to install $app." echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi # Check if the app is "google-chrome-stable" if [ "$app" == "google-chrome-stable" ]; then # Add Google Chrome installation steps here # Check if the URL is reachable if ! curl --silent --head --fail https://dl.google.com/linux/linux_signing_key.pub >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://dl.google.com/linux/linux_signing_key.pub" fi curl -fsSL https://dl.google.com/linux/linux_signing_key.pub | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/google.gpg >/dev/null sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list' sudo aptitude update || handle_error "Failed to update aptitude" sudo aptitude install -y google-chrome-stable || handle_error "[${apps[$app]}] Failed to install $app." echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi # Check if the app is "docker" if [ "$app" == "docker" ]; then # Add Docker installation steps here # Check if the URL is reachable if ! curl --silent --head --fail https://download.docker.com/linux/ubuntu/gpg >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://download.docker.com/linux/ubuntu/gpg" fi curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor >docker.gpg sudo install -o root -g root -m 644 docker.gpg /etc/apt/trusted.gpg.d/ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/trusted.gpg.d/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null sudo rm docker.gpg if ! curl --silent --head --fail https://download.docker.com/linux/ubuntu >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://download.docker.com/linux/ubuntu" fi sudo aptitude update || handle_error${LINENO} "Failed to update aptitude" sudo aptitude install -y docker-ce docker-ce-cli containerd.io || handle_error ${LINENO} "[${apps[$app]}] Failed to install $app." # Add the current user to the docker group if ! grep -q "^docker:" /etc/group; then sudo groupadd docker sudo usermod -aG docker $USER fi # Check if the URL is reachable if ! curl --silent --head --fail "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install Docker Compose. Unable to reach the URL: https://github.com/docker/compose/releases/latest" fi # Install Docker Compose sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" \ -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi # Check if the app is "pyenv" if [ "$app" == "pyenv" ]; then # Add Pyenv installation steps here # Check if the URL is reachable if ! curl --silent --head --fail https://pyenv.run >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://pyenv.run" else if ! curl https://pyenv.run | bash >/dev/null 2>&1; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app." else echo "" >>~/.bashrc echo "# Add pyenv to path" >>~/.bashrc echo 'export PYENV_ROOT="$HOME/.pyenv"' >>~/.bashrc echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >>~/.bashrc echo 'eval "$(pyenv init -)"' >>~/.bashrc export PATH="$HOME/.pyenv/bin:$PATH" eval "$(pyenv init --path)" echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi fi fi # Example: Install Poetry if [ "$app" == "poetry" ]; then # Add Poetry installation steps here if ! curl --silent --head --fail https://install.python-poetry.org >/dev/null; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app. Unable to reach the URL: https://install.python-poetry.org" else if ! command -v python >/dev/null 2>&1; then PYTHON_EXECUTABLE="python3" else PYTHON_EXECUTABLE="python" fi if ! curl -sSL https://install.python-poetry.org | "$PYTHON_EXECUTABLE" - >/dev/null 2>&1; then handle_error ${LINENO} "[${apps[$app]}] Failed to install $app." else export PATH="$HOME/.local/bin:$PATH" echo -e "\e[1;32m[${apps[$app]}] $app has been installed.\e[0m" fi fi fi # Example: Install SoftEtherVPN Client if [ "$app" == "softether-vpnclient" ]; then # Add SoftEtherVPN Client installation steps here api_url="https://api.github.com/repos/SoftEtherVPN/SoftEtherVPN_Stable/releases/latest" # Check if the URL is reachable if ! curl --silent --head --fail "$api_url" >/dev/null; then handle_error ${LINENO} "Failed to install $app. Unable to reach the URL: $api_url" fi response=$(curl -s "$api_url") build_tag=$(echo "$response" | jq -r '.tag_name') published_date=$(echo "$response" | jq -r '.published_at') published_date=$(date -u -d "$published_date" +%Y.%m.%d) arc=$(uname -m | rev | cut -c 1-2 | rev) url="https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/${build_tag}/softether-vpnclient-${build_tag}-${published_date}-linux-x64-64bit.tar.gz" # Check if the URL is reachable if ! curl --silent --head --fail "$url" >/dev/null; then handle_error ${LINENO} "Failed to install $app. Unable to reach the URL: $url" fi # curl -O -L $url # Extract SoftEtherVPN Client and handle errors if ! tar xzvf "softether-vpnclient-${build_tag}-${published_date}-linux-x64-64bit.tar.gz"; then handle_error ${LINENO} "Failed to extract $app." fi cd vpnclient # Compile SoftEtherVPN Client if ! make; then cd .. handle_error ${LINENO} "Failed to compile $app." fi cd .. sudo mv vpnclient /usr/local || handle_error ${LINENO} "Unable to move vpnclient to /usr/local" # Start SoftEtherVPN Client and handle errors if ! sudo $VPNCLIENT start; then handle_error ${LINENO} "Failed to start vpnclient" fi echo -e "\e[1;32m$app has been installed.\e[0m" fi done echo "Installation complete." else echo "No applications will be installed." fi 
Enter fullscreen mode Exit fullscreen mode

Top comments (1)

Collapse
 
nricks profile image
nricks • Edited

I think they repackaged compose into an actual docker plugin installable from the repo that you run as "docker compose up" instead of the way you're doing it, there is actually some since QoL stuff in it even in the naming conventions alone.