├── LICENSE ├── README.md └── swizzin_installer.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 coder8338 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swizzin installer for Appbox on the Ubuntu 20.04 app! 2 | Finally you can install Swizzin on appbox! I decided to depreciate the appbox_installer as Swizzin seems to cover almost everything and is constantly updated. 3 | 4 | If you're looking to run this on Debian 11, please [click here!](https://github.com/coder8338/appbox_swizzin_installer/tree/Debian_11) 5 | 6 | ## What's Swizzin? 7 | Swizzin was designed to be an easy to use, modular seedbox solution. It currently supports installing over 50 apps! It comes with a cool dashboard to monitor your apps and a nice easy CLI interface for installing more apps. 8 | 9 | For more info check: https://swizzin.ltd/ 10 | 11 | ## Performance 12 | In order to get the best performance, I recommend using Debian 11, it has minimal other things installed so it's much faster. [Click here!](https://github.com/coder8338/appbox_swizzin_installer/tree/Debian_11) to go to the Debian 11 version! 13 | 14 | ## How to run 15 | 1. Install the [Ubuntu 20.04 app](https://www.appbox.co/appstore/app/210) 16 | 17 | 2. Connect to your Ubuntu either through SSH or by the No VNC WebUI (and clicking the "Applications" menu, then "Terminal Emulator") 18 | 19 | 3. Enter the following `sudo bash -c "bash <(curl -Ls https://raw.githubusercontent.com/coder8338/appbox_swizzin_installer/Ubuntu_20.04/swizzin_installer.sh)"` 20 | 21 | ## Pre-installed apps 22 | The script will pre-install sonarr, radarr & panel apps. 23 | 24 | ## Sonarr Error : Failed to load series from API bug 25 | If you get this error ^ use the following command to fix it: 26 | ``` 27 | sed -i 's/127.0.0.1/*/g' /home/appbox/.config/Sonarr/config.xml && sudo systemctl restart sonarr 28 | ``` 29 | 30 | ## Requesting additional apps 31 | You can request new apps & features here: https://feathub.com/liaralabs/swizzin 32 | 33 | ## How to manage apps 34 | Apps can be managed through the Swizzin panel or Swizzin's built-in CLI app. 35 | 36 | ### Using Swizzin's built-in CLI app called box 37 | The box app is really cool, as it allows you to install and remove apps really quickly and easily. 38 | 39 | **Note:** I have added overseer to the install options. 40 | 41 | To enter the box app interactively simply type the following into your terminal: 42 | 43 | `sudo box` 44 | 45 | You can read about how to use box to do even more things here: https://docs.swizzin.net/getting-started/box-basics/ 46 | 47 | For example to start an app use: 48 | 49 | `sudo box start ` 50 | 51 | to stop an app: 52 | 53 | `sudo box stop ` 54 | 55 | to disable an app: 56 | 57 | `sudo box disable ` 58 | 59 | ### Installing/uninstalling apps 60 | 61 | You can either use the interactive CLI with `sudo box` or; 62 | 63 | To list all available apps: 64 | `sudo box list` 65 | 66 | To install a new app: 67 | `sudo box install ` 68 | 69 | To uninstall an app: 70 | `sudo box uninstall ` 71 | 72 | ## FAQs 73 | Q: I want auto moving from my torrent client to anywhere using Radarr/Sonarr 74 | 75 | A: You'll need to mirror the torrent client's directories using: 76 | 77 | ``` 78 | sudo ln -s /APPBOX_DATA/apps/..appboxes.co/torrents/ /torrents 79 | sudo ln -s /APPBOX_DATA/apps/ /torrents/home/apps 80 | sudo ln -s /APPBOX_DATA/storage/ /torrents/home/storage 81 | ``` 82 | -------------------------------------------------------------------------------- /swizzin_installer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export DEBIAN_FRONTEND=noninteractive 4 | 5 | OLD_INSTALLS_EXIST=0 6 | 7 | run_as_root() { 8 | if ! whoami | grep -q 'root'; then 9 | echo "This script must be run with sudo, please run:" 10 | echo "sudo $0" 11 | exit 1 12 | fi 13 | } 14 | 15 | run_as_root 16 | 17 | echo 'Please enter your Debian password (for the username appbox):' 18 | read -r USER_PASSWORD 19 | 20 | userline=$(sudo awk -v u=appbox -F: 'u==$1 {print $2}' /etc/shadow) 21 | IFS='$' 22 | a=($userline) 23 | 24 | if [[ ! "$(printf "${USER_PASSWORD}" | openssl passwd -"${a[1]}" -salt "${a[2]}" -stdin)" = "${userline}" ]]; then 25 | echo "Password does not match" 26 | exit 1 27 | fi 28 | 29 | cd /tmp || exit 1 30 | 31 | url_output() { 32 | echo -e "\n\n\n\n\n 33 | Installation of Swizzin sucessful! Please point your browser to: 34 | \e[4mhttps://${HOSTNAME}/\e[39m\e[0m 35 | 36 | This will ask for your login details which are as follows: 37 | 38 | \e[4mUsername: appbox\e[39m\e[0m 39 | \e[4mPassword: ${USER_PASSWORD}\e[39m\e[0m 40 | 41 | If you want to install/remove apps, please type the following into your terminal: 42 | sudo box 43 | 44 | Some apps will require you to restart the Ubuntu app, so if you find something isn't working, please try that first! 45 | 46 | Enjoy! 47 | 48 | \n\n" 49 | } 50 | 51 | create_service() { 52 | NAME=$1 53 | mkdir -p /etc/services.d/${NAME}/log 54 | echo "3" >/etc/services.d/${NAME}/notification-fd 55 | cat </etc/services.d/${NAME}/log/run 56 | #!/bin/sh 57 | exec logutil-service /var/log/appbox/${NAME} 58 | EOF 59 | chmod +x /etc/services.d/${NAME}/log/run 60 | echo "${RUNNER}" >/etc/services.d/${NAME}/run 61 | chmod +x /etc/services.d/${NAME}/run 62 | cp -R /etc/services.d/${NAME} /var/run/s6/services 63 | kill -HUP 1 64 | until [ -d "/run/s6/services/${NAME}/supervise/" ]; do 65 | echo 66 | echo "Waiting for s6 to recognize service..." 67 | sleep 1 68 | done 69 | s6-svc -u /run/s6/services/${NAME} 70 | } 71 | 72 | mkdir -p /run/php/ 73 | 74 | check_old_installs() { 75 | echo "Checking for old installs..." 76 | # Create array of old installs 77 | OLD_INSTALLS=(radarr sonarr sickchill jackett couchpotato nzbget sabnzbdplus ombi lidarr organizr nzbhydra2 bazarr flexget filebot synclounge medusa lazylibrarian pyload ngpost komga ombiv4 readarr overseerr requestrr updatetool flood tautulli unpackerr mylar flaresolverr) 78 | 79 | # Loop through array 80 | for i in "${OLD_INSTALLS[@]}"; do 81 | # Check if install exists 82 | if [ -d "/etc/services.d/$i" ]; then 83 | OLD_INSTALLS_EXIST=1 84 | fi 85 | done 86 | } 87 | 88 | check_old_installs 89 | 90 | if [ $OLD_INSTALLS_EXIST -eq 1 ]; then 91 | echo "Old installs detected, this will cause a conflict with the new Swizzin services." 92 | echo "Would you like to remove them (y/n)?" 93 | read -r REMOVE_OLD_INSTALLS 94 | if [ "$REMOVE_OLD_INSTALLS" = "y" ] || [ "$REMOVE_OLD_INSTALLS" = "Y" ] || [ "$REMOVE_OLD_INSTALLS" = "yes" ]; then 95 | echo "Removing old installs..." 96 | for i in "${OLD_INSTALLS[@]}"; do 97 | echo "Removing $i..." 98 | s6-svc -d /run/s6/services/"$i" || true 99 | if [ -d "/etc/services.d/$i" ]; then 100 | rm -rf /etc/services.d/"$i" 101 | fi 102 | if [ -d "/var/run/s6/services/$i" ]; then 103 | rm -rf /var/run/s6/services/"$i" 104 | fi 105 | if [ -d "/home/appbox/.config/${i^}" ]; then 106 | rm -rf /home/appbox/.config/"${i^}" 107 | fi 108 | if [ -d "/var/log/appbox/$i" ]; then 109 | rm -rf /var/log/appbox/"$i" 110 | fi 111 | done 112 | 113 | rm -rf /home/appbox/appbox_installer 114 | else 115 | echo "Please remove the old installs and try again, or use this script to remove them." 116 | exit 1 117 | fi 118 | fi 119 | 120 | sed -i 's/www-data/appbox/g' /etc/nginx/nginx.conf 121 | echo -e "\nUpdating mono certs..." 122 | cert-sync --quiet /etc/ssl/certs/ca-certificates.crt 123 | echo -e "\nUpdating apt packages..." 124 | echo >>/etc/apt/apt.conf.d/99verify-peer.conf "Acquire { https::Verify-Peer false }" 125 | 126 | # Just do this the first time 127 | if [ -f /etc/systemd/system/dbus-fi.w1.wpa_supplicant1.service ] && [ ! -f /etc/systemd/system/panel.service ]; then 128 | rm -rf /lib/systemd/system/* 129 | rm -rf /etc/systemd/system/* 130 | fi 131 | 132 | echo "Upgrading system..." 133 | apt-get -qq update 134 | apt-get -qq upgrade -y 135 | 136 | wget -q https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl3.py -O /usr/local/bin/systemctl 137 | chmod +x /usr/local/bin/systemctl 138 | 139 | systemctl daemon-reload 140 | 141 | RUNNER=$( 142 | cat </usr/lib/os-release 161 | NAME="Ubuntu" 162 | VERSION="20.04.1 LTS (Focal Fossa)" 163 | ID=ubuntu 164 | ID_LIKE=debian 165 | PRETTY_NAME="Ubuntu 20.04.1 LTS" 166 | VERSION_ID="20.04" 167 | HOME_URL="https://www.ubuntu.com/" 168 | SUPPORT_URL="https://help.ubuntu.com/" 169 | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" 170 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 171 | VERSION_CODENAME=focal 172 | UBUNTU_CODENAME=focal 173 | EOF 174 | 175 | git clone https://github.com/swizzin/swizzin.git /etc/swizzin &>/dev/null 176 | cd /etc/swizzin || exit 1 177 | git fetch origin overseer &>/dev/null 178 | git merge --no-edit origin/overseer &>/dev/null 179 | sed -i '/Type=exec/d' /etc/swizzin/scripts/install/overseerr.sh 180 | sed -i 's/# _nginx/_nginx/g' /etc/swizzin/scripts/install/overseerr.sh 181 | cat >/etc/swizzin/scripts/nginx/overseerr.sh < /etc/nginx/apps/overseerr.conf << EOF 184 | location /overseerr { 185 | set \\\$app "overseerr"; 186 | # Remove /overseerr path to pass to the app 187 | rewrite ^/overseerr/?(.*)$ /\\\$1 break; 188 | proxy_pass http://127.0.0.1:5055; # NO TRAILING SLASH 189 | # Redirect location headers 190 | proxy_redirect ^ /\\\$app; 191 | proxy_redirect /setup /\\\$app/setup; 192 | proxy_redirect /login /\\\$app/login; 193 | # Sub filters to replace hardcoded paths 194 | proxy_set_header Accept-Encoding ""; 195 | sub_filter_once off; 196 | sub_filter_types *; 197 | sub_filter 'href="/"' 'href="/\\\$app"'; 198 | sub_filter 'href="/login"' 'href="/\\\$app/login"'; 199 | sub_filter 'href:"/"' 'href:"/\\\$app"'; 200 | sub_filter '\/_next' '\/\\\$app\/_next'; 201 | sub_filter '/_next' '/\\\$app/_next'; 202 | sub_filter '/api/v1' '/\\\$app/api/v1'; 203 | sub_filter '/login/plex/loading' '/\\\$app/login/plex/loading'; 204 | sub_filter '/images/' '/\\\$app/images/'; 205 | sub_filter '/apple-' '/\\\$app/apple-'; 206 | sub_filter '/favicon' '/\\\$app/favicon'; 207 | sub_filter '/logo.png' '/\\\$app/logo.png'; 208 | sub_filter '/logo_full.svg' '/\\\$app/logo_full.svg'; 209 | sub_filter '/logo_stacked.svg' '/\\\$app/logo_stacked.svg'; 210 | sub_filter '/site.webmanifest' '/\\\$app/site.webmanifest'; 211 | } 212 | EOF 213 | cat > /opt/overseerr/env.conf << EOF 214 | # specify on which interface to listen, by default overseerr listens on all interfaces 215 | HOST=127.0.0.1 216 | EOF 217 | systemctl try-restart overseerr 218 | EON 219 | sed -i '/Continue setting up user/d' /etc/swizzin/scripts/box 220 | 221 | echo "Installing php required by some apps..." 222 | apt install -y php7.4-fpm 223 | sed -i 's/www-data/appbox/g' /etc/php/7.4/fpm/pool.d/www.conf 224 | systemctl restart php7.4-fpm 225 | 226 | # Hack: Some apps need permissions fixed, chown every 10 mins 227 | if crontab -l | grep -q '/srv'; then 228 | echo "Crontab already updated" 229 | else 230 | (crontab -l; echo "*/10 * * * * chown -R appbox:appbox /srv >/dev/null 2>&1") | crontab 231 | fi 232 | 233 | /etc/swizzin/setup.sh --unattend nginx panel radarr sonarr --user appbox --pass "$USER_PASSWORD" 234 | 235 | cat >/etc/nginx/sites-enabled/default <d+)$" \$p; 239 | } 240 | 241 | server { 242 | listen 80 default_server; 243 | listen [::]:80 default_server; 244 | listen 443 ssl default_server; 245 | listen [::]:443 ssl default_server; 246 | ssl_protocols TLSv1.2 TLSv1.3; 247 | ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 248 | ssl_prefer_server_ciphers off; 249 | ssl_stapling on; 250 | ssl_stapling_verify on; 251 | resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] valid=300s; # Cloudflare 252 | resolver_timeout 5s; 253 | ssl_session_cache shared:MozSSL:10m; # about 40000 sessions 254 | ssl_buffer_size 4k; 255 | ssl_session_timeout 1d; 256 | ssl_session_tickets off; 257 | ssl_certificate /etc/ssl/cert.pem; 258 | ssl_certificate_key /etc/ssl/key.pem; 259 | ssl_trusted_certificate /etc/ssl/cert.pem; 260 | proxy_hide_header Strict-Transport-Security; 261 | add_header Strict-Transport-Security "max-age=63072000" always; 262 | 263 | server_name _; 264 | location /.well-known { 265 | alias /srv/.well-known; 266 | allow all; 267 | default_type "text/plain"; 268 | autoindex on; 269 | } 270 | server_tokens off; 271 | root /srv/; 272 | include /etc/nginx/apps/*.conf; 273 | location ~ /\.ht { 274 | deny all; 275 | } 276 | 277 | location /vnc { 278 | index vnc.html; 279 | alias /usr/share/novnc/; 280 | try_files \$uri \$uri/ /vnc.html; 281 | } 282 | location /websockify_audio { 283 | proxy_http_version 1.1; 284 | proxy_pass http://localhost:6081/; 285 | proxy_set_header Upgrade \$http_upgrade; 286 | proxy_set_header Connection "upgrade"; 287 | proxy_read_timeout 61s; 288 | proxy_buffering off; 289 | } 290 | location /websockify { 291 | proxy_http_version 1.1; 292 | proxy_pass http://localhost:6080/; 293 | proxy_set_header Upgrade \$http_upgrade; 294 | proxy_set_header Connection "upgrade"; 295 | proxy_read_timeout 61s; 296 | proxy_buffering off; 297 | } 298 | proxy_set_header X-Real-IP \$remote_addr; 299 | proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; 300 | proxy_set_header X-Forwarded-Server \$host; 301 | proxy_set_header X-Forwarded-Port \$port; 302 | proxy_set_header X-Forwarded-Proto \$scheme; 303 | proxy_http_version 1.1; 304 | proxy_set_header Upgrade \$http_upgrade; 305 | proxy_set_header Connection \$http_connection; 306 | proxy_set_header Host \$host; 307 | proxy_cache_bypass \$http_upgrade; 308 | proxy_set_header X-Forwarded-Host \$host; 309 | proxy_connect_timeout 300s; 310 | proxy_read_timeout 3600s; 311 | client_header_timeout 300s; 312 | client_body_timeout 300s; 313 | client_max_body_size 1000M; 314 | send_timeout 300s; 315 | } 316 | NGC 317 | 318 | sed -i 's/FORMS_LOGIN = True/FORMS_LOGIN = False/g' /opt/swizzin/core/config.py 319 | echo 'RATELIMIT_ENABLED = False' >> /opt/swizzin/swizzin.cfg 320 | 321 | systemctl restart panel 322 | systemctl restart nginx 323 | 324 | url_output 325 | --------------------------------------------------------------------------------