diff --git a/README.md b/README.md index b70f9bec..16629fd8 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,6 @@ The most convenient way to install the Bluecherry docker image is to use this sc The included Dockerfile generates an image based on an **Ubuntu 20.04** docker image. The latest tagged version of the **Bluecherry Server v3.x.x** from the [bluecherry-apps](https://github.com/bluecherrydvr/bluecherry-apps) source repository. The included docker-compose file uses **MySQL version 8.x.x** to host the bluecherry database. -The current version of this docker code intends to build a bluecherry docker image that is as small as possible, and which does *not* bake in any configuration into the image (since docker images are intended to be ephemeral). - Instead, needed configuration parameters such as database and server passwords are passed into the docker container via environment variables. Environment variables are defined and passed using typical methods with `docker` or `docker-compose` commands. ## Initialization and Usage diff --git a/scripts/install.sh b/scripts/install.sh old mode 100644 new mode 100755 index 9e9fd1ea..a7a8e5f6 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,11 +1,13 @@ -#!/bin/sh +#!/bin/bash set -e +set -u +set -o pipefail export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # Make sure we are root or we sudo'd! -[ $(id -u) != "0" ] && { echo "Error: You must be root to run this script"; exit 1; } +[ "$(id -u)" != "0" ] && { echo "Error: You must be root to run this script"; exit 1; } # set the current path so we aren't confused when moving directories. Always assuming $workingpath/bluecherry-docker for all Bluecherry scripts @@ -25,67 +27,67 @@ check_docker_process() { docker_compose_init() { -# Make sure we are still in the bluecherry-docker directory + # Make sure we are still in the bluecherry-docker directory -#uptimekuma + #uptimekuma -echo "Downloading latest Bluecherry and related images...this may take a while..." + echo "Downloading latest Bluecherry and related images...this may take a while..." -cd "$workingpath/bluecherry-docker" + cd "$workingpath/bluecherry-docker" -# Init the mailenv config + # Init the mailenv config -cp $workingpath/bluecherry-docker/mailenv-example $workingpath/bluecherry-docker/.mailenv + cp "$workingpath"/bluecherry-docker/mailenv-example "$workingpath"/bluecherry-docker/.mailenv -docker compose pull -docker compose up bc-mysql -d + docker compose pull + docker compose up bc-mysql -d -echo "Sleeping 45 seconds to make sure the database is initialized correctly..." + echo "Sleeping 45 seconds to make sure the database is initialized correctly..." -sleep 45 -docker compose stop bc-mysql -docker compose up -d bc-mysql + sleep 45 + docker compose stop bc-mysql + docker compose up -d bc-mysql -echo "Sleeping another 15 seconds to run the database creation scripts..." -echo "\n\n" + echo "Sleeping another 15 seconds to run the database creation scripts..." + echo -e "\n\n" -sleep 15 -docker compose run bluecherry bc-database-create -docker compose down -#for i in {1..50}; do -# if docker compose pull; then -# if docker compose up -d; then -# break -# fi -# fi + sleep 15 + docker compose run bluecherry bc-database-create + docker compose down + #for i in {1..50}; do + # if docker compose pull; then + # if docker compose up -d; then + # break + # fi + # fi sleep 10 -docker compose up -d -#done + docker compose up -d + #done } configure_env() { -echo "\n\n******************************************************************\n\n" -echo "You will be asked the following to configure the docker container: + echo -e "\n\n******************************************************************\n\n" + echo "You will be asked the following to configure the docker container: Time Zone (formatted like this - See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) Create a password for the mysql admin Create a password for the mysql bluecherry user " -echo "Time Zone (i.e. - America/Chicago): " -read timezoneset + echo "Time Zone (i.e. - America/Chicago): " + read -r timezoneset -#read -p "Time Zone (i.e. - America/Chicago):" timezone -#timezoneset="${timezone:=American/Chicago}" -read -p "Please provide a mysql admin password:" mysqladminpass -read -p "Please provide a mysql bluecherry password:" mysqlbluecherrypass + #read -p "Time Zone (i.e. - America/Chicago):" timezone + #timezoneset="${timezone:=American/Chicago}" + read -r -p "Please provide a mysql admin password:" mysqladminpass + read -r -p "Please provide a mysql bluecherry password:" mysqlbluecherrypass -# Install variables -echo " + # Install variables + echo " # Set to your desired timezone. See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones TZ=$timezoneset @@ -118,7 +120,7 @@ BLUECHERRY_USERHOST=% # UID/GID to run bluecherry user as. If you want to access recordings from the host, it is # recommended to set them the same as a user/group that you want access to read it. -# run `id $(whoami)` to find the UID/GID of your user +# run \`id \$(whoami)\` to find the UID/GID of your user BLUECHERRY_GROUP_ID=1000 BLUECHERRY_USER_ID=1000 @@ -128,17 +130,16 @@ BLUECHERRY_USER_ID=1000 configure_smtp() { -echo "Configure SMTP" + echo "Configure SMTP" -read -p "Please provide the SMTP server: " smtpserver -read -p "Please provide the SMTP username: " smtplogin -read -p "Please provide the SMTP password: " smtppassword -read -p "Please provide the SMTP port: " smtpport -#read -p "Please provide the SMTP username: " smtplogin + read -r -p "Please provide the SMTP server: " smtpserver + read -r -p "Please provide the SMTP username: " smtplogin + read -r -p "Please provide the SMTP password: " smtppassword + read -r -p "Please provide the SMTP port: " smtpport + #read -p "Please provide the SMTP username: " smtplogin -#read -p "Please provide the NFS mount point for the NFS export" nfsmountpoint -echo " + echo " SMTP_USERNAME=$smtplogin SMTP_PASSWORD=$smtppassword @@ -147,58 +148,55 @@ SMTP_PORT=$smtpport SERVER_HOSTNAME=$smtpserver ALWAYS_ADD_MISSING_HEADERS=yes -" > $workingpath/bluecherry-docker/.mailenv +" > "$workingpath"/bluecherry-docker/.mailenv } check_process() { - process_name=$1 - status=$(docker ps --filter "name=$process_name" --format '{{.Names}}' | grep -w "$process_name") - - if [ -n "$status" ]; then - echo "\e[32m$process_name is running\e[0m" # Green color for running process - -#exit 1 - else - echo "\e[31m$process_name is not running\e[0m" # Red color for not running process - fi -#exit 1 + process_name=$1 + status=$(docker ps --filter "name=$process_name" --format '{{.Names}}' | grep -w "$process_name") + if [ -n "$status" ]; then + echo "\e[32m$process_name is running\e[0m" # Green color for running process + #exit 1 + else + echo "\e[31m$process_name is not running\e[0m" # Red color for not running process + fi + #exit 1 } check_docker_processes() { - if docker ps --format '{{.Names}}' | grep -q -w 'bc-server' && docker ps --format '{{.Names}}' | grep -q -w 'bc-mysql'; then - echo "**********************************************************************" - echo - echo "Installation finished, you can access the Bluecherry server here below" - echo "The default login is Admin and the default password is bluecherry" - echo - echo "https://$IP:7001" - echo - echo "**********************************************************************" - else - echo -e "\n\n\e[31mWARNING: Either bc-server or bc-mysql process is not running in Docker. Below is a listing of the current bc-server and bc-mysql processes\e[0m\n\n" - echo -e "If you are unable to resolve this issue please visit the Bluecherry community at https://forums.bluecherrydvr.com\n\n" - echo -e "Below are statuses of the 'bc-server' and 'bc-mysql' containers:\n\n" -check_process "bc-server" -check_process "bc-mysql" - echo -e "\n\n" + if docker ps --format '{{.Names}}' | grep -q -w 'bc-server' && docker ps --format '{{.Names}}' | grep -q -w 'bc-mysql'; then + echo "**********************************************************************" + echo + echo "Installation finished, you can access the Bluecherry server here below" + echo "The default login is Admin and the default password is bluecherry" + echo + echo "https://$IP:7001" + echo + echo "**********************************************************************" + else + echo -e "\n\n\e[31mWARNING: Either bc-server or bc-mysql process is not running in Docker. Below is a listing of the current bc-server and bc-mysql processes\e[0m\n\n" + echo -e "If you are unable to resolve this issue please visit the Bluecherry community at https://forums.bluecherrydvr.com\n\n" + echo -e "Below are statuses of the 'bc-server' and 'bc-mysql' containers:\n\n" + check_process "bc-server" + check_process "bc-mysql" + echo -e "\n\n" - fi + fi } configure_nfs() { -echo "installing nfs" + echo "installing nfs" -read -p "Please provide the IP address of the NFS server: " nfsserver -read -p "Please provide the NFS server export path: " nfsexport -#read -p "Please provide the NFS mount point for the NFS export" nfsmountpoint + read -r -p "Please provide the IP address of the NFS server: " nfsserver + read -r -p "Please provide the NFS server export path: " nfsexport -echo " + echo " version: '3.8' services: @@ -211,37 +209,38 @@ services: volumes: videos: driver_opts: - type: "nfs" - o: "addr=$nfsserver,nolock,soft" - device: ":$nfsexport" -" > $workingpath/bluecherry-docker/docker-compose.override.yml + type: \"nfs\" + o: \"addr=$nfsserver,nolock,soft\" + device: \":$nfsexport\" +" > "$workingpath"/bluecherry-docker/docker-compose.override.yml } clone_bluecherrydocker() { - local directory=$pwd/bluecherry-docker + local directory + directory="$(pwd)"/bluecherry-docker if [ -d "$directory" ]; then echo "Directory $directory exists...skipping...." - return 0 -else + return 0 + else -echo "Directory $directory...proceeding with cloning" + echo "Directory $directory...proceeding with cloning" -cd "$workingpath" -#mkdir bluecherry-server -#cd bluecherry-server -git clone https://github.com/bluecherrydvr/bluecherry-docker.git + cd "$workingpath" + #mkdir bluecherry-server + #cd bluecherry-server + git clone https://github.com/bluecherrydvr/bluecherry-docker.git -# Sigh...Fedora LXC containers and maybe others set max keys at 2000. We need more. For now more systems are needed to test on. -# https://unix.stackexchange.com/questions/600968/disk-quota-exceeded-when-trying-to-deploy-docker-container-inside-lxc -#echo 5000 | tee /proc/sys/kernel/keys/maxkeys -#echo "kernel.keys.maxkeys=5000" > /etc/sysctl.d/99-custom.conf + # Sigh...Fedora LXC containers and maybe others set max keys at 2000. We need more. For now more systems are needed to test on. + # https://unix.stackexchange.com/questions/600968/disk-quota-exceeded-when-trying-to-deploy-docker-container-inside-lxc + #echo 5000 | tee /proc/sys/kernel/keys/maxkeys + #echo "kernel.keys.maxkeys=5000" > /etc/sysctl.d/99-custom.conf -#return 1 -fi + #return 1 + fi } @@ -249,86 +248,87 @@ fi install_bluecherry() { -echo -e "\n\nInstalling Bluecherry.......\n\n" - -distribution=$(detect_distribution) - -case $distribution in - "debian" | "ubuntu") - install_debian_packages - ;; - "centos" | "rhel" | "fedora" | "rocky" | "Rocky") - install_redhat_packages - ;; - "sles" | "opensuse" | "suse") - install_suse_packages - ;; - "arch") - install_arch_packages - ;; - "fedora") - install_fedora_packages - ;; - # Add cases for other distributions and call the appropriate installation functions - *) - echo "Unsupported distribution, please contact Bluecherry for support in adding your distribution. Please provide output of /etc/os-release and /etc/lsb_release" - exit 1 - ;; -esac + echo -e "\n\nInstalling Bluecherry.......\n\n" + + distribution=$(detect_distribution) + + case $distribution in + "debian" | "ubuntu") + install_debian_packages + ;; + "centos" | "rhel" | "rocky" | "Rocky") + install_redhat_packages + ;; + "sles" | "opensuse" | "suse") + install_suse_packages + ;; + "arch") + install_arch_packages + ;; + "fedora") + install_fedora_packages + ;; + # Add cases for other distributions and call the appropriate installation functions + *) + echo "Unsupported distribution, please contact Bluecherry for support in adding your distribution. Please provide output of /etc/os-release and /etc/lsb_release" + exit 1 + ;; + esac } # Function to detect the Linux distribution detect_distribution() { - if [ -f "/etc/os-release" ]; then - . /etc/os-release - echo "$ID" - else - echo "Unsupported distribution" - exit 1 - fi + if [ -f "/etc/os-release" ]; then + # shellcheck disable=SC1091 # "Not following: /etc/os-release was not specified as input" + . /etc/os-release + echo "$ID" + else + echo "Unsupported distribution" + exit 1 + fi } # Function to install packages on Debian-based distributions install_debian_packages() { - apt-get update - apt-get install -y git + apt-get update + apt-get install -y git } # Function to install packages on Red Hat-based distributions install_redhat_packages() { - yum update - yum install -y git - install_docker -# Fix mainly for rocky...but we will try on all RHEL releases - sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/docker.service - sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/containerd.service - systemctl daemon-reload - systemctl stop docker - systemctl start docker + yum update + yum install -y git + install_docker + # Fix mainly for rocky...but we will try on all RHEL releases + sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/docker.service + sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/containerd.service + systemctl daemon-reload + systemctl stop docker + systemctl start docker } # Function to install packages on SUSE-based distributions install_suse_packages() { - zypper refresh - zypper install -y git - install_docker + zypper refresh + zypper install -y git + install_docker } # Function to install packages on Arch Linux install_arch_packages() { - pacman -Syu --noconfirm git - install_docker - sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/docker.service - sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/containerd.service - systemctl start docker - systemctl enable docker - pacman -Syu --noconfirm docker-compose + pacman -Syu --noconfirm git + install_docker + sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/docker.service + sed -i 's/^LimitNOFILE=infinity$/LimitNOFILE=1048576/' /usr/lib/systemd/system/containerd.service + systemctl start docker + systemctl enable docker + pacman -Syu --noconfirm docker-compose } # Function to install packages on Fedora install_fedora_packages() { - dnf update - dnf install -y git - install_docker + dnf update + dnf install -y git + install_docker } install_docker() { @@ -336,47 +336,43 @@ install_docker() { if command -v docker > /dev/null 2>&1; then echo -e "\n\nDocker is installed....skipping!\n\n" return 0 - else - - - curl -fsSL https://get.docker.com -o /tmp/install-docker.sh - sh /tmp/install-docker.sh - systemctl start docker - systemctl enable docker + curl -fsSL https://get.docker.com -o /tmp/install-docker.sh + sh /tmp/install-docker.sh + systemctl start docker + systemctl enable docker fi } uptimekuma() { -echo -e "Installing Uptime Kuma for monitoring of Bluecherry services\n\n" - - DOWNLOAD_URL='https://github.com/louislam/uptime-kuma/releases/download/1.21.3/dist.tar.gz' - - cd "$workingpath/bluecherry-docker" || exit 1 + echo -e "Installing Uptime Kuma for monitoring of Bluecherry services\n\n" - wget "${DOWNLOAD_URL}" - tar -zxf "$workingpath/dist.tar.gz" -C "$workingpath" + DOWNLOAD_URL='https://github.com/louislam/uptime-kuma/releases/download/1.21.3/dist.tar.gz' + cd "$workingpath/bluecherry-docker" || exit 1 + wget "${DOWNLOAD_URL}" + tar -zxf "$workingpath/dist.tar.gz" -C "$workingpath" -echo -e "Installing Uptime Kuma for monitoring of Bluecherry services\n\n" + echo -e "Installing Uptime Kuma for monitoring of Bluecherry services\n\n" -cd bluecherry-docker -wget https://github.com/louislam/uptime-kuma/releases/download/1.21.3/dist.tar.gz -tar -xvf dist.tar.gz + cd bluecherry-docker + wget https://github.com/louislam/uptime-kuma/releases/download/1.21.3/dist.tar.gz + tar -xvf dist.tar.gz } +# shellcheck disable=SC2162 # "read without -r will mangle backslashes." read -p "Do you want to install docker and setup Bluecherry server? [y/n]: " answer # Execute the appropriate function based on the answer case $answer in y) - install_docker - install_bluecherry -# configure_env - #clone_bluecherrydocker + install_docker + install_bluecherry + # configure_env + #clone_bluecherrydocker ;; n) ;; @@ -385,22 +381,24 @@ case $answer in ;; esac +# shellcheck disable=SC2162 # "read without -r will mangle backslashes." read -p "Do you want to download and configure the Bluecherry docker images? If this is the first run of the script then select 'y' [y/n]: " clonedocker case $clonedocker in y) -clone_bluecherrydocker -configure_env -docker_compose_init + clone_bluecherrydocker + configure_env + docker_compose_init ;; n) -# exit + # exit ;; *) echo "Invalid answer" esac +# shellcheck disable=SC2162 # "read without -r will mangle backslashes." read -p "Do you want to configure SMTP settings? [y/n]: " smtp case $smtp in @@ -408,7 +406,7 @@ case $smtp in configure_smtp ;; n) -# exit + # exit ;; *) echo "Invalid answer" @@ -417,14 +415,15 @@ esac echo -e "\nNote: NFS is typically recommended for external storage. Read the Bluecherry docs for information on adding CIFS (smb) shares\n\n" +# shellcheck disable=SC2162 # "read without -r will mangle backslashes." read -p "Do you want to add a NFS mount? [y/n]: " add_nfs case $add_nfs in y) configure_nfs -;; + ;; n) -# exit + # exit ;; *) echo "Invalid answer" @@ -432,32 +431,6 @@ case $add_nfs in esac -configure_nfs() { - -echo "installing nfs" - -read -p "Please provide the IP address of the NFS server: " nfsserver -read -p "Please provide the NFS server export path: " nfsexport - -echo " - -version: '3.8' -services: - - bluecherry: - volumes: -# - ./recordings:/var/lib/bluecherry/recordings - - videos:/media/bluecherry/nfs - -volumes: - videos: - driver_opts: - type: "nfs" - o: "addr=$nfsserver,nolock,soft" - device: ":$nfsexport" -" > $workingpath/bluecherry-docker/docker-compose.override.yml - -} # Let the user know how to access to Bluecherry web UI IP=$(ip route get 8.8.8.8 | sed -n '/src/{s/.*src *\([^ ]*\).*/\1/p;q}') diff --git a/tests/install.expect b/tests/install.expect new file mode 100755 index 00000000..df267061 --- /dev/null +++ b/tests/install.expect @@ -0,0 +1,27 @@ +#!/usr/bin/expect -f +#exp_internal 1 +set timeout 60 +spawn bluecherry-docker/scripts/install.sh +expect -ex {Do you want to install docker and setup Bluecherry server? [y/n]: } +send -- "y\r" + +expect -ex {Do you want to download and configure the Bluecherry docker images? If this is the first run of the script then select 'y' [y/n]: } +send -- "y\r" +expect -ex {Time Zone (i.e. - America/Chicago): } +send -- "Etc/UTC\r" +expect -ex {Please provide a mysql admin password:} +send -- "mysql-admin-password\r" +expect -ex {Please provide a mysql bluecherry password:} +send -- "mysql-bluecherry-password\r" + +expect -ex {Sleeping 45 seconds to make sure the database is initialized correctly...} +set timeout 60 +expect -ex {Sleeping another 15 seconds to run the database creation scripts...} + +expect -ex {Do you want to configure SMTP settings? [y/n]: } +send -- "n\r" + +expect -ex {Do you want to add a NFS mount? [y/n]: } +send -- "n\r" + +expect eof