From 456bb08a2e9a9c61733e736e5f9d7892bd60902a Mon Sep 17 00:00:00 2001 From: Sam <54530346+asylumexp@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:50:46 +1000 Subject: [PATCH] Merge upstream #3 attempt - 2fauth thru homebox done --- .gitignore | 1 + install/2fauth-install.sh | 125 +++++++++++++ install/5etools-install.sh | 85 +++++++++ install/alpine-nextcloud-install.sh | 49 ++--- install/alpine-vaultwarden-install.sh | 8 +- install/apache-guacamole-install.sh | 156 ++++++++++++++++ install/archivebox-install.sh | 17 +- install/authentik-install.sh | 197 ++++++++++++++++++++ install/blocky-install.sh | 247 +++----------------------- install/bookstack-install.sh | 122 +++++++++++++ install/changedetection-install.sh | 1 - install/checkmk-install.sh | 50 ++++++ install/cloudflared-install.sh | 35 ++++ install/docker-install.sh | 10 +- install/firefly-install.sh | 103 +++++++++++ install/frigate-install.sh | 4 +- install/glance-install.sh | 83 +++++++++ install/glpi-install.sh | 153 ++++++++++++++++ install/grist-install.sh | 85 +++++++++ install/hoarder-install.sh | 183 +++++++++++++++++++ install/homarr-install.sh | 33 ++-- install/homeassistant-core-install.sh | 49 ++++- install/homebox-install.sh | 11 +- 23 files changed, 1525 insertions(+), 282 deletions(-) create mode 100644 .gitignore create mode 100644 install/2fauth-install.sh create mode 100644 install/5etools-install.sh create mode 100644 install/apache-guacamole-install.sh create mode 100644 install/authentik-install.sh create mode 100644 install/bookstack-install.sh create mode 100644 install/checkmk-install.sh create mode 100644 install/firefly-install.sh create mode 100644 install/glance-install.sh create mode 100644 install/glpi-install.sh create mode 100644 install/grist-install.sh create mode 100644 install/hoarder-install.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..780fc3831 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +script*.py diff --git a/install/2fauth-install.sh b/install/2fauth-install.sh new file mode 100644 index 000000000..2a16c0805 --- /dev/null +++ b/install/2fauth-install.sh @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: jkrgr0 +# License: MIT +# Source: https://docs.2fauth.app/ + +# Import Functions und Setup +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +# Installing Dependencies with the 3 core dependencies (curl;sudo;mc) +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + nginx \ + composer \ + php8.2-{bcmath,common,ctype,curl,fileinfo,fpm,gd,mbstring,mysql,xml,cli} \ + mariadb-server \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +# Template: MySQL Database +msg_info "Setting up Database" +DB_NAME=2fauth_db +DB_USER=2fauth +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +$STD mysql -u root -e "CREATE DATABASE $DB_NAME;" +$STD mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" +$STD mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "2FAuth Credentials" + echo "Database User: $DB_USER" + echo "Database Password: $DB_PASS" + echo "Database Name: $DB_NAME" +} >> ~/2FAuth.creds +msg_ok "Set up Database" + +# Setup App +msg_info "Setup 2FAuth" +RELEASE=$(curl -s https://api.github.com/repos/Bubka/2FAuth/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget -q "https://github.com/Bubka/2FAuth/archive/refs/tags/${RELEASE}.zip" +unzip -q "${RELEASE}.zip" +mv "2FAuth-${RELEASE//v}/" /opt/2fauth + +cd "/opt/2fauth" || return +cp .env.example .env +IPADDRESS=$(hostname -I | awk '{print $1}') + +sed -i -e "s|^APP_URL=.*|APP_URL=http://$IPADDRESS|" \ + -e "s|^DB_CONNECTION=$|DB_CONNECTION=mysql|" \ + -e "s|^DB_DATABASE=$|DB_DATABASE=$DB_NAME|" \ + -e "s|^DB_HOST=$|DB_HOST=127.0.0.1|" \ + -e "s|^DB_PORT=$|DB_PORT=3306|" \ + -e "s|^DB_USERNAME=$|DB_USERNAME=$DB_USER|" \ + -e "s|^DB_PASSWORD=$|DB_PASSWORD=$DB_PASS|" .env + +export COMPOSER_ALLOW_SUPERUSER=1 +$STD composer update --no-plugins --no-scripts +$STD composer install --no-dev --prefer-source --no-plugins --no-scripts + +$STD php artisan key:generate --force + +$STD php artisan migrate:refresh +$STD php artisan passport:install -q -n +$STD php artisan storage:link +$STD php artisan config:cache + +chown -R www-data: /opt/2fauth +chmod -R 755 /opt/2fauth + +echo "${RELEASE}" >"/opt/2fauth_version.txt" +msg_ok "Setup 2fauth" + +# Configure Service (NGINX) +msg_info "Configure Service" +cat </etc/nginx/conf.d/2fauth.conf +server { + listen 80; + root /opt/2fauth/public; + server_name $IPADDRESS; + index index.php; + charset utf-8; + + location / { + try_files \$uri \$uri/ /index.php?\$query_string; + } + + location = /favicon.ico { access_log off; log_not_found off; } + location = /robots.txt { access_log off; log_not_found off; } + + error_page 404 /index.php; + + location ~ \.php\$ { + fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; + fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name; + include fastcgi_params; + } + + location ~ /\.(?!well-known).* { + deny all; + } +} +EOF + +systemctl reload nginx +msg_ok "Configured Service" + +motd_ssh +customize + +# Cleanup +msg_info "Cleaning up" +rm -f "/opt/v${RELEASE}.zip" +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/5etools-install.sh b/install/5etools-install.sh new file mode 100644 index 000000000..88cba94c9 --- /dev/null +++ b/install/5etools-install.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: TheRealVira +# License: MIT +# Source: https://5e.tools/ + +# Import Functions und Setup +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + mc \ + sudo \ + git \ + gpg \ + ca-certificates \ + apache2 \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +# Setup App +msg_info "Set up 5etools Base" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/5etools-mirror-3/5etools-src/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +wget -q "https://github.com/5etools-mirror-3/5etools-src/archive/refs/tags/${RELEASE}.zip" +unzip -q "${RELEASE}.zip" +mv "5etools-src-${RELEASE:1}" /opt/5etools +cd /opt/5etools +$STD npm install +$STD npm run build +echo "${RELEASE}" >"/opt/5etools_version.txt" +msg_ok "Set up 5etools Base" + +msg_info "Set up 5etools Image" +cd /opt +IMG_RELEASE=$(curl -s https://api.github.com/repos/5etools-mirror-2/5etools-img/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') +curl -sSL "https://github.com/5etools-mirror-2/5etools-img/archive/refs/tags/${IMG_RELEASE}.zip" > "${IMG_RELEASE}.zip" +unzip -q "${IMG_RELEASE}.zip" +mv "5etools-img-${IMG_RELEASE:1}" /opt/5etools/img +echo "${IMG_RELEASE}" >"/opt/5etools_IMG_version.txt" +msg_ok "Set up 5etools Image" + +msg_info "Creating Service" +cat <> /etc/apache2/apache2.conf + + SetHandler server-status + Order deny,allow + Allow from all + +EOF +rm -rf /var/www/html +ln -s "/opt/5etools" /var/www/html +chown -R www-data: "/opt/5etools" +chmod -R 755 "/opt/5etools" +msg_ok "Created Service" + +msg_info "Cleaning up" +rm -rf /opt/${IMG_RELEASE}.zip +rm -rf /opt/${RELEASE}.zip +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" + +motd_ssh +customize diff --git a/install/alpine-nextcloud-install.sh b/install/alpine-nextcloud-install.sh index e5d2971dc..59fdcaf90 100644 --- a/install/alpine-nextcloud-install.sh +++ b/install/alpine-nextcloud-install.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck (tteckster) # License: MIT # https://github.com/tteck/Proxmox/raw/main/LICENSE @@ -25,18 +25,18 @@ $STD apk add openssh msg_ok "Installed Dependencies" msg_info "Installing PHP/Redis" -$STD apk add php82-opcache -$STD apk add php82-redis -$STD apk add php82-apcu -$STD apk add php82-fpm -$STD apk add php82-sysvsem -$STD apk add php82-ftp -$STD apk add php82-pecl-smbclient -$STD apk add php82-pecl-imagick -$STD apk add php82-pecl-vips -$STD apk add php82-exif -$STD apk add php82-sodium -$STD apk add php82-bz2 +$STD apk add php83-opcache +$STD apk add php83-redis +$STD apk add php83-apcu +$STD apk add php83-fpm +$STD apk add php83-sysvsem +$STD apk add php83-ftp +$STD apk add php83-pecl-smbclient +$STD apk add php83-pecl-imagick +$STD apk add php83-pecl-vips +$STD apk add php83-exif +$STD apk add php83-sodium +$STD apk add php83-bz2 $STD apk add redis msg_ok "Installed PHP/Redis" @@ -51,7 +51,7 @@ echo -e "Nextcloud Database Username: \e[32m$DB_USER\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Password: \e[32m$DB_PASS\e[0m" >>~/nextcloud.creds echo -e "Nextcloud Database Name: \e[32m$DB_NAME\e[0m" >>~/nextcloud.creds $STD apk add nextcloud-mysql mariadb mariadb-client -$STD mysql_install_db --user=mysql --datadir=/var/lib/mysql +$STD mariadb-install-db --user=mysql --datadir=/var/lib/mysql $STD service mariadb start $STD rc-update add mariadb mysql -uroot -p"$ADMIN_PASS" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '$ADMIN_PASS' WITH GRANT OPTION; DELETE FROM mysql.user WHERE User=''; DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); DROP DATABASE test; DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'; CREATE DATABASE $DB_NAME; GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS'; GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost.localdomain' IDENTIFIED BY '$DB_PASS'; FLUSH PRIVILEGES;" @@ -104,6 +104,8 @@ server { listen 80; return 301 https://$host$request_uri; server_name localhost; + client_max_body_size 16G; + fastcgi_read_timeout 120s; } server { listen 443 ssl http2; @@ -128,6 +130,8 @@ server { fastcgi_pass unix:/run/nextcloud/fastcgi.sock; # From the nextcloud-initscript package fastcgi_index index.php; include fastcgi.conf; + fastcgi_read_timeout 120s; + client_max_body_size 16G; } location ^~ /.well-known/carddav { return 301 /remote.php/dav/; } location ^~ /.well-known/caldav { return 301 /remote.php/dav/; } @@ -135,11 +139,13 @@ server { location ^~ /.well-known/nodeinfo { return 301 /index.php/.well-known/nodeinfo; } } EOF -sed -i -e 's|memory_limit = 128M|memory_limit = 512M|; $aapc.enable_cli=1' /etc/php82/php.ini -sed -i -E '/^php_admin_(flag|value)\[opcache/s/^/;/' /etc/php82/php-fpm.d/nextcloud.conf +sed -i -e 's|memory_limit = 128M|memory_limit = 512M|; $aapc.enable_cli=1' /etc/php83/php.ini +sed -i -e 's|upload_max_file_size = 2M|upload_max_file_size = 16G|' /etc/php83/php.ini +sed -i -E '/^php_admin_(flag|value)\[opcache/s/^/;/' /etc/php83/php-fpm.d/nextcloud.conf msg_ok "Installed Nextcloud" msg_info "Adding Additional Nextcloud Packages" +$STD apk add nextcloud-occ $STD apk add nextcloud-default-apps $STD apk add nextcloud-activity $STD apk add nextcloud-admin_audit @@ -164,9 +170,10 @@ msg_ok "Added Additional Nextcloud Packages" msg_info "Starting Services" $STD rc-service redis start $STD rc-update add redis default -$STD rc-service php-fpm82 start +$STD rc-service php-fpm83 start chown -R nextcloud:www-data /var/log/nextcloud/ -$STD rc-service php-fpm82 restart +chown -R nextcloud:www-data /usr/share/webapps/nextcloud/ +$STD rc-service php-fpm83 restart $STD rc-service nginx start $STD rc-service nextcloud start $STD rc-update add nginx default @@ -176,16 +183,16 @@ msg_ok "Started Services" msg_info "Start Nextcloud Setup-Wizard" echo -e "export VISUAL=nano\nexport EDITOR=nano" >>/etc/profile cd /usr/share/webapps/nextcloud -$STD su nextcloud -s /bin/sh -c "php82 occ maintenance:install \ +$STD su nextcloud -s /bin/sh -c "php83 occ maintenance:install \ --database='mysql' --database-name $DB_NAME \ --database-user '$DB_USER' --database-pass '$DB_PASS' \ --admin-user '$ADMIN_USER' --admin-pass '$ADMIN_PASS' \ --data-dir '/var/lib/nextcloud/data'" -$STD su nextcloud -s /bin/sh -c 'php82 occ background:cron' +$STD su nextcloud -s /bin/sh -c 'php83 occ background:cron' rm -rf /usr/share/webapps/nextcloud/apps/serverinfo IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) sed -i "/0 => \'localhost\',/a \ \1 => '$IP4'," /usr/share/webapps/nextcloud/config/config.php -su nextcloud -s /bin/sh -c 'php82 -f /usr/share/webapps/nextcloud/cron.php' +su nextcloud -s /bin/sh -c 'php83 -f /usr/share/webapps/nextcloud/cron.php' msg_ok "Finished Nextcloud Setup-Wizard" motd_ssh diff --git a/install/alpine-vaultwarden-install.sh b/install/alpine-vaultwarden-install.sh index 7bad5568e..c6d27f5d8 100644 --- a/install/alpine-vaultwarden-install.sh +++ b/install/alpine-vaultwarden-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck (tteckster) # License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" color @@ -26,7 +26,9 @@ msg_ok "Installed Dependencies" msg_info "Installing Alpine-Vaultwarden" $STD apk add vaultwarden -sed -i -e 's/# export ADMIN_TOKEN=.*/export ADMIN_TOKEN='\'''\''/' -e '/^# export ROCKET_ADDRESS=0\.0\.0\.0/s/^# //' -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden +sed -i -e 's|export WEB_VAULT_ENABLED=.*|export WEB_VAULT_ENABLED=true|' /etc/conf.d/vaultwarden +echo -e "export ADMIN_TOKEN=''" >>/etc/conf.d/vaultwarden +echo -e "export ROCKET_ADDRESS=0.0.0.0" >>/etc/conf.d/vaultwarden msg_ok "Installed Alpine-Vaultwarden" msg_info "Installing Web-Vault" diff --git a/install/apache-guacamole-install.sh b/install/apache-guacamole-install.sh new file mode 100644 index 000000000..057f31041 --- /dev/null +++ b/install/apache-guacamole-install.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash +#Copyright (c) 2021-2025 community-scripts ORG +# Author: Michel Roegl-Brunner (michelroegl-brunner) | MickLesk (CanbiZ) +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + build-essential \ + curl \ + jq \ + libcairo2-dev \ + libturbojpeg0 \ + libpng-dev \ + libtool-bin \ + libossp-uuid-dev \ + libvncserver-dev \ + freerdp2-dev \ + libssh2-1-dev \ + libtelnet-dev \ + libwebsockets-dev \ + libpulse-dev \ + libvorbis-dev \ + libwebp-dev \ + libssl-dev \ + libpango1.0-dev \ + libswscale-dev \ + libavcodec-dev \ + libavutil-dev \ + libavformat-dev \ + mariadb-server \ + default-jdk \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Setup Apache Tomcat" +RELEASE=$(wget -qO- https://dlcdn.apache.org/tomcat/tomcat-9/ | grep -oP '(?<=href=")v[^"/]+(?=/")' | sed 's/^v//') +mkdir -p /opt/apache-guacamole/tomcat9 +mkdir -p /opt/apache-guacamole/server +wget -qO- "https://dlcdn.apache.org/tomcat/tomcat-9/v${RELEASE}/bin/apache-tomcat-${RELEASE}.tar.gz" | tar -xz -C /opt/apache-guacamole/tomcat9 --strip-components=1 +useradd -r -d /opt/apache-guacamole/tomcat9 -s /bin/false tomcat +chown -R tomcat: /opt/apache-guacamole/tomcat9 +chmod -R g+r /opt/apache-guacamole/tomcat9/conf +chmod g+x /opt/apache-guacamole/tomcat9/conf +msg_ok "Setup Apache Tomcat" + +msg_info "Setup Apache Guacamole" +mkdir -p /etc/guacamole/{extensions,lib} +RELEASE_SERVER=$(curl -sL https://api.github.com/repos/apache/guacamole-server/tags | jq -r '.[0].name') +wget -qO- https://api.github.com/repos/apache/guacamole-server/tarball/refs/tags/${RELEASE_SERVER} | tar -xz --strip-components=1 -C /opt/apache-guacamole/server +cd /opt/apache-guacamole/server +$STD autoreconf -fi +$STD ./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots +$STD make +$STD make install +$STD ldconfig +RELEASE_CLIENT=$(curl -sL https://api.github.com/repos/apache/guacamole-client/tags | jq -r '.[0].name') +wget -q -O /opt/apache-guacamole/tomcat9/webapps/guacamole.war https://downloads.apache.org/guacamole/${RELEASE_CLIENT}/binary/guacamole-${RELEASE_CLIENT}.war +cd /root +wget -q --directory-prefix=/root/ https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.26.tar.gz +$STD tar -xf ~/mysql-connector-java-8.0.26.tar.gz +mv ~/mysql-connector-java-8.0.26/mysql-connector-java-8.0.26.jar /etc/guacamole/lib/ +wget -q --directory-prefix=/root/ https://downloads.apache.org/guacamole/1.5.5/binary/guacamole-auth-jdbc-1.5.5.tar.gz +$STD tar -xf ~/guacamole-auth-jdbc-1.5.5.tar.gz +mv ~/guacamole-auth-jdbc-1.5.5/mysql/guacamole-auth-jdbc-mysql-1.5.5.jar /etc/guacamole/extensions/ +msg_ok "Setup Apache Guacamole" + +msg_info "Setup Database" +DB_NAME=guacamole_db +DB_USER=guacamole_user +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +mysql -u root -e "CREATE DATABASE $DB_NAME;" +mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" +mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "Guacamole-Credentials" + echo "Database User: $DB_USER" + echo "Database Password: $DB_PASS" + echo "Database Name: $DB_NAME" +} >> ~/guacamole.creds +cd guacamole-auth-jdbc-1.5.5/mysql/schema +cat *.sql | mysql -u root ${DB_NAME} +{ + echo "mysql-hostname: 127.0.0.1" + echo "mysql-port: 3306" + echo "mysql-database: $DB_NAME" + echo "mysql-username: $DB_USER" + echo "mysql-password: $DB_PASS" + +} >> /etc/guacamole/guacamole.properties +msg_ok "Setup Database" + +msg_info "Setup Service" +cat </etc/guacamole/guacd.conf +[server] +bind_host = 127.0.0.1 +bind_port = 4822 +EOF +JAVA_HOME=$(update-alternatives --query javadoc | grep Value: | head -n1 | sed 's/Value: //' | sed 's@bin/javadoc$@@') +cat </etc/systemd/system/tomcat.service +[Unit] +Description=Apache Tomcat Web Application Container +After=network.target +[Service] +Type=forking +Environment="JAVA_HOME=${JAVA_HOME}" +Environment="CATALINA_PID=/opt/apache-guacamole/tomcat9/temp/tomcat.pid" +Environment="CATALINA_HOME=/opt/apache-guacamole/tomcat9/" +Environment="CATALINA_BASE=/opt/apache-guacamole/tomcat9/" +Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC" +Environment="JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom" +ExecStart=/opt/apache-guacamole/tomcat9/bin/startup.sh +ExecStop=/opt/apache-guacamole/tomcat9/bin/shutdown.sh +User=tomcat +Group=tomcat +UMask=0007 +RestartSec=10 +Restart=always +[Install] +WantedBy=multi-user.target +EOF +cat </etc/systemd/system/guacd.service +[Unit] +Description=Guacamole Proxy Daemon (guacd) +After=mysql.service tomcat.service +Requires=mysql.service tomcat.service +[Service] +Type=forking +ExecStart=/etc/init.d/guacd start +ExecStop=/etc/init.d/guacd stop +ExecReload=/etc/init.d/guacd restart +PIDFile=/var/run/guacd.pid +[Install] +WantedBy=multi-user.target +EOF +systemctl -q enable --now mysql tomcat guacd +msg_ok "Setup Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf ~/mysql-connector-java-8.0.26{,.tar.gz} +rm -rf ~/guacamole-auth-jdbc-1.5.5{,.tar.gz} +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/archivebox-install.sh b/install/archivebox-install.sh index ad168ce87..7c97f6154 100644 --- a/install/archivebox-install.sh +++ b/install/archivebox-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck # License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" color @@ -50,14 +50,14 @@ $STD apt-get update $STD apt-get install -y nodejs msg_ok "Installed Node.js" -msg_info "Installing Playright/Chromium" -$STD pip install playwright -$STD playwright install --with-deps chromium -msg_ok "Installed Playright/Chromium" +msg_info "Installing Playwright" +$STD pip install playwright +$STD playwright install-deps chromium +msg_ok "Installed Playwright" -msg_info "Installing ArchiveBox" +msg_info "Installing Chromium and ArchiveBox" mkdir -p /opt/archivebox/{data,.npm,.cache,.local} -$STD adduser --system --shell /bin/bash --gecos 'Archive Box User' --group --disabled-password archivebox +$STD adduser --system --shell /bin/bash --gecos 'Archive Box User' --group --disabled-password --home /home/archivebox archivebox chown -R archivebox:archivebox /opt/archivebox/{data,.npm,.cache,.local} chmod -R 755 /opt/archivebox/data $STD pip install archivebox @@ -66,6 +66,7 @@ expect </etc/GeoIP.conf +#GEOIPUPDATE_EDITION_IDS="GeoLite2-City GeoLite2-ASN" +#GEOIPUPDATE_VERBOSE="1" +#GEOIPUPDATE_ACCOUNT_ID_FILE="/run/secrets/GEOIPUPDATE_ACCOUNT_ID" +#GEOIPUPDATE_LICENSE_KEY_FILE="/run/secrets/GEOIPUPDATE_LICENSE_KEY" +EOF +msg_ok "Installed GeoIP" + +msg_info "Setting up Python 3" +cd /tmp +wget -q https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tgz -O Python.tgz +tar -zxf Python.tgz +cd Python-3.12.1 +$STD ./configure --enable-optimizations +$STD make altinstall +cd ~ +$STD update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.12 1 +msg_ok "Setup Python 3" + +msg_info "Setting up Node.js Repository" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +msg_ok "Set up Node.js Repository" + +msg_info "Installing Node.js" +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Golang" +cd /tmp +set +o pipefail +GO_RELEASE=$(curl -s https://go.dev/dl/ | grep -o -m 1 "go.*\linux-amd64.tar.gz") +wget -q https://golang.org/dl/${GO_RELEASE} +tar -xzf ${GO_RELEASE} -C /usr/local +ln -s /usr/local/go/bin/go /usr/bin/go +set -o pipefail +msg_ok "Installed Golang" + +msg_info "Installing Redis" +$STD apt-get install -y redis-server +systemctl enable -q --now redis-server +msg_ok "Installed Redis" + +msg_info "Installing PostgreSQL" +$STD apt-get install -y postgresql postgresql-contrib +DB_NAME="authentik" +DB_USER="authentik" +DB_PASS="$(openssl rand -base64 18 | cut -c1-13)" +$STD sudo -u postgres psql -c "CREATE DATABASE $DB_NAME;" +$STD sudo -u postgres psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';" +$STD sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;" +$STD sudo -u postgres psql -c "ALTER DATABASE $DB_NAME OWNER TO $DB_USER;" +$STD sudo -u postgres psql -c "ALTER USER $DB_USER WITH SUPERUSER;" +msg_ok "Installed PostgreSQL" + +msg_info "Installing authentik" +RELEASE=$(curl -s https://api.github.com/repos/goauthentik/authentik/releases/latest | grep "tarball_url" | awk '{print substr($2, 2, length($2)-3)}') +mkdir -p /opt/authentik +wget -qO authentik.tar.gz "${RELEASE}" +tar -xzf authentik.tar.gz -C /opt/authentik --strip-components 1 --overwrite +cd /opt/authentik/website +$STD npm install +$STD npm run build-bundled +cd /opt/authentik/web +$STD npm install +$STD npm run build +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +cd /opt/authentik +$STD go mod download +$STD go build -o /go/authentik ./cmd/server +$STD go build -o /opt/authentik/authentik-server /opt/authentik/cmd/server/ +cd /opt/authentik +$STD pip3 install --upgrade pip +$STD pip3 install poetry poetry-plugin-export +ln -s /usr/local/bin/poetry /usr/bin/poetry +$STD poetry install --only=main --no-ansi --no-interaction --no-root +$STD poetry export --without-hashes --without-urls -f requirements.txt --output requirements.txt +$STD pip install --no-cache-dir -r requirements.txt +$STD pip install . +mkdir -p /etc/authentik +mv /opt/authentik/authentik/lib/default.yml /etc/authentik/config.yml +$STD yq -i ".secret_key = \"$(openssl rand -hex 32)\"" /etc/authentik/config.yml +$STD yq -i ".postgresql.password = \"${DB_PASS}\"" /etc/authentik/config.yml +$STD yq -i ".geoip = \"/opt/authentik/tests/GeoLite2-City-Test.mmdb\"" /etc/authentik/config.yml +cp -r /opt/authentik/authentik/blueprints /opt/authentik/blueprints +$STD yq -i ".blueprints_dir = \"/opt/authentik/blueprints\"" /etc/authentik/config.yml +ln -s /usr/bin/python3 /usr/bin/python +ln -s /usr/local/bin/gunicorn /usr/bin/gunicorn +ln -s /usr/local/bin/celery /usr/bin/celery +$STD bash /opt/authentik/lifecycle/ak migrate +cd ~ +msg_ok "Installed authentik" + +msg_info "Creating Services" +cat </etc/systemd/system/authentik-server.service +[Unit] +Description = authentik Server + +[Service] +ExecStart=/opt/authentik/authentik-server +WorkingDirectory=/opt/authentik/ +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/authentik-worker.service +[Unit] +Description = authentik Worker + +[Service] +Environment=DJANGO_SETTINGS_MODULE="authentik.root.settings" +ExecStart=celery -A authentik.root.celery worker -Ofair --max-tasks-per-child=1 --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events +WorkingDirectory=/opt/authentik/authentik +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF +systemctl enable -q --now authentik-server +sleep 2 +systemctl enable -q --now authentik-worker +msg_ok "Created Services" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /tmp/Python-3.12.1 +rm -rf /tmp/Python.tgz +rm -rf go/ +rm -rf /tmp/${GO_RELEASE} +rm -rf /tmp/geoipupdate.deb +rm -rf authentik.tar.gz +$STD apt-get -y remove yq +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/blocky-install.sh b/install/blocky-install.sh index f4cf52d15..b9ae01caa 100644 --- a/install/blocky-install.sh +++ b/install/blocky-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck (tteckster) # License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" color @@ -30,241 +30,46 @@ RELEASE=$(curl -s https://api.github.com/repos/0xERR0R/blocky/releases/latest | wget -qO- https://github.com/0xERR0R/blocky/releases/download/v${RELEASE}/blocky_v${RELEASE}_Linux_arm64.tar.gz | tar -xzf - -C /opt/blocky/ cat </opt/blocky/config.yml -upstream: - # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query - # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) - # this configuration is mandatory, please define at least one external DNS resolver - default: - # example for tcp+udp IPv4 server (https://digitalcourage.de/) - #- 5.9.164.112 - # Cloudflare - - 1.1.1.1 - # example for DNS-over-TLS server (DoT) - #- tcp-tls:fdns1.dismail.de:853 - # example for DNS-over-HTTPS (DoH) - #- https://dns.digitale-gesellschaft.ch/dns-query - # optional: use client name (with wildcard support: * - sequence of any characters, [0-9] - range) - # or single ip address / client subnet as CIDR notation - #laptop*: - #- 123.123.123.123 +# configuration documentation: https://0xerr0r.github.io/blocky/latest/configuration/ -# optional: timeout to query the upstream resolver. Default: 2s -#upstreamTimeout: 2s +upstreams: + groups: + # these external DNS resolvers will be used. Blocky picks 2 random resolvers from the list for each query + # format for resolver: [net:]host:[port][/path]. net could be empty (default, shortcut for tcp+udp), tcp+udp, tcp, udp, tcp-tls or https (DoH). If port is empty, default port will be used (53 for udp and tcp, 853 for tcp-tls, 443 for https (Doh)) + # this configuration is mandatory, please define at least one external DNS resolver + default: + # Cloudflare + - 1.1.1.1 + # Quad9 DNS-over-TLS server (DoT) + - tcp-tls:dns.quad9.net -# optional: If true, blocky will fail to start unless at least one upstream server per group is reachable. Default: false -#startVerifyUpstream: true - -# optional: Determines how blocky will create outgoing connections. This impacts both upstreams, and lists. -# accepted: dual, v4, v6 -# default: dual -#connectIPVersion: dual - -# optional: custom IP address(es) for domain name (with all sub-domains). Multiple addresses must be separated by a comma -# example: query "printer.lan" or "my.printer.lan" will return 192.168.178.3 -#customDNS: - #customTTL: 1h - # optional: if true (default), return empty result for unmapped query types (for example TXT, MX or AAAA if only IPv4 address is defined). - # if false, queries with unmapped types will be forwarded to the upstream resolver - #filterUnmappedTypes: true - # optional: replace domain in the query with other domain before resolver lookup in the mapping - #rewrite: - #example.com: printer.lan - #mapping: - #printer.lan: 192.168.178.3,2001:0db8:85a3:08d3:1319:8a2e:0370:7344 - -# optional: definition, which DNS resolver(s) should be used for queries to the domain (with all sub-domains). Multiple resolvers must be separated by a comma -# Example: Query client.fritz.box will ask DNS server 192.168.178.1. This is necessary for local network, to resolve clients by host name -#conditional: - # optional: if false (default), return empty result if after rewrite, the mapped resolver returned an empty answer. If true, the original query will be sent to the upstream resolver - # Example: The query "blog.example.com" will be rewritten to "blog.fritz.box" and also redirected to the resolver at 192.168.178.1. If not found and if was set to , the original query "blog.example.com" will be sent upstream. - # Usage: One usecase when having split DNS for internal and external (internet facing) users, but not all subdomains are listed in the internal domain. - #fallbackUpstream: false - # optional: replace domain in the query with other domain before resolver lookup in the mapping - #rewrite: - #example.com: fritz.box - #mapping: - #fritz.box: 192.168.178.1 - #lan.net: 192.168.178.1,192.168.178.2 - -# optional: use black and white lists to block queries (for example ads, trackers, adult pages etc.) +# optional: use allow/denylists to block queries (for example ads, trackers, adult pages etc.) blocking: - # definition of blacklist groups. Can be external link (http/https) or local file - blackLists: + # definition of denylist groups. Can be external link (http/https) or local file + denylists: ads: - - https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt - https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts - - http://sysctl.org/cameleon/hosts - - https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt - - | - # inline definition with YAML literal block scalar style - # hosts format - someadsdomain.com - special: - - https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts - # definition of whitelist groups. Attention: if the same group has black and whitelists, whitelists will be used to disable particular blacklist entries. If a group has only whitelist entries -> this means only domains from this list are allowed, all other domains will be blocked - whiteLists: - ads: - - whitelist.txt - - | - # inline definition with YAML literal block scalar style - # hosts format - whitelistdomain.com - # this is a regex - /^banners?[_.-]/ # definition: which groups should be applied for which client clientGroupsBlock: # default will be used, if no special definition for a client name exists default: - ads - - special - # use client name (with wildcard support: * - sequence of any characters, [0-9] - range) - # or single ip address / client subnet as CIDR notation - #laptop*: - #- ads - #192.168.178.1/24: - #- special - # which response will be sent, if query is blocked: - # zeroIp: 0.0.0.0 will be returned (default) - # nxDomain: return NXDOMAIN as return code - # comma separated list of destination IP addresses (for example: 192.100.100.15, 2001:0db8:85a3:08d3:1319:8a2e:0370:7344). Should contain ipv4 and ipv6 to cover all query types. Useful with running web server on this address to display the "blocked" page. - blockType: zeroIp - # optional: TTL for answers to blocked domains - # default: 6h - blockTTL: 1m - # optional: automatically list refresh period (in duration format). Default: 4h. - # Negative value -> deactivate automatically refresh. - # 0 value -> use default - refreshPeriod: 4h - # optional: timeout for list download (each url). Default: 60s. Use large values for big lists or slow internet connections - downloadTimeout: 4m - # optional: Download attempt timeout. Default: 60s - downloadAttempts: 5 - # optional: Time between the download attempts. Default: 1s - downloadCooldown: 10s - # optional: if failOnError, application startup will fail if at least one list can't be downloaded / opened. Default: blocking - #startStrategy: failOnError - -# optional: configuration for caching of DNS responses -caching: - # duration how long a response must be cached (min value). - # If <=0, use response's TTL, if >0 use this value, if TTL is smaller - # Default: 0 - minTime: 5m - # duration how long a response must be cached (max value). - # If <0, do not cache responses - # If 0, use TTL - # If > 0, use this value, if TTL is greater - # Default: 0 - maxTime: 30m - # Max number of cache entries (responses) to be kept in cache (soft limit). Useful on systems with limited amount of RAM. - # Default (0): unlimited - maxItemsCount: 0 - # if true, will preload DNS results for often used queries (default: names queried more than 5 times in a 2-hour time window) - # this improves the response time for often used queries, but significantly increases external traffic - # default: false - prefetching: true - # prefetch track time window (in duration format) - # default: 120 - prefetchExpires: 2h - # name queries threshold for prefetch - # default: 5 - prefetchThreshold: 5 - # Max number of domains to be kept in cache for prefetching (soft limit). Useful on systems with limited amount of RAM. - # Default (0): unlimited - #prefetchMaxItemsCount: 0 - -# optional: configuration of client name resolution -clientLookup: - # optional: this DNS resolver will be used to perform reverse DNS lookup (typically local router) - #upstream: 192.168.178.1 - # optional: some routers return multiple names for client (host name and user defined name). Define which single name should be used. - # Example: take second name if present, if not take first name - #singleNameOrder: - #- 2 - #- 1 - # optional: custom mapping of client name to IP addresses. Useful if reverse DNS does not work properly or just to have custom client names. - #clients: - #laptop: - #- 192.168.178.29 -# optional: configuration for prometheus metrics endpoint -prometheus: - # enabled if true - #enable: true - # url path, optional (default '/metrics') - #path: /metrics # optional: write query information (question, answer, client, duration etc.) to daily csv file queryLog: # optional one of: mysql, postgresql, csv, csv-client. If empty, log to console - #type: mysql - # directory (should be mounted as volume in docker) for csv, db connection string for mysql/postgresql - #target: db_user:db_password@tcp(db_host_or_ip:3306)/db_name?charset=utf8mb4&parseTime=True&loc=Local - #postgresql target: postgres://user:password@db_host_or_ip:5432/db_name - # if > 0, deletes log files which are older than ... days - #logRetentionDays: 7 - # optional: Max attempts to create specific query log writer, default: 3 - #creationAttempts: 1 - # optional: Time between the creation attempts, default: 2s - #creationCooldown: 2s + type: -# optional: Blocky can synchronize its cache and blocking state between multiple instances through redis. -redis: - # Server address and port - #address: redis:6379 - # Password if necessary - #password: passwd - # Database, default: 0 - #database: 2 - # Connection is required for blocky to start. Default: false - #required: true - # Max connection attempts, default: 3 - #connectionAttempts: 10 - # Time between the connection attempts, default: 1s - #connectionCooldown: 3s +# optional: use these DNS servers to resolve denylist urls and upstream DNS servers. It is useful if no system DNS resolver is configured, and/or to encrypt the bootstrap queries. +bootstrapDns: + - upstream: tcp-tls:one.one.one.one + ips: + - 1.1.1.1 -# optional: DNS listener port(s) and bind ip address(es), default 53 (UDP and TCP). Example: 53, :53, "127.0.0.1:5353,[::1]:5353" -port: 553 -# optional: Port(s) and bind ip address(es) for DoT (DNS-over-TLS) listener. Example: 853, 127.0.0.1:853 -#tlsPort: 853 -# optional: HTTPS listener port(s) and bind ip address(es), default empty = no http listener. If > 0, will be used for prometheus metrics, pprof, REST API, DoH... Example: 443, :443, 127.0.0.1:443 -#httpPort: 4000 -#httpsPort: 443 -# optional: Mininal TLS version that the DoH and DoT server will use -#minTlsServeVersion: 1.3 -# if https port > 0: path to cert and key file for SSL encryption. if not set, self-signed certificate will be generated -#certFile: server.crt -#keyFile: server.key -# optional: use this DNS server to resolve blacklist urls and upstream DNS servers. Useful if no DNS resolver is configured and blocky needs to resolve a host name. Format net:IP:port, net must be udp or tcp -#bootstrapDns: tcp+udp:1.1.1.1 - -filtering: -# optional: drop all queries with following query types. Default: empty - #queryTypes: - #- AAAA - -# optional: if path defined, use this file for query resolution (A, AAAA and rDNS). Default: empty -hostsFile: - # optional: Path to hosts file (e.g. /etc/hosts on Linux) - #filePath: /etc/hosts - # optional: TTL, default: 1h - #hostsTTL: 60m - # optional: Time between hosts file refresh, default: 1h - #refreshPeriod: 30m - # optional: Whether loopback hosts addresses (127.0.0.0/8 and ::1) should be filtered or not, default: false - #filterLoopback: true -# optional: Log level (one from debug, info, warn, error). Default: info -#logLevel: info -# optional: Log format (text or json). Default: text -#logFormat: text -# optional: log timestamps. Default: true -#logTimestamp: true -# optional: obfuscate log output (replace all alphanumeric characters with *) for user sensitive data like request domains or responses to increase privacy. Default: false -#logPrivacy: false - -# optional: add EDE error codes to dns response -#ede: - # enabled if true, Default: false - #enable: true +# optional: logging configuration +log: + # optional: Log level (one from trace, debug, info, warn, error). Default: info + level: info EOF msg_ok "Installed Blocky" diff --git a/install/bookstack-install.sh b/install/bookstack-install.sh new file mode 100644 index 000000000..618d37659 --- /dev/null +++ b/install/bookstack-install.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: MickLesk (Canbiz) +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies (Patience)" +$STD apt-get install -y \ + unzip \ + mariadb-server \ + apache2 \ + curl \ + sudo \ + php8.2-{mbstring,gd,fpm,curl,intl,ldap,tidy,bz2,mysql,zip,xml} \ + composer \ + libapache2-mod-php \ + make \ + mc \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Setting up Database" +DB_NAME=bookstack +DB_USER=bookstack +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +$STD sudo mysql -u root -e "CREATE DATABASE $DB_NAME;" +$STD sudo mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" +$STD sudo mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "Bookstack-Credentials" + echo "Bookstack Database User: $DB_USER" + echo "Bookstack Database Password: $DB_PASS" + echo "Bookstack Database Name: $DB_NAME" +} >> ~/bookstack.creds +msg_ok "Set up database" + +msg_info "Setup Bookstack (Patience)" +LOCAL_IP="$(hostname -I | awk '{print $1}')" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/BookStackApp/BookStack/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q "https://github.com/BookStackApp/BookStack/archive/refs/tags/v${RELEASE}.zip" +unzip -q v${RELEASE}.zip +mv BookStack-${RELEASE} /opt/bookstack +cd /opt/bookstack +cp .env.example .env +sudo sed -i "s|APP_URL=.*|APP_URL=http://$LOCAL_IP|g" /opt/bookstack/.env +sudo sed -i "s/DB_DATABASE=.*/DB_DATABASE=$DB_NAME/" /opt/bookstack/.env +sudo sed -i "s/DB_USERNAME=.*/DB_USERNAME=$DB_USER/" /opt/bookstack/.env +sudo sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$DB_PASS/" /opt/bookstack/.env +$STD composer install --no-dev --no-plugins --no-interaction +$STD php artisan key:generate --no-interaction --force +$STD php artisan migrate --no-interaction --force +chown www-data:www-data -R /opt/bookstack /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads /opt/bookstack/storage +chmod -R 755 /opt/bookstack /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads /opt/bookstack/storage +chmod -R 775 /opt/bookstack/storage /opt/bookstack/bootstrap/cache /opt/bookstack/public/uploads +chmod -R 640 /opt/bookstack/.env +$STD a2enmod rewrite +$STD a2enmod php8.2 +echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" +msg_ok "Installed Bookstack" + +msg_info "Creating Service" +cat </etc/apache2/sites-available/bookstack.conf + + ServerAdmin webmaster@localhost + DocumentRoot /opt/bookstack/public/ + + + Options -Indexes +FollowSymLinks + AllowOverride None + Require all granted + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Handle Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + + + + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log combined + + +EOF +$STD a2ensite bookstack.conf +$STD a2dissite 000-default.conf +$STD systemctl reload apache2 +msg_ok "Created Services" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /opt/v${RELEASE}.zip +$STD apt-get autoremove +$STD apt-get autoclean +msg_ok "Cleaned" diff --git a/install/changedetection-install.sh b/install/changedetection-install.sh index 0e0e8e914..c34132d8e 100644 --- a/install/changedetection-install.sh +++ b/install/changedetection-install.sh @@ -85,7 +85,6 @@ $STD npm prune production --prefix /opt/browserless msg_ok "Installed Browserless & Playwright" msg_info "Installing Font Packages" -DEBIAN_FRONTEND=noninteractive $STD apt-get install -y \ fontconfig \ libfontconfig1 \ diff --git a/install/checkmk-install.sh b/install/checkmk-install.sh new file mode 100644 index 000000000..f271815bf --- /dev/null +++ b/install/checkmk-install.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +#Copyright (c) 2021-2025 community-scripts ORG +# Author: Michel Roegl-Brunner (michelroegl-brunner) +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Install Checkmk" +RELEASE=$(curl -fsSL https://api.github.com/repos/checkmk/checkmk/tags | grep "name" | awk '{print substr($2, 3, length($2)-4) }' | grep -v "*-rc" | tail -n +2 | head -n 1) +wget -q https://download.checkmk.com/checkmk/${RELEASE}/check-mk-raw-${RELEASE}_0.bookworm_arm64.deb -O /opt/checkmk.deb +$STD apt-get install -y /opt/checkmk.deb +echo "${RELEASE}" >"/opt/checkmk_version.txt" +msg_ok "Installed Checkmk" + +motd_ssh +customize + +msg_info "Creating Service" +PASSWORD=$(omd create monitoring | grep "password:" | awk '{print $NF}') +$STD omd start +{ + echo "Application-Credentials" + echo "Username: cmkadmin" + echo "Password: $PASSWORD" +} >> ~/checkmk.creds +msg_ok "Created Service" + +msg_info "Cleaning up" +rm -rf /opt/checkmk.deb +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/cloudflared-install.sh b/install/cloudflared-install.sh index cc99746fd..b3927652f 100644 --- a/install/cloudflared-install.sh +++ b/install/cloudflared-install.sh @@ -30,6 +30,41 @@ $STD apt-get update $STD apt-get install -y cloudflared msg_ok "Installed Cloudflared" +read -r -p "Would you like to configure cloudflared as a DNS-over-HTTPS (DoH) proxy? " prompt +if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then + msg_info "Creating Service" + cat </usr/local/etc/cloudflared/config.yml +proxy-dns: true +proxy-dns-address: 0.0.0.0 +proxy-dns-port: 53 +proxy-dns-max-upstream-conns: 5 +proxy-dns-upstream: + - https://1.1.1.1/dns-query + - https://1.0.0.1/dns-query + #- https://8.8.8.8/dns-query + #- https://8.8.4.4/dns-query + #- https://9.9.9.9/dns-query + #- https://149.112.112.112/dns-query +EOF + cat </etc/systemd/system/cloudflared.service +[Unit] +Description=cloudflared DNS-over-HTTPS (DoH) proxy +After=syslog.target network-online.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/cloudflared --config /usr/local/etc/cloudflared/config.yml +Restart=on-failure +RestartSec=10 +KillMode=process + +[Install] +WantedBy=multi-user.target +EOF + systemctl enable -q --now cloudflared.service + msg_ok "Created Service" +fi + motd_ssh customize diff --git a/install/docker-install.sh b/install/docker-install.sh index f46867c6d..711137994 100644 --- a/install/docker-install.sh +++ b/install/docker-install.sh @@ -63,15 +63,7 @@ else msg_ok "Installed Portainer Agent $PORTAINER_AGENT_LATEST_VERSION" fi fi -read -r -p "Would you like to add Docker Compose? " prompt -if [[ ${prompt,,} =~ ^(y|yes)$ ]]; then - msg_info "Installing Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" - DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker} - mkdir -p $DOCKER_CONFIG/cli-plugins - curl -sSL https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_LATEST_VERSION/docker-compose-linux-aarch64 -o ~/.docker/cli-plugins/docker-compose - chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose - msg_ok "Installed Docker Compose $DOCKER_COMPOSE_LATEST_VERSION" -fi + motd_ssh customize diff --git a/install/firefly-install.sh b/install/firefly-install.sh new file mode 100644 index 000000000..703d979e0 --- /dev/null +++ b/install/firefly-install.sh @@ -0,0 +1,103 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: quantumryuu +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + mc \ + sudo \ + wget \ + openssh-server +curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg +echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ bookworm main" >/etc/apt/sources.list.d/php.list +$STD apt-get update +$STD apt-get install -y \ + apache2 \ + libapache2-mod-php8.4 \ + php8.4-{bcmath,cli,intl,curl,zip,gd,xml,mbstring,mysql} \ + mariadb-server \ + composer +msg_ok "Installed Dependencies" + +msg_info "Setting up database" +DB_NAME=firefly +DB_USER=firefly +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +MYSQL_VERSION=$(mysql --version | grep -oP 'Distrib \K[0-9]+\.[0-9]+\.[0-9]+') +mysql -u root -e "CREATE DATABASE $DB_NAME;" +mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED WITH mysql_native_password AS PASSWORD('$DB_PASS');" +mysql -u root -e "GRANT ALL ON $DB_NAME.* TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "Firefly-Credentials" + echo "Firefly Database User: $DB_USER" + echo "Firefly Database Password: $DB_PASS" + echo "Firefly Database Name: $DB_NAME" +} >> ~/firefly.creds +msg_ok "Set up database" + +msg_info "Installing Firefly III (Patience)" +RELEASE=$(curl -s https://api.github.com/repos/firefly-iii/firefly-iii/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}') +cd /opt +wget -q "https://github.com/firefly-iii/firefly-iii/releases/download/v${RELEASE}/FireflyIII-v${RELEASE}.tar.gz" +mkdir -p /opt/firefly +tar -xzf FireflyIII-v${RELEASE}.tar.gz -C /opt/firefly +chown -R www-data:www-data /opt/firefly +chmod -R 775 /opt/firefly/storage +cd /opt/firefly +cp .env.example .env +sed -i "s/DB_HOST=.*/DB_HOST=localhost/" /opt/firefly/.env +sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=$DB_PASS/" /opt/firefly/.env +echo "export COMPOSER_ALLOW_SUPERUSER=1" >> ~/.bashrc +source ~/.bashrc +$STD composer install --no-dev --no-plugins --no-interaction +$STD php artisan firefly:upgrade-database +$STD php artisan firefly:correct-database +$STD php artisan firefly:report-integrity +$STD php artisan firefly:laravel-passport-keys +echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" +msg_ok "Installed Firefly III" + +msg_info "Creating Service" +cat </etc/apache2/sites-available/firefly.conf + + ServerAdmin webmaster@localhost + DocumentRoot /opt/firefly/public/ + + + Options FollowSymLinks + AllowOverride All + Require all granted + + + ErrorLog /var/log/apache2/error.log + CustomLog /var/log/apache2/access.log combined + + +EOF +$STD a2enmod php8.4 +$STD a2enmod rewrite +$STD a2ensite firefly.conf +$STD a2dissite 000-default.conf +$STD systemctl reload apache2 +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /opt/FireflyIII-v${RELEASE}.tar.gz +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/frigate-install.sh b/install/frigate-install.sh index cc968d3f2..9e5cdffb0 100644 --- a/install/frigate-install.sh +++ b/install/frigate-install.sh @@ -15,7 +15,7 @@ network_check update_os msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils,wget,openssh-server} +$STD apt-get install -y {curl,sudo,mc,git,gpg,automake,build-essential,xz-utils,libtool,ccache,pkg-config,libgtk-3-dev,libavcodec-dev,libavformat-dev,libswscale-dev,libv4l-dev,libxvidcore-dev,libx264-dev,libjpeg-dev,libpng-dev,libtiff-dev,gfortran,openexr,libatlas-base-dev,libssl-dev,libtbb2,libtbb-dev,libdc1394-22-dev,libopenexr-dev,libgstreamer-plugins-base1.0-dev,libgstreamer1.0-dev,gcc,gfortran,libopenblas-dev,liblapack-dev,libusb-1.0-0-dev,jq,moreutils,wget,openssh-server,ca-certificates} msg_ok "Installed Dependencies" msg_info "Installing Python3 Dependencies" @@ -104,7 +104,7 @@ fi echo "tmpfs /tmp/cache tmpfs defaults 0 0" >> /etc/fstab msg_ok "Installed Frigate $RELEASE" -if grep -q -o -m1 'avx[^ ]*' /proc/cpuinfo; then +if grep -q -o -m1 -E 'avx[^ ]*' /proc/cpuinfo; then msg_ok "AVX Support Detected" msg_info "Installing Openvino Object Detection Model (Resilience)" $STD pip install -r /opt/frigate/docker/main/requirements-ov.txt diff --git a/install/glance-install.sh b/install/glance-install.sh new file mode 100644 index 000000000..690d939b1 --- /dev/null +++ b/install/glance-install.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: kristocopani +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + mc \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + + +msg_info "Installing Glance" +RELEASE=$(curl -s https://api.github.com/repos/glanceapp/glance/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +cd /opt +wget -q https://github.com/glanceapp/glance/releases/download/v${RELEASE}/glance-linux-arm64.tar.gz +mkdir -p /opt/glance +tar -xzf glance-linux-arm64.tar.gz -C /opt/glance +cat </opt/glance/glance.yml +pages: + - name: Startpage + width: slim + hide-desktop-navigation: true + center-vertically: true + columns: + - size: full + widgets: + - type: search + autofocus: true + - type: bookmarks + groups: + - title: General + links: + - title: Google + url: https://www.google.com/ + - title: Helper Scripts + url: https://github.com/community-scripts/ProxmoxVE +EOF + +echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" +msg_ok "Installed Glance" + +msg_info "Creating Service" +service_path="/etc/systemd/system/glance.service" +echo "[Unit] +Description=Glance Daemon +After=network.target + +[Service] +Type=simple +WorkingDirectory=/opt/glance +ExecStart=/opt/glance/glance --config /opt/glance/glance.yml +TimeoutStopSec=20 +KillMode=process +Restart=on-failure + +[Install] +WantedBy=multi-user.target" >$service_path + +systemctl enable -q --now glance.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /opt/glance-linux-arm64.tar.gz +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file diff --git a/install/glpi-install.sh b/install/glpi-install.sh new file mode 100644 index 000000000..aab88b579 --- /dev/null +++ b/install/glpi-install.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: NĂ­colas Pastorello (opastorello) +# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + git \ + sudo \ + mc \ + apache2 \ + php8.2-{apcu,cli,common,curl,gd,imap,ldap,mysql,xmlrpc,xml,mbstring,bcmath,intl,zip,redis,bz2,soap} \ + php-cas \ + libapache2-mod-php \ + mariadb-server \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Setting up database" +DB_NAME=glpi_db +DB_USER=glpi +DB_PASS=$(openssl rand -base64 18 | tr -dc 'a-zA-Z0-9' | head -c13) +mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql +mysql -u root -e "CREATE DATABASE $DB_NAME;" +mysql -u root -e "CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS';" +mysql -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" +mysql -u root -e "GRANT SELECT ON \`mysql\`.\`time_zone_name\` TO '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" +{ + echo "GLPI Database Credentials" + echo "Database: $DB_NAME" + echo "Username: $DB_USER" + echo "Password: $DB_PASS" +} >> ~/glpi_db.creds +msg_ok "Set up database" + +msg_info "Installing GLPi" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/glpi-project/glpi/releases/latest | grep '"tag_name"' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/') +wget -q "https://github.com/glpi-project/glpi/releases/download/${RELEASE}/glpi-${RELEASE}.tgz" +$STD tar -xzvf glpi-${RELEASE}.tgz +cd /opt/glpi +$STD php bin/console db:install --db-name=$DB_NAME --db-user=$DB_USER --db-password=$DB_PASS --no-interaction +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed GLPi" + +msg_info "Setting Downstream file" +cat < /opt/glpi/inc/downstream.php + /etc/glpi/local_define.php +/etc/apache2/sites-available/glpi.conf + + ServerName localhost + DocumentRoot /opt/glpi/public + + + Require all granted + RewriteEngine On + RewriteCond %{HTTP:Authorization} ^(.+)$ + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ index.php [QSA,L] + + + ErrorLog \${APACHE_LOG_DIR}/glpi_error.log + CustomLog \${APACHE_LOG_DIR}/glpi_access.log combined + +EOF +$STD a2dissite 000-default.conf +$STD a2enmod rewrite +$STD a2ensite glpi.conf +msg_ok "Setup Service" + +msg_info "Setup Cronjob" +echo "* * * * * php /opt/glpi/front/cron.php" | crontab - +msg_ok "Setup Cronjob" + +msg_info "Update PHP Params" +PHP_VERSION=$(ls /etc/php/ | grep -E '^[0-9]+\.[0-9]+$' | head -n 1) +PHP_INI="/etc/php/$PHP_VERSION/apache2/php.ini" +sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 20M/' $PHP_INI +sed -i 's/^post_max_size = .*/post_max_size = 20M/' $PHP_INI +sed -i 's/^max_execution_time = .*/max_execution_time = 60/' $PHP_INI +sed -i 's/^max_input_vars = .*/max_input_vars = 5000/' $PHP_INI +sed -i 's/^memory_limit = .*/memory_limit = 256M/' $PHP_INI +sed -i 's/^;\?\s*session.cookie_httponly\s*=.*/session.cookie_httponly = On/' $PHP_INI +systemctl restart apache2 +msg_ok "Update PHP Params" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /opt/glpi/install +rm -rf /opt/glpi-${RELEASE}.tgz +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" diff --git a/install/grist-install.sh b/install/grist-install.sh new file mode 100644 index 000000000..874639ad5 --- /dev/null +++ b/install/grist-install.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 community-scripts ORG +# Author: cfurrow +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/gristlabs/grist-core + +source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + curl \ + sudo \ + make \ + gnupg \ + ca-certificates \ + mc \ + unzip \ + python3.11-venv \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Installing Node.js" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +$STD apt-get update +$STD apt-get install -y nodejs +$STD npm install -g yarn +msg_ok "Installed Node.js" + +msg_info "Installing Grist" +RELEASE=$(curl -s https://api.github.com/repos/gristlabs/grist-core/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +export CYPRESS_INSTALL_BINARY=0 +export NODE_OPTIONS="--max-old-space-size=2048" +cd /opt +wget -q https://github.com/gristlabs/grist-core/archive/refs/tags/v${RELEASE}.zip +unzip -q v$RELEASE.zip +mv grist-core-${RELEASE} grist +cd grist +$STD yarn install +$STD yarn run build:prod +$STD yarn run install:python +cat </opt/grist/.env +NODE_ENV=production +GRIST_HOST=0.0.0.0 +EOF +echo "${RELEASE}" >/opt/${APPLICATION}_version.txt +msg_ok "Installed Grist" + +msg_info "Create Service" +cat </etc/systemd/system/grist.service +[Unit] +Description=Grist +After=network.target + +[Service] +Type=exec +WorkingDirectory=/opt/grist +ExecStart=/usr/bin/yarn run start:prod +EnvironmentFile=-/opt/grist/.env + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable -q --now grist.service +msg_ok "Created Service" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /opt/v${RELEASE}.zip +$STD apt-get -y autoremove +$STD apt-get -y autoclean +msg_ok "Cleaned" \ No newline at end of file diff --git a/install/hoarder-install.sh b/install/hoarder-install.sh new file mode 100644 index 000000000..fee1b7ea7 --- /dev/null +++ b/install/hoarder-install.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021-2025 tteck +# Author: MickLesk (Canbiz) & vhsdream +# License: MIT +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE + +source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" +color +verb_ip6 +catch_errors +setting_up_container +network_check +update_os + +msg_info "Installing Dependencies" +$STD apt-get install -y \ + g++ \ + build-essential \ + curl \ + git \ + sudo \ + gnupg \ + ca-certificates \ + chromium/stable \ + chromium-common/stable \ + mc \ + wget \ + openssh-server +msg_ok "Installed Dependencies" + +msg_info "Installing Additional Tools" +wget -q https://github.com/Y2Z/monolith/releases/latest/download/monolith-gnu-linux-x86_64 -O /usr/bin/monolith +chmod +x /usr/bin/monolith +wget -q https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux -O /usr/bin/yt-dlp +chmod +x /usr/bin/yt-dlp +msg_ok "Installed Additional Tools" + +msg_info "Installing Meilisearch" +cd /tmp +wget -q https://github.com/meilisearch/meilisearch/releases/latest/download/meilisearch.deb +$STD dpkg -i meilisearch.deb +wget -q https://raw.githubusercontent.com/meilisearch/meilisearch/latest/config.toml -O /etc/meilisearch.toml +MASTER_KEY=$(openssl rand -base64 12) +sed -i \ + -e 's|^env =.*|env = "production"|' \ + -e "s|^# master_key =.*|master_key = \"$MASTER_KEY\"|" \ + -e 's|^db_path =.*|db_path = "/var/lib/meilisearch/data"|' \ + -e 's|^dump_dir =.*|dump_dir = "/var/lib/meilisearch/dumps"|' \ + -e 's|^snapshot_dir =.*|snapshot_dir = "/var/lib/meilisearch/snapshots"|' \ + -e 's|^# no_analytics = true|no_analytics = true|' \ + /etc/meilisearch.toml +msg_ok "Installed Meilisearch" + +msg_info "Installing Node.js" +mkdir -p /etc/apt/keyrings +curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" >/etc/apt/sources.list.d/nodesource.list +$STD apt-get update +$STD apt-get install -y nodejs +msg_ok "Installed Node.js" + +msg_info "Installing Hoarder" +cd /opt +RELEASE=$(curl -s https://api.github.com/repos/hoarder-app/hoarder/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q "https://github.com/hoarder-app/hoarder/archive/refs/tags/v${RELEASE}.zip" +unzip -q v${RELEASE}.zip +mv hoarder-${RELEASE} /opt/hoarder +cd /opt/hoarder +corepack enable +export PUPPETEER_SKIP_DOWNLOAD="true" +export NEXT_TELEMETRY_DISABLED=1 +export CI="true" +cd /opt/hoarder/apps/web +$STD pnpm install --frozen-lockfile +$STD pnpm exec next build --experimental-build-mode compile +cp -r /opt/hoarder/apps/web/.next/standalone/apps/web/server.js /opt/hoarder/apps/web +cd /opt/hoarder/apps/workers +$STD pnpm install --frozen-lockfile + +export DATA_DIR=/opt/hoarder_data +HOARDER_SECRET=$(openssl rand -base64 36 | cut -c1-24) +cat </opt/hoarder/.env +SERVER_VERSION=$RELEASE +NEXTAUTH_SECRET="$HOARDER_SECRET" +NEXTAUTH_URL="http://localhost:3000" +DATA_DIR="$DATA_DIR" +MEILI_ADDR="http://127.0.0.1:7700" +MEILI_MASTER_KEY="$MASTER_KEY" +BROWSER_WEB_URL="http://127.0.0.1:9222" + +# If you're planning to use OpenAI for tagging. Uncomment the following line: +# OPENAI_API_KEY="" + +# If you're planning to use ollama for tagging, uncomment the following lines: +# OLLAMA_BASE_URL="" + +# You can change the models used by uncommenting the following lines, and changing them according to your needs: +# INFERENCE_TEXT_MODEL="gpt-4o-mini" +# INFERENCE_IMAGE_MODEL="gpt-4o-mini" +EOF +echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" +msg_ok "Installed Hoarder" + +msg_info "Running Database Migration" +mkdir -p ${DATA_DIR} +cd /opt/hoarder/packages/db +$STD pnpm migrate +msg_ok "Database Migration Completed" + +msg_info "Creating Services" +cat </etc/systemd/system/meilisearch.service +[Unit] +Description=Meilisearch +After=network.target + +[Service] +ExecStart=/usr/bin/meilisearch --config-file-path /etc/meilisearch.toml +Restart=always + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/hoarder-web.service +[Unit] +Description=Hoarder Web +Wants=network.target hoarder-workers.service +After=network.target hoarder-workers.service + +[Service] +ExecStart=pnpm start +WorkingDirectory=/opt/hoarder/apps/web +EnvironmentFile=/opt/hoarder/.env +Restart=always + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/hoarder-browser.service +[Unit] +Description=Hoarder Headless Browser +After=network.target + +[Service] +User=root +ExecStart=/usr/bin/chromium --headless --no-sandbox --disable-gpu --disable-dev-shm-usage --remote-debugging-address=127.0.0.1 --remote-debugging-port=9222 --hide-scrollbars +Restart=always + +[Install] +WantedBy=multi-user.target +EOF + +cat </etc/systemd/system/hoarder-workers.service +[Unit] +Description=Hoarder Workers +Wants=network.target hoarder-browser.service meilisearch.service +After=network.target hoarder-browser.service meilisearch.service + +[Service] +ExecStart=pnpm start:prod +WorkingDirectory=/opt/hoarder/apps/workers +EnvironmentFile=/opt/hoarder/.env +Restart=always +TimeoutStopSec=5 + +[Install] +WantedBy=multi-user.target +EOF + +systemctl -q enable --now meilisearch.service hoarder-browser.service hoarder-workers.service hoarder-web.service +msg_ok "Created Services" + +motd_ssh +customize + +msg_info "Cleaning up" +rm -rf /tmp/meilisearch.deb +rm -f /opt/v${RELEASE}.zip +$STD apt-get autoremove -y +$STD apt-get autoclean -y +msg_ok "Cleaned" diff --git a/install/homarr-install.sh b/install/homarr-install.sh index b1d58f461..c4d206f97 100644 --- a/install/homarr-install.sh +++ b/install/homarr-install.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck (tteckster) +# Co-Author: MickLesk (Canbiz) # License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE +# Source: https://github.com/ajnart/homarr source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" color @@ -14,14 +16,17 @@ network_check update_os msg_info "Installing Dependencies" -$STD apt-get install -y curl -$STD apt-get install -y sudo -$STD apt-get install -y mc -$STD apt-get install -y git -$STD apt-get install -y ca-certificates -$STD apt-get install -y gnupg -$STD apt-get install -y wget -$STD apt-get install -y openssh-server +$STD apt-get install -y \ + sudo \ + mc \ + curl \ + ca-certificates \ + gnupg \ + make \ + g++ \ + build-essential \ + wget \ + openssh-server msg_ok "Installed Dependencies" msg_info "Setting up Node.js Repository" @@ -33,12 +38,15 @@ msg_ok "Set up Node.js Repository" msg_info "Installing Node.js/Yarn" $STD apt-get update $STD apt-get install -y nodejs -$STD npm install -g npm@latest $STD npm install -g yarn msg_ok "Installed Node.js/Yarn" msg_info "Installing Homarr (Patience)" -$STD git clone -b dev https://github.com/ajnart/homarr.git /opt/homarr +RELEASE=$(curl -s https://api.github.com/repos/ajnart/homarr/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }') +wget -q "https://github.com/ajnart/homarr/archive/refs/tags/v${RELEASE}.zip" +unzip -q v${RELEASE}.zip +rm -rf v${RELEASE}.zip +mv homarr-${RELEASE} /opt/homarr cat </opt/homarr/.env DATABASE_URL="file:./database/db.sqlite" NEXTAUTH_URL="http://localhost:3000" @@ -50,6 +58,7 @@ cd /opt/homarr $STD yarn install $STD yarn build $STD yarn db:migrate +echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" msg_ok "Installed Homarr" msg_info "Creating Service" diff --git a/install/homeassistant-core-install.sh b/install/homeassistant-core-install.sh index a099c4730..ff16f6f16 100644 --- a/install/homeassistant-core-install.sh +++ b/install/homeassistant-core-install.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck (tteckster) # License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE source /dev/stdin <<<"$FUNCTIONS_FILE_PATH" color @@ -14,9 +14,52 @@ network_check update_os msg_info "Installing Dependencies (Patience)" -$STD apt-get install -y git curl sudo mc bluez libffi-dev libssl-dev libjpeg-dev zlib1g-dev autoconf build-essential libopenjp2-7 libturbojpeg0-dev ffmpeg liblapack3 liblapack-dev dbus-broker libpcap-dev libavdevice-dev libavformat-dev libavcodec-dev libavutil-dev libavfilter-dev libmariadb-dev-compat libatlas-base-dev pip python3.12-dev wget openssh-server +$STD apt-get install -y \ + curl \ + git \ + sudo \ + mc \ + gnupg \ + ca-certificates \ + bluez \ + libtiff6 \ + tzdata \ + libffi-dev \ + libssl-dev \ + libjpeg-dev \ + zlib1g-dev \ + autoconf \ + build-essential \ + libopenjp2-7 \ + libturbojpeg0-dev \ + ffmpeg \ + liblapack3 \ + liblapack-dev \ + dbus-broker \ + libpcap-dev \ + libavdevice-dev \ + libavformat-dev \ + libavcodec-dev \ + libavutil-dev \ + libavfilter-dev \ + libmariadb-dev-compat \ + libatlas-base-dev \ + software-properties-common \ + wget \ + openssh-server msg_ok "Installed Dependencies" +msg_info "Setup Python3" +$STD add-apt-repository -y ppa:deadsnakes/ppa +$STD apt-get update +$STD apt-get install -y \ + python3.13-* \ + python3-pip \ + python3.13-dev \ + python3.13-venv +rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED +msg_ok "Setup Python3" + msg_info "Installing UV" $STD pip install uv msg_ok "Installed UV" diff --git a/install/homebox-install.sh b/install/homebox-install.sh index 56ea7ac69..404bc2af5 100644 --- a/install/homebox-install.sh +++ b/install/homebox-install.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash -# Copyright (c) 2021-2024 tteck +# Copyright (c) 2021-2025 tteck # Author: tteck # Co-Author: MickLesk (Canbiz) # License: MIT -# https://github.com/tteck/Proxmox/raw/main/LICENSE +# https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # Source: https://github.com/sysadminsmedia/homebox source /dev/stdin <<< "$FUNCTIONS_FILE_PATH" @@ -28,6 +28,12 @@ msg_info "Installing Homebox" RELEASE=$(curl -s https://api.github.com/repos/sysadminsmedia/homebox/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3) }') wget -qO- https://github.com/sysadminsmedia/homebox/releases/download/${RELEASE}/homebox_Linux_arm64.tar.gz | tar -xzf - -C /opt chmod +x /opt/homebox +cat </opt/.env +# For possible environment variables check here: https://homebox.software/en/configure-homebox +HBOX_MODE=production +HBOX_WEB_PORT=7745 +HBOX_WEB_HOST=0.0.0.0 +EOF echo "${RELEASE}" >"/opt/${APPLICATION}_version.txt" msg_ok "Installed Homebox" @@ -40,6 +46,7 @@ After=network.target [Service] WorkingDirectory=/opt ExecStart=/opt/homebox +EnvironmentFile=/opt/.env Restart=on-failure [Install]