#!/bin/bash set -o errexit # Regular Colors Black='\033[0;30m' # Black Red='\[\e[0;31m\]' # Red Green='\033[0;32m' # Green Yellow='\033[0;33m' # Yellow Blue='\033[0;34m' # Blue Purple='\033[0;35m' # Purple Cyan='\033[0;36m' # Cyan White='\033[0;37m' # White NC='\033[0m' # No Color is_command_present() { type "$1" >/dev/null 2>&1 } # Check whether 'wget' command exists. has_wget() { has_cmd wget } # Check whether 'curl' command exists. has_curl() { has_cmd curl } # Check whether the given command exists. has_cmd() { command -v "$1" > /dev/null 2>&1 } is_mac() { [[ $OSTYPE == darwin* ]] } is_arm64(){ [[ `uname -m` == 'arm64' || `uname -m` == 'aarch64' ]] } check_os() { if is_mac; then package_manager="brew" desired_os=1 os="Mac" return fi if is_arm64; then arch="arm64" arch_official="aarch64" else arch="amd64" arch_official="x86_64" fi platform=$(uname -s | tr '[:upper:]' '[:lower:]') os_name="$(cat /etc/*-release | awk -F= '$1 == "NAME" { gsub(/"/, ""); print $2; exit }')" case "$os_name" in Ubuntu*|Pop!_OS) desired_os=1 os="ubuntu" package_manager="apt-get" ;; Amazon\ Linux*) desired_os=1 os="amazon linux" package_manager="yum" ;; Debian*) desired_os=1 os="debian" package_manager="apt-get" ;; Linux\ Mint*) desired_os=1 os="linux mint" package_manager="apt-get" ;; Red\ Hat*) desired_os=1 os="red hat" package_manager="yum" ;; CentOS*) desired_os=1 os="centos" package_manager="yum" ;; Rocky*) desired_os=1 os="centos" package_manager="yum" ;; SLES*) desired_os=1 os="sles" package_manager="zypper" ;; openSUSE*) desired_os=1 os="opensuse" package_manager="zypper" ;; *) desired_os=0 os="Not Found: $os_name" esac } # This function checks if the relevant ports required by SigNoz are available or not # The script should error out in case they aren't available check_ports_occupied() { local port_check_output local ports_pattern="3301|4317" if is_mac; then port_check_output="$(netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /^.*\.('"$ports_pattern"')$/')" elif is_command_present ss; then # The `ss` command seems to be a better/faster version of `netstat`, but is not available on all Linux # distributions by default. Other distributions have `ss` but no `netstat`. So, we try for `ss` first, then # fallback to `netstat`. port_check_output="$(ss --all --numeric --tcp | awk '$1 == "LISTEN" && $4 ~ /^.*:('"$ports_pattern"')$/')" elif is_command_present netstat; then port_check_output="$(netstat --all --numeric --tcp | awk '$6 == "LISTEN" && $4 ~ /^.*:('"$ports_pattern"')$/')" fi if [[ -n $port_check_output ]]; then send_event "port_not_available" echo "+++++++++++ ERROR ++++++++++++++++++++++" echo "SigNoz requires ports 3301 & 4317 to be open. Please shut down any other service(s) that may be running on these ports." echo "You can run SigNoz on another port following this guide https://signoz.io/docs/install/troubleshooting/" echo "++++++++++++++++++++++++++++++++++++++++" echo "" exit 1 fi } install_docker() { echo "++++++++++++++++++++++++" echo "Setting up docker repos" if [[ $package_manager == apt-get ]]; then apt_cmd="$sudo_cmd apt-get --yes --quiet" $apt_cmd update $apt_cmd install software-properties-common gnupg-agent curl -fsSL "https://download.docker.com/linux/$os/gpg" | $sudo_cmd apt-key add - $sudo_cmd add-apt-repository \ "deb [arch=$arch] https://download.docker.com/linux/$os $(lsb_release -cs) stable" $apt_cmd update echo "Installing docker" $apt_cmd install docker-ce docker-ce-cli containerd.io elif [[ $package_manager == zypper ]]; then zypper_cmd="$sudo_cmd zypper --quiet --no-gpg-checks --non-interactive" echo "Installing docker" if [[ $os == sles ]]; then os_sp="$(cat /etc/*-release | awk -F= '$1 == "VERSION_ID" { gsub(/"/, ""); print $2; exit }')" os_arch="$(uname -i)" SUSEConnect -p sle-module-containers/$os_sp/$os_arch -r '' fi $zypper_cmd install docker docker-runc containerd $sudo_cmd systemctl enable docker.service elif [[ $package_manager == yum && $os == 'amazon linux' ]]; then echo echo "Amazon Linux detected ... " echo # yum install docker # service docker start $sudo_cmd yum install -y amazon-linux-extras $sudo_cmd amazon-linux-extras enable docker $sudo_cmd yum install -y docker else yum_cmd="$sudo_cmd yum --assumeyes --quiet" $yum_cmd install yum-utils $sudo_cmd yum-config-manager --add-repo https://download.docker.com/linux/$os/docker-ce.repo echo "Installing docker" $yum_cmd install docker-ce docker-ce-cli containerd.io fi } compose_version () { local compose_version compose_version="$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4)" echo "${compose_version:-v2.18.1}" } install_docker_compose() { if [[ $package_manager == "apt-get" || $package_manager == "zypper" || $package_manager == "yum" ]]; then if [[ ! -f /usr/bin/docker-compose ]];then echo "++++++++++++++++++++++++" echo "Installing docker-compose" compose_url="https://github.com/docker/compose/releases/download/$(compose_version)/docker-compose-$platform-$arch_official" echo "Downloading docker-compose from $compose_url" $sudo_cmd curl -L "$compose_url" -o /usr/local/bin/docker-compose $sudo_cmd chmod +x /usr/local/bin/docker-compose $sudo_cmd ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose echo "docker-compose installed!" echo "" fi else send_event "docker_compose_not_found" echo "+++++++++++ IMPORTANT READ ++++++++++++++++++++++" echo "docker-compose not found! Please install docker-compose first and then continue with this installation." echo "Refer https://docs.docker.com/compose/install/ for installing docker-compose." echo "+++++++++++++++++++++++++++++++++++++++++++++++++" exit 1 fi } start_docker() { echo -e "šŸ³ Starting Docker ...\n" if [[ $os == "Mac" ]]; then open --background -a Docker && while ! docker system info > /dev/null 2>&1; do sleep 1; done else if ! $sudo_cmd systemctl is-active docker.service > /dev/null; then echo "Starting docker service" $sudo_cmd systemctl start docker.service fi # if [[ -z $sudo_cmd ]]; then # docker ps > /dev/null && true # if [[ $? -ne 0 ]]; then # request_sudo # fi # fi if [[ -z $sudo_cmd ]]; then if ! docker ps > /dev/null && true; then request_sudo fi fi fi } wait_for_containers_start() { local timeout=$1 # The while loop is important because for-loops don't work for dynamic values while [[ $timeout -gt 0 ]]; do status_code="$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:3301/api/v1/health?live=1" || true)" if [[ status_code -eq 200 ]]; then break else echo -ne "Waiting for all containers to start. This check will timeout in $timeout seconds ...\r\c" fi ((timeout--)) sleep 1 done echo "" } bye() { # Prints a friendly good bye message and exits the script. if [[ "$?" -ne 0 ]]; then set +o errexit echo "šŸ”“ The containers didn't seem to start correctly. Please run the following command to check containers that may have errored out:" echo "" echo -e "$sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml ps -a" echo "Please read our troubleshooting guide https://signoz.io/docs/install/troubleshooting/" echo "or reach us for support in #help channel in our Slack Community https://signoz.io/slack" echo "++++++++++++++++++++++++++++++++++++++++" if [[ $email == "" ]]; then echo -e "\nšŸ“Ø Please share your email to receive support with the installation" read -rp 'Email: ' email while [[ $email == "" ]] do read -rp 'Email: ' email done fi send_event "installation_support" echo "" echo -e "\nWe will reach out to you at the email provided shortly, Exiting for now. Bye! šŸ‘‹ \n" exit 0 fi } request_sudo() { if hash sudo 2>/dev/null; then echo -e "\n\nšŸ™‡ We will need sudo access to complete the installation." if (( $EUID != 0 )); then sudo_cmd="sudo" echo -e "Please enter your sudo password, if prompted." # $sudo_cmd -l | grep -e "NOPASSWD: ALL" > /dev/null # if [[ $? -ne 0 ]] && ! $sudo_cmd -v; then # echo "Need sudo privileges to proceed with the installation." # exit 1; # fi if ! $sudo_cmd -l | grep -e "NOPASSWD: ALL" > /dev/null && ! $sudo_cmd -v; then echo "Need sudo privileges to proceed with the installation." exit 1; fi echo -e "Got it! Thanks!! šŸ™\n" echo -e "Okay! We will bring up the SigNoz cluster from here šŸš€\n" fi fi } echo "" echo -e "šŸ‘‹ Thank you for trying out SigNoz! " echo "" sudo_cmd="" # Check sudo permissions if (( $EUID != 0 )); then echo "šŸŸ” Running installer with non-sudo permissions." echo " In case of any failure or prompt, please consider running the script with sudo privileges." echo "" else sudo_cmd="sudo" fi # Checking OS and assigning package manager desired_os=0 os="" email="" echo -e "šŸŒ Detecting your OS ...\n" check_os # Obtain unique installation id # sysinfo="$(uname -a)" # if [[ $? -ne 0 ]]; then # uuid="$(uuidgen)" # uuid="${uuid:-$(cat /proc/sys/kernel/random/uuid)}" # sysinfo="${uuid:-$(cat /proc/sys/kernel/random/uuid)}" # fi if ! sysinfo="$(uname -a)"; then uuid="$(uuidgen)" uuid="${uuid:-$(cat /proc/sys/kernel/random/uuid)}" sysinfo="${uuid:-$(cat /proc/sys/kernel/random/uuid)}" fi digest_cmd="" if hash shasum 2>/dev/null; then digest_cmd="shasum -a 256" elif hash sha256sum 2>/dev/null; then digest_cmd="sha256sum" elif hash openssl 2>/dev/null; then digest_cmd="openssl dgst -sha256" fi if [[ -z $digest_cmd ]]; then SIGNOZ_INSTALLATION_ID="$sysinfo" else SIGNOZ_INSTALLATION_ID=$(echo "$sysinfo" | $digest_cmd | grep -E -o '[a-zA-Z0-9]{64}') fi # echo "" # echo -e "šŸ‘‰ ${RED}Two ways to go forward\n" # echo -e "${RED}1) ClickHouse as database (default)\n" # read -p "āš™ļø Enter your preference (1/2):" choice_setup # while [[ $choice_setup != "1" && $choice_setup != "2" && $choice_setup != "" ]] # do # # echo $choice_setup # echo -e "\nāŒ ${CYAN}Please enter either 1 or 2" # read -p "āš™ļø Enter your preference (1/2): " choice_setup # # echo $choice_setup # done # if [[ $choice_setup == "1" || $choice_setup == "" ]];then # setup_type='clickhouse' # fi setup_type='clickhouse' # echo -e "\nāœ… ${CYAN}You have chosen: ${setup_type} setup\n" # Run bye if failure happens trap bye EXIT URL="https://api.segment.io/v1/track" HEADER_1="Content-Type: application/json" HEADER_2="Authorization: Basic OWtScko3b1BDR1BFSkxGNlFqTVBMdDVibGpGaFJRQnI=" send_event() { error="" case "$1" in 'install_started') event="Installation Started" ;; 'os_not_supported') event="Installation Error" error="OS Not Supported" ;; 'docker_not_installed') event="Installation Error" error="Docker not installed" ;; 'docker_compose_not_found') event="Installation Error" event="Docker Compose not found" ;; 'port_not_available') event="Installation Error" error="port not available" ;; 'installation_error_checks') event="Installation Error - Checks" error="Containers not started" others='"data": "some_checks",' ;; 'installation_support') event="Installation Support" others='"email": "'"$email"'",' ;; 'installation_success') event="Installation Success" ;; 'identify_successful_installation') event="Identify Successful Installation" others='"email": "'"$email"'",' ;; *) print_error "unknown event type: $1" exit 1 ;; esac if [[ "$error" != "" ]]; then error='"error": "'"$error"'", ' fi DATA='{ "anonymousId": "'"$SIGNOZ_INSTALLATION_ID"'", "event": "'"$event"'", "properties": { "os": "'"$os"'", '"$error $others"' "setup_type": "'"$setup_type"'" } }' if has_curl; then curl -sfL -d "$DATA" --header "$HEADER_1" --header "$HEADER_2" "$URL" > /dev/null 2>&1 elif has_wget; then wget -q --post-data="$DATA" --header "$HEADER_1" --header "$HEADER_2" "$URL" > /dev/null 2>&1 fi } send_event "install_started" if [[ $desired_os -eq 0 ]]; then send_event "os_not_supported" fi # check_ports_occupied # Check is Docker daemon is installed and available. If not, the install & start Docker for Linux machines. We cannot automatically install Docker Desktop on Mac OS if ! is_command_present docker; then if [[ $package_manager == "apt-get" || $package_manager == "zypper" || $package_manager == "yum" ]]; then request_sudo install_docker # enable docker without sudo from next reboot sudo usermod -aG docker "${USER}" elif is_mac; then echo "" echo "+++++++++++ IMPORTANT READ ++++++++++++++++++++++" echo "Docker Desktop must be installed manually on Mac OS to proceed. Docker can only be installed automatically on Ubuntu / openSUSE / SLES / Redhat / Cent OS" echo "https://docs.docker.com/docker-for-mac/install/" echo "++++++++++++++++++++++++++++++++++++++++++++++++" send_event "docker_not_installed" exit 1 else echo "" echo "+++++++++++ IMPORTANT READ ++++++++++++++++++++++" echo "Docker must be installed manually on your machine to proceed. Docker can only be installed automatically on Ubuntu / openSUSE / SLES / Redhat / Cent OS" echo "https://docs.docker.com/get-docker/" echo "++++++++++++++++++++++++++++++++++++++++++++++++" send_event "docker_not_installed" exit 1 fi fi # Install docker-compose if ! is_command_present docker-compose; then request_sudo install_docker_compose fi start_docker # $sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml up -d --remove-orphans || true echo "" echo -e "\nšŸŸ” Pulling the latest container images for SigNoz.\n" $sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml pull echo "" echo "šŸŸ” Starting the SigNoz containers. It may take a few minutes ..." echo # The docker-compose command does some nasty stuff for the `--detach` functionality. So we add a `|| true` so that the # script doesn't exit because this command looks like it failed to do it's thing. $sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml up --detach --remove-orphans || true wait_for_containers_start 60 echo "" if [[ $status_code -ne 200 ]]; then echo "+++++++++++ ERROR ++++++++++++++++++++++" echo "šŸ”“ The containers didn't seem to start correctly. Please run the following command to check containers that may have errored out:" echo "" echo -e "$sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml ps -a" echo "Please read our troubleshooting guide https://signoz.io/docs/install/troubleshooting/" echo "or reach us on SigNoz for support https://signoz.io/slack" echo "++++++++++++++++++++++++++++++++++++++++" send_event "installation_error_checks" exit 1 else send_event "installation_success" echo "++++++++++++++++++ SUCCESS ++++++++++++++++++++++" echo "" echo "šŸŸ¢ Your installation is complete!" echo "" echo -e "šŸŸ¢ Your frontend is running on http://localhost:3301" echo "" echo "ā„¹ļø By default, retention period is set to 15 days for logs and traces, and 30 days for metrics." echo -e "To change this, navigate to the General tab on the Settings page of SigNoz UI. For more details, refer to https://signoz.io/docs/userguide/retention-period \n" echo "ā„¹ļø To bring down SigNoz and clean volumes : $sudo_cmd docker-compose -f ./docker/clickhouse-setup/docker-compose.yaml down -v" echo "" echo "+++++++++++++++++++++++++++++++++++++++++++++++++" echo "" echo "šŸ‘‰ Need help in Getting Started?" echo -e "Join us on Slack https://signoz.io/slack" echo "" echo -e "\nšŸ“Ø Please share your email to receive support & updates about SigNoz!" read -rp 'Email: ' email while [[ $email == "" ]] do read -rp 'Email: ' email done send_event "identify_successful_installation" fi echo -e "\nšŸ™ Thank you!\n"