2022-08-13 07:48:06 +02:00
|
|
|
#! /usr/bin/env bash
|
2022-08-20 05:22:07 +02:00
|
|
|
# Standard Installation Script for BirdNET-stream for Debian Based Linux distros
|
2022-08-13 11:33:40 +02:00
|
|
|
# set -x
|
2022-08-13 07:48:06 +02:00
|
|
|
set -e
|
|
|
|
|
|
|
|
DEBUG=${DEBUG:-0}
|
|
|
|
|
2022-08-22 05:46:59 +02:00
|
|
|
REQUIREMENTS="git wget ffmpeg python3 python3-pip python3-dev python3-venv gzip sqlite3"
|
2022-08-20 05:22:07 +02:00
|
|
|
REPOSITORY=${REPOSITORY:-https://github.com/UncleSamulus/BirdNET-stream.git}
|
2022-08-21 07:52:41 +02:00
|
|
|
BRANCH=${BRANCH:-main}
|
2022-08-21 06:13:15 +02:00
|
|
|
WORKDIR="$(pwd)/BirdNET-stream"
|
|
|
|
PYTHON_VENV="./.venv/birdnet-stream"
|
2022-08-13 07:48:06 +02:00
|
|
|
|
|
|
|
debug() {
|
2022-08-21 06:13:15 +02:00
|
|
|
[[ $DEBUG -eq 1 ]] && echo "$@"
|
2022-08-13 07:48:06 +02:00
|
|
|
}
|
|
|
|
|
2022-08-21 07:52:41 +02:00
|
|
|
add_birdnet_user() {
|
|
|
|
sudo useradd -m -s /bin/bash -G sudo birdnet
|
|
|
|
sudo usermod -aG birdnet $USER
|
|
|
|
sudo usermod -aG birdnet www-data
|
|
|
|
}
|
|
|
|
|
2022-08-13 07:48:06 +02:00
|
|
|
install_requirements() {
|
|
|
|
requirements=$1
|
|
|
|
# Install requirements
|
|
|
|
missing_requirements=""
|
|
|
|
for requirement in $requirements; do
|
2022-08-21 06:13:15 +02:00
|
|
|
if ! dpkg -s "$requirement" >/dev/null 2>&1; then
|
2022-08-13 07:48:06 +02:00
|
|
|
missing_requirements="$missing_requirements $requirement"
|
|
|
|
fi
|
|
|
|
done
|
2022-08-21 06:13:15 +02:00
|
|
|
if [[ -n "$missing_requirements" ]]; then
|
2022-08-13 07:48:06 +02:00
|
|
|
debug "Installing missing requirements: $missing_requirements"
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo apt-get install -y $missing_requirements
|
2022-08-13 07:48:06 +02:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Install BirdNET-stream
|
|
|
|
install_birdnetstream() {
|
2022-08-13 11:33:40 +02:00
|
|
|
# Check if repo is not already installed
|
2022-08-21 07:52:41 +02:00
|
|
|
if [[ -d "$WORKDIR" ]]; then
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "BirdNET-stream is already installed, use update script (not implemented yet)"
|
2022-08-13 16:00:08 +02:00
|
|
|
else
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "Installing BirdNET-stream"
|
|
|
|
debug "Creating BirdNET-stream directory"
|
|
|
|
mkdir -p "$WORKDIR"
|
2022-08-13 16:00:08 +02:00
|
|
|
# Clone BirdNET-stream
|
2022-08-21 06:13:15 +02:00
|
|
|
cd "$WORKDIR"
|
2022-08-13 16:00:08 +02:00
|
|
|
debug "Cloning BirdNET-stream from $REPOSITORY"
|
2022-08-22 05:46:59 +02:00
|
|
|
git clone -b "$BRANCH" --recurse-submodules "$REPOSITORY" .
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "Creating python3 virtual environment $PYTHON_VENV"
|
|
|
|
python3 -m venv $PYTHON_VENV
|
|
|
|
debug "Activating $PYTHON_VENV"
|
|
|
|
source "$PYTHON_VENV/bin/activate"
|
|
|
|
debug "Installing python packages"
|
|
|
|
pip3 install -U pip
|
|
|
|
pip3 install -r requirements.txt
|
|
|
|
debug "Creating ./var directory"
|
|
|
|
mkdir -p ./var/{charts,chunks/{in,out}}
|
2022-08-13 11:33:40 +02:00
|
|
|
fi
|
2022-08-13 07:48:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Install systemd services
|
|
|
|
install_birdnetstream_services() {
|
2022-08-21 06:13:15 +02:00
|
|
|
GROUP=birdnet
|
2022-08-21 07:52:41 +02:00
|
|
|
DIR="$WORKDIR"
|
|
|
|
cd "$WORKDIR"
|
2022-08-13 07:48:06 +02:00
|
|
|
debug "Setting up BirdNET stream systemd services"
|
2022-08-16 05:21:53 +02:00
|
|
|
services="birdnet_recording.service birdnet_analyzis.service birdnet_miner.timer birdnet_miner.service birdnet_plotter.service birdnet_plotter.timer"
|
2022-08-21 07:52:41 +02:00
|
|
|
read -r -a services_array <<<"$services"
|
|
|
|
for service in ${services_array[@]}; do
|
2022-08-21 06:13:15 +02:00
|
|
|
sudo cp "daemon/systemd/templates/$service" "/etc/systemd/system/"
|
2022-08-13 11:33:40 +02:00
|
|
|
variables="DIR USER GROUP"
|
|
|
|
for variable in $variables; do
|
2022-08-21 06:13:15 +02:00
|
|
|
sudo sed -i "s|<$variable>|${!variable}|g" "/etc/systemd/system/$service"
|
2022-08-13 11:33:40 +02:00
|
|
|
done
|
|
|
|
done
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo sed -i "s|<VENV>|$WORKDIR/$PYTHON_VENV|g" "/etc/systemd/system/birdnet_plotter.service"
|
2022-08-13 07:48:06 +02:00
|
|
|
sudo systemctl daemon-reload
|
2022-08-21 07:52:41 +02:00
|
|
|
enabled_services="birdnet_recording.service birdnet_analyzis.service birdnet_miner.timer birdnet_plotter.timer"
|
|
|
|
read -r -a services_array <<<"$services"
|
|
|
|
for service in ${services_array[@]}; do
|
|
|
|
debug "Enabling $service"
|
|
|
|
sudo systemctl enable "$service"
|
|
|
|
sudo systemctl start "$service"
|
|
|
|
done
|
2022-08-14 10:33:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
install_php8() {
|
|
|
|
# Remove previously installed php version
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo apt-get remove --purge php* -y
|
2022-08-14 10:33:30 +02:00
|
|
|
# Install required packages for php
|
|
|
|
sudo apt-get install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
|
|
|
|
# Get php package from sury repo
|
|
|
|
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
|
|
|
|
sudo wget -qO - https://packages.sury.org/php/apt.gpg | sudo gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/debian-php-8.gpg --import
|
|
|
|
sudo chmod 644 /etc/apt/trusted.gpg.d/debian-php-8.gpg
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo apt-get update && sudo apt-get upgrade -y
|
|
|
|
sudo apt-get install -y php8.1
|
2022-08-14 10:33:30 +02:00
|
|
|
# Install and enable php-fpm
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo apt-get install -y php8.1-fpm
|
|
|
|
sudo systemctl enable --now php8.1-fpm
|
2022-08-14 10:33:30 +02:00
|
|
|
# Install php packages
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo apt-get install -y php8.1-{sqlite3,curl,intl,xml,zip}
|
2022-08-14 10:33:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
install_composer() {
|
2022-08-21 07:52:41 +02:00
|
|
|
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
|
|
|
php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
|
|
|
|
php composer-setup.php
|
|
|
|
php -r "unlink('composer-setup.php');"
|
|
|
|
sudo mv composer.phar /usr/local/bin/composer
|
2022-08-14 10:33:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
install_nodejs() {
|
|
|
|
# Install nodejs
|
|
|
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
|
2022-08-21 06:13:15 +02:00
|
|
|
export NVM_DIR="$([[ -z "${XDG_CONFIG_HOME-}" ]] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
|
|
|
|
[[ -s "$NVM_DIR/nvm.sh" ]] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
2022-08-14 10:33:30 +02:00
|
|
|
nvm install 16
|
|
|
|
nvm use 16
|
|
|
|
install_requirements "npm"
|
|
|
|
# Install yarn
|
|
|
|
sudo npm install -g yarn
|
2022-08-13 11:33:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
install_web_interface() {
|
|
|
|
debug "Setting up web interface"
|
2022-08-14 10:33:30 +02:00
|
|
|
# Install php 8.1
|
|
|
|
install_php8
|
|
|
|
# Install composer
|
|
|
|
install_composer
|
|
|
|
# Install nodejs 16
|
|
|
|
install_nodejs
|
|
|
|
# Install Symfony web app
|
2022-08-21 06:13:15 +02:00
|
|
|
cd "$WORKDIR"
|
2022-08-13 11:33:40 +02:00
|
|
|
cd www
|
|
|
|
debug "Retrieving composer dependencies"
|
|
|
|
composer install
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "PHP dependencies installed"
|
2022-08-13 11:33:40 +02:00
|
|
|
debug "Installing nodejs dependencies"
|
2022-08-14 10:33:30 +02:00
|
|
|
yarn install
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "npm dependencies installed"
|
2022-08-13 11:33:40 +02:00
|
|
|
debug "Building assets"
|
2022-08-14 10:33:30 +02:00
|
|
|
yarn build
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "Webpack assets built"
|
2022-08-13 11:33:40 +02:00
|
|
|
debug "Web interface is available"
|
2022-08-14 10:33:30 +02:00
|
|
|
debug "Please restart nginx after double check of /etc/nginx/sites-available/birdnet-stream.conf"
|
2022-08-13 07:48:06 +02:00
|
|
|
}
|
|
|
|
|
2022-08-21 07:52:41 +02:00
|
|
|
setup_http_server() {
|
|
|
|
debug "Setting up HTTP server"
|
|
|
|
install_requirements "nginx"
|
|
|
|
debug "Setup nginx server"
|
|
|
|
cd "$WORKDIR"
|
|
|
|
cd www
|
|
|
|
debug "Creating nginx configuration"
|
|
|
|
sudo cp nginx.conf.template /etc/nginx/sites-available/birdnet-stream.conf
|
|
|
|
sudo mkdir -p /var/log/nginx/birdnet/
|
|
|
|
if [[ -f "/etc/nginx/sites-enabled/birdnet-stream.conf" ]]; then
|
|
|
|
sudo unlink /etc/nginx/sites-enabled/birdnet-stream.conf
|
|
|
|
fi
|
|
|
|
debug "Enable birdnet.lan domain"
|
|
|
|
sudo ln -s /etc/nginx/sites-available/birdnet-stream.conf /etc/nginx/sites-enabled/birdnet-stream.conf
|
|
|
|
debug "Info: Please edit /etc/nginx/sites-available/birdnet-stream.conf to set the correct server name and paths"
|
|
|
|
debug "Setup nginx variables the best way possible"
|
2022-08-21 08:17:16 +02:00
|
|
|
sudo sed -i "s|<SYMFONY_PUBLIC>|$WORKDIR/www/public/|g" /etc/nginx/sites-available/birdnet-stream.conf
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo sed -i "s|<RECORDS_FOLDER>|$CHUNK_FOLDER/out|g" /etc/nginx/sites-available/birdnet-stream.conf
|
|
|
|
sudo sed -i "s|<CHARTS_FOLDER>|$WORKDIR/var/charts|g" /etc/nginx/sites-available/birdnet-stream.conf
|
|
|
|
debug "Generate self signed certificate"
|
|
|
|
CERTS_LOCATION="/etc/nginx/certs/birdnet"
|
|
|
|
sudo mkdir -p "$CERTS_LOCATION"
|
|
|
|
cd $CERTS_LOCATION
|
2022-08-21 08:17:16 +02:00
|
|
|
sudo openssl req -x509 -newkey rsa:4096 -keyout privkey.pem -out fullchain.pem -sha256 -days 365 -nodes --subj '/CN=birdnet.lan'
|
|
|
|
sudo sed -i "s|<CERTIFICATE>|$CERTS_LOCATION/fullchain.pem|g" /etc/nginx/sites-available/birdnet-stream.conf
|
|
|
|
sudo sed -i "s|<PRIVATE_KEY>|$CERTS_LOCATION/privkey.pem|g" /etc/nginx/sites-available/birdnet-stream.conf
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo systemctl enable --now nginx
|
|
|
|
sudo systemctl restart nginx
|
|
|
|
cd -
|
|
|
|
}
|
|
|
|
|
2022-08-21 06:13:15 +02:00
|
|
|
change_value() {
|
|
|
|
local variable_name
|
|
|
|
variable_name="$1"
|
|
|
|
local variable_new_value
|
|
|
|
variable_new_value="$2"
|
|
|
|
local variable_filepath="$3"
|
|
|
|
sed -i "s|$variable_name=.*|$variable_name=\"$variable_new_value\"|g" "$variable_filepath"
|
|
|
|
}
|
|
|
|
|
|
|
|
install_config() {
|
|
|
|
debug "Updating config"
|
|
|
|
cd "$WORKDIR"
|
|
|
|
cp ./config/birdnet.conf.example ./config/birdnet.conf
|
|
|
|
config_filepath="$WORKDIR/config/birdnet.conf"
|
|
|
|
change_value "DIR" "$WORKDIR" "$config_filepath"
|
|
|
|
change_value "PYTHON_VENV" "$PYTHON_VENV" "$config_filepath"
|
|
|
|
change_value "AUDIO_RECORDING" "true" "$config_filepath"
|
|
|
|
source "$config_filepath"
|
|
|
|
cd www
|
|
|
|
debug "Setup webapp .env"
|
|
|
|
cp .env.local.example .env.local
|
|
|
|
change_value "RECORDS_DIR" "$CHUNKS_FOLDER" ".env.local"
|
|
|
|
}
|
|
|
|
|
2022-08-21 07:52:41 +02:00
|
|
|
update_permissions() {
|
|
|
|
debug "Updating permissions (may not work properly)"
|
2022-08-21 08:24:04 +02:00
|
|
|
cd $WORKDIR
|
2022-08-21 08:17:16 +02:00
|
|
|
sudo chown -R $USER:birdnet "$WORKDIR"
|
|
|
|
sudo chown -R $USER:birdnet "$CHUNK_FOLDER"
|
2022-08-21 07:52:41 +02:00
|
|
|
sudo chmod -R 755 "$CHUNK_FOLDER"
|
|
|
|
}
|
|
|
|
|
2022-08-13 07:48:06 +02:00
|
|
|
main() {
|
2022-08-21 06:13:15 +02:00
|
|
|
install_requirements "$REQUIREMENTS"
|
2022-08-21 08:17:16 +02:00
|
|
|
install_birdnetstream
|
|
|
|
install_birdnetstream_services
|
2022-08-14 10:33:30 +02:00
|
|
|
install_web_interface
|
2022-08-21 08:17:16 +02:00
|
|
|
setup_http_server
|
2022-08-21 06:13:15 +02:00
|
|
|
install_config
|
2022-08-22 05:46:59 +02:00
|
|
|
debug "Run loginctl enable-linger for $USER"
|
|
|
|
loginctl enable-linger
|
2022-08-21 07:52:41 +02:00
|
|
|
update_permissions
|
2022-08-21 06:13:15 +02:00
|
|
|
debug "Installation done"
|
2022-08-13 07:48:06 +02:00
|
|
|
}
|
|
|
|
|
2022-08-13 11:33:40 +02:00
|
|
|
main
|