diff --git a/INSTALL.md b/INSTALL.md index 22f4239..cd75f97 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -8,6 +8,18 @@ For a one-liner installation, you can use the following command: curl -sL https://raw.githubusercontent.com/UncleSamulus/BirdNET-stream/main/install.sh | bash ``` +For debug purposes, you can use the following command, it will log the installation steps to the console: + +```bash +DEBUG=1 ./install.sh +``` + +If you need to use a specific branch (e.g. dev), you can use the following command: + +```bash +BRANCH=dev ./install.sh +``` + ## Requirements - git diff --git a/daemon/systemd/templates/birdnet_plotter.service b/daemon/systemd/templates/birdnet_plotter.service index d2a3c68..ecc5e8d 100644 --- a/daemon/systemd/templates/birdnet_plotter.service +++ b/daemon/systemd/templates/birdnet_plotter.service @@ -5,7 +5,7 @@ Description=BirdNET-stream plotter User= Group= WorkingDirectory= -ExecStart=./.venv/birdnet-stream/bin/python3 ./daemon/plotter/chart.py +ExecStart=/bin/python3 ./daemon/plotter/chart.py Type=simple [Install] diff --git a/install.sh b/install.sh index a4a0669..9f720aa 100755 --- a/install.sh +++ b/install.sh @@ -5,8 +5,9 @@ set -e DEBUG=${DEBUG:-0} -REQUIREMENTS="git ffmpeg python3 python3-pip python3-dev" +REQUIREMENTS="git wget ffmpeg python3 python3-pip python3-dev python3-venv gzip" REPOSITORY=${REPOSITORY:-https://github.com/UncleSamulus/BirdNET-stream.git} +BRANCH=${BRANCH:-main} WORKDIR="$(pwd)/BirdNET-stream" PYTHON_VENV="./.venv/birdnet-stream" @@ -14,6 +15,12 @@ debug() { [[ $DEBUG -eq 1 ]] && echo "$@" } +add_birdnet_user() { + sudo useradd -m -s /bin/bash -G sudo birdnet + sudo usermod -aG birdnet $USER + sudo usermod -aG birdnet www-data +} + install_requirements() { requirements=$1 # Install requirements @@ -25,16 +32,15 @@ install_requirements() { done if [[ -n "$missing_requirements" ]]; then debug "Installing missing requirements: $missing_requirements" - sudo apt-get install -y "$missing_requirements" + sudo apt-get install -y $missing_requirements fi } # Install BirdNET-stream install_birdnetstream() { # Check if repo is not already installed - if [[ -d "$DIR" ]]; then + if [[ -d "$WORKDIR" ]]; then debug "BirdNET-stream is already installed, use update script (not implemented yet)" - exit 1 else debug "Installing BirdNET-stream" debug "Creating BirdNET-stream directory" @@ -42,7 +48,7 @@ install_birdnetstream() { # Clone BirdNET-stream cd "$WORKDIR" debug "Cloning BirdNET-stream from $REPOSITORY" - git clone --recurse-submodules "$REPOSITORY" . + git clone -b "$BRANCH"--recurse-submodules "$REPOSITORY" . debug "Creating python3 virtual environment $PYTHON_VENV" python3 -m venv $PYTHON_VENV debug "Activating $PYTHON_VENV" @@ -58,43 +64,53 @@ install_birdnetstream() { # Install systemd services install_birdnetstream_services() { GROUP=birdnet + DIR="$WORKDIR" + cd "$WORKDIR" debug "Setting up BirdNET stream systemd services" services="birdnet_recording.service birdnet_analyzis.service birdnet_miner.timer birdnet_miner.service birdnet_plotter.service birdnet_plotter.timer" - read -r -a services_array <<< "$services" - for service in "${services_array[@]}"; do + read -r -a services_array <<<"$services" + for service in ${services_array[@]}; do sudo cp "daemon/systemd/templates/$service" "/etc/systemd/system/" variables="DIR USER GROUP" for variable in $variables; do sudo sed -i "s|<$variable>|${!variable}|g" "/etc/systemd/system/$service" done done + sudo sed -i "s||$WORKDIR/$PYTHON_VENV|g" "/etc/systemd/system/birdnet_plotter.service" sudo systemctl daemon-reload - sudo systemctl enable --now birdnet_recording.service birdnet_analyzis.service birdnet_miner.timer birdnet_plotter.timer + 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 } install_php8() { # Remove previously installed php version - sudo apt-get remove --purge php* + sudo apt-get remove --purge php* -y # 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 - update - sudo apt-get install php8.1 + sudo apt-get update && sudo apt-get upgrade -y + sudo apt-get install -y php8.1 # Install and enable php-fpm - sudo apt-get install php8.1-fpm - sudo systemctl enable php8.1-fpm + sudo apt-get install -y php8.1-fpm + sudo systemctl enable --now php8.1-fpm # Install php packages - sudo apt-get install php8.1-{sqlite3,curl,intl} + sudo apt-get install -y php8.1-{sqlite3,curl,intl,xml,zip} } install_composer() { - cd /tmp - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"\nphp -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"\nphp composer-setup.php\nphp -r "unlink('composer-setup.php');" - sudo mv ./composer.phar /usr/local/bin/composer - cd - + 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 } install_nodejs() { @@ -111,7 +127,6 @@ install_nodejs() { install_web_interface() { debug "Setting up web interface" - install_requirements "nginx" # Install php 8.1 install_php8 # Install composer @@ -121,13 +136,6 @@ install_web_interface() { # Install Symfony web app cd "$WORKDIR" cd www - debug "Creating nginx configuration" - sudo cp nginx.conf /etc/nginx/sites-available/birdnet-stream.conf - sudo mkdir /var/log/nginx/birdnet/ - sudo ln -s /etc/nginx/sites-available/birdnet-stream.conf /etc/nginx/sites-available/birdnet-stream.conf - debug "Info: Please edit /etc/nginx/sites-available/birdnet-stream.conf to set the correct server name and paths" - sudo systemctl enable --now nginx - sudo systemctl restart nginx debug "Retrieving composer dependencies" composer install debug "PHP dependencies installed" @@ -141,6 +149,36 @@ install_web_interface() { debug "Please restart nginx after double check of /etc/nginx/sites-available/birdnet-stream.conf" } +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" + sudo sed -i "s||$CHUNK_FOLDER/out|g" /etc/nginx/sites-available/birdnet-stream.conf + sudo sed -i "s||$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 + openssl req -x509 -newkey rsa:4096 -keyout privkey.pem -out fullchain.pem -sha256 -days 365 -nodes --subj '/CN=birdnet.lan' + sudo sed -i "s||$CERTS_LOCATION/birdnet/fullchain.pem|g" /etc/nginx/sites-available/birdnet-stream.conf + sudo sed -i "s||$CERTS_LOCATION/birdnet/privkey.pem|g" /etc/nginx/sites-available/birdnet-stream.conf + sudo systemctl enable --now nginx + sudo systemctl restart nginx + cd - +} + change_value() { local variable_name variable_name="$1" @@ -165,13 +203,20 @@ install_config() { change_value "RECORDS_DIR" "$CHUNKS_FOLDER" ".env.local" } +update_permissions() { + debug "Updating permissions (may not work properly)" + sudo chown -R "$USER":"birdnet" "$WORKDIR" + sudo chown -R "$USER":"birdnet" "$CHUNK_FOLDER" + sudo chmod -R 755 "$CHUNK_FOLDER" +} + main() { install_requirements "$REQUIREMENTS" - install_birdnetstream - install_birdnetstream_services + # install_birdnetstream + # install_birdnetstream_services install_web_interface install_config - update_permissions "$WORKDIR" + update_permissions debug "Installation done" } diff --git a/uninstal.sh b/uninstal.sh new file mode 100644 index 0000000..36e4627 --- /dev/null +++ b/uninstal.sh @@ -0,0 +1,41 @@ +#! /usr/bin/env bash +# Standard uninstallation script for BirdNET-stream installed on Debian Based Linux distros +set -e +# set -x +DEBUG=${DEBUG:-0} +debug() { + [[ $DEBUG -eq 1 ]] && echo "$@" +} + +if [[ -f ./config/birdnet.conf ]]; then + source ./config/birdnet.conf +fi + +WORKDIR=${WORKDIR:-$(pwd)/BirdNET-stream} + +# Remove systemd services +uninstall_birdnet_services() { + debug "Removing systemd services" + services=(birdnet_recording.service + birdnet_streaming.service + birdnet_miner.service + birdnet_miner.timer + birdnet_plotter.service + birdnet_plotter.timer) + for service in "$services"; do + debug "Stopping $service" + sudo systemctl stop "$service" + sudo systemctl disable "$service" + sudo rm -f "/etc/systemd/system/$service" + done + debug "Done removing systemd services" +} + +uninstall_webapp() { + debug "Removing webapp" + debug "Removing nginx server configuration" + sudo unlink /etc/nginx/sites-enabled/birdnet-stream.conf + sudo systemctl restart nginx + debug "Removing webapp directory" + sudo rm -rf $WORKDIR +} \ No newline at end of file diff --git a/www/.env b/www/.env index 5983721..5bcd056 100644 --- a/www/.env +++ b/www/.env @@ -25,11 +25,14 @@ APP_SECRET=8bd3643031a08d0cd34e6fd3f680fb22 # # DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db" # DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4" -DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=14&charset=utf8" +# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=14&charset=utf8" +DATABASE_DEFAULT_URL=sqlite:///%kernel.project_dir%/./var/db-default.sqlite +DATABASE_OBSERVATIONS_URL=sqlite:///%kernel.project_dir%/../var/db.sqlite ###< doctrine/doctrine-bundle ### -### records folder -RECORDS_DIR=%kernel.project_dir%/../var/chunks # adapt to your needs +### records folder and disk +RECORDS_DISK=/dev/sda1 +RECORDS_DIR=%kernel.project_dir%/../var/chunks ### ###> symfony/mailer ### diff --git a/www/nginx.conf b/www/nginx.conf deleted file mode 100644 index 263024d..0000000 --- a/www/nginx.conf +++ /dev/null @@ -1,34 +0,0 @@ -server { - listen 80; - server_name birdnet.example.com; - root /var/www/html; - - location / { - return 302 https://$server_name$request_uri; - } -} - -server { - listen 443 ssl; - server_name birdnet.example.com; - root /var/www/html; - ssl on; - ssl_certificate /etc/nginx/ssl/birdnet.crt; - ssl_certificate_key /etc/nginx/ssl/birdnet.key; - - index index.html index.htm index.php; - - location / { - try_files $uri $uri/ /index.php$is_args$args; - } - - location ~ \.php$ { - fastcgi_split_path_info ^(.+\.php)(/.+)$; - fastcgi_pass unix:/run/php-fpm/www.sock; - fastcgi_index index.php; - include fastcgi.conf; - } - - access_log /var/log/nginx/birdnet/birdnet-access.log; - error_log /var/log/nginx/birdnet/birdnet-error.log error; -} \ No newline at end of file diff --git a/www/nginx.conf.template b/www/nginx.conf.template new file mode 100644 index 0000000..aae1155 --- /dev/null +++ b/www/nginx.conf.template @@ -0,0 +1,56 @@ +server { + listen 80; + server_name birdnet.lab.home; + + location / { + return 302 https://$host$request_uri; + } + + location /.well-known/acme-challenge { + alias /var/www/html/.well-known/acme-challenge; + allow all; + } +} + +server { + listen 443 ssl; + server_name birdnet.lab.home; + + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + + root ; + + ssl_certificate ; + ssl_certificate_key ; + + index index.php; + + location / { + try_files $uri $uri/ /index.php$is_args$args; + } + + location ^~ /media/records { + autoindex on; + alias ; + } + + location ^~ /media/charts { + autoindex on; + alias ; + } + + location ~ \.php$ { + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass unix:/run/php/www.sock; + fastcgi_index index.php; + include fastcgi.conf; + } + + location /stream { + proxy_pass http://localhost:8000/stream; + } + + access_log /var/log/nginx/birdnet/birdnet-access.log; + error_log /var/log/nginx/birdnet/birdnet-error.log error; +}