diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 000000000..29ceefb25 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,14 @@ +default: true +MD007: # Unordered list indentation + indent: 4 +MD013: false # Line length +MD029: # Ordered list item prefix + style: one_or_ordered +MD033: # Inline HTML + allowed_elements: + - a +MD036: false # Emphasis used instead of a header +MD040: false # Fenced code blocks should have a language specified +MD041: false # First line in file should be a top level header +no-hard-tabs: true +whitespace: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..3d94f3a80 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,5 @@ +repos: + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.35.0 + hooks: + - id: markdownlint-fix \ No newline at end of file diff --git a/README.md b/README.md index 291380e8c..f666812a1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [Visit the Swizzin website here](https://swizzin.ltd) +## [Visit the Swizzin website here](https://swizzin.ltd) ---- diff --git a/docs/dev/beta-testing.md b/docs/dev/beta-testing.md index 896c59573..79899dc4e 100644 --- a/docs/dev/beta-testing.md +++ b/docs/dev/beta-testing.md @@ -55,4 +55,5 @@ All you need to do is run `box update`, and you will be back right on track! If you are unsure what is safe to do, please ask the author of the branch to provide you with instructions on how to get back. ### Preventing updates + If you'd like to make sure that you do not go back to the master branch until you are ready, please read the [section on updating](/dev/setup#updating-mechanism). diff --git a/docs/dev/functions.md b/docs/dev/functions.md index 3a73daac1..f850ddb51 100644 --- a/docs/dev/functions.md +++ b/docs/dev/functions.md @@ -5,11 +5,13 @@ sidebar_label: Functions --- ## Snippets + We are keeping a lot of reusable code in the `.vscode/*.code-snippets` files. These give you auto-completions within VSCode and its derivatives, and have pre-defined fields which you can tab-through in order to skip to the next ones. There _should_ be snippets available for all of the functions declared in `global.sh`. + ## Functions :::caution Work in progress! @@ -29,6 +31,7 @@ These functions provide a solution to storing arbitrary information organised by The keys can contain slashes in order to define further structure to the database, in a smilar fashion Windows uses registry keys. Therefore, `abc/def` will create a directory called `abc` and store the key `def` in it. You can then retrieve that value under the key `abc/def`. Available functions are: + - `swizdb set $key $value` - Stores the content of `$value` under the `$key` - `swizdb get $key` @@ -41,36 +44,41 @@ Available functions are: - Removes the key and clears its stored value from the filesystem - Returns exit code `1` in case the key is not present - `swizdb list [$key]` - - Returns a list of present and set full keys + - Returns a list of present and set full keys - Can filter results based on a key "directory". #### `os` functions + _Documented in the file itself_ #### `user` functions -_Documented in the file itself_ +_Documented in the file itself_ #### Echo functions -_Documented in Contributors.md_ +_Documented in Contributors.md_ #### Apt functions + _Documented in Contributors.md_ ### Functions that need to be `source`d #### `utils` + This file contains various functionality which is difficult to separate or justify an entire file for. It is **not** included in `globals.sh` by default. Functions can be moved out of this file and split into their own if it makes sense, but that's a really loose definition and is usually discussed at PR-level. Obviously, if that happens, corrective action needs to be done wherever the functions were used, and the scripts that use it should vaguely be re-tested. #### Python functions for `pyenv` and `venv` + _Documented inline_ These functions handle the installation of the required python versions and creating virtual environments for applications. Please refer to the existing use of these functions in source code. #### `tests` + _Documented **thoroughly** inline_ -This file contains small tests which will often attempt to guess at best testing values unless supplied (e.g. ports, or baseurls). Please read the inline documentation thoroughly. \ No newline at end of file +This file contains small tests which will often attempt to guess at best testing values unless supplied (e.g. ports, or baseurls). Please read the inline documentation thoroughly. diff --git a/docs/dev/intro.md b/docs/dev/intro.md index 41bd8c792..bfd08d997 100644 --- a/docs/dev/intro.md +++ b/docs/dev/intro.md @@ -12,4 +12,4 @@ These docs tell you how to get easily started with a setup we know is fast, conv :::caution These docs are in progress! While this chapter is in development, please make sure to still refer to the [CONTRIBUTORS.md](https://github.com/swizzin/swizzin/blob/master/CONTRIBUTING.md) on our GitHub, which has a very condensed version of all of this. -::: \ No newline at end of file +::: diff --git a/docs/dev/setup.md b/docs/dev/setup.md index b8a57a097..d3bea491f 100644 --- a/docs/dev/setup.md +++ b/docs/dev/setup.md @@ -5,24 +5,28 @@ sidebar_label: Setup --- ## VM + We highly suggest you use a virtualized environment to test your swizzin set up. It is extremely convenient to have this isolated from the rest of your system, and be able to discard and initialize a system within minutes. ### Multipass + :::tip Sausage's preferred development setup ::: + 1. Enable virtualization OS and BIOS side 1. [Install multipass](https://multipass.run) -1. Run `multipass shell` to start a default primary VM and join the shell. -2. Get swizzin repo on your VM +1. Run `multipass shell` to start a default primary VM and join the shell. +1. Get swizzin repo on your VM 1. You can mount it wherever you want (your user directory should be auto-mounted into `/home/ubuntu` if you're using the `primary` instance) 2. You can clone it wherever you want -3. Install swizzin with `bash /path/to/setup.sh --local` +1. Install swizzin with `bash /path/to/setup.sh --local` ### LXD **TODO** ### Parallels + 1. Download your image 2. Create a VM 3. Run through the OS install @@ -47,37 +51,41 @@ Please see contributors.md in the main repo while this is under development ## Installation -This will install swizzin and as part of the setup, symlink your folder to `/etc/swizzin/`. This is useful if your virtualization auto-mounts from your host. +This will install swizzin and as part of the setup, symlink your folder to `/etc/swizzin/`. This is useful if your virtualization auto-mounts from your host. + ```bash bash /path/to/setup.sh --local ``` You can also already have the swizzin folder mounted/cloned in `/etc/`, this option will switch to use the `.dev.lock` option. This is useful if you're manually mounting the folder from your host, or have cloned directly into your VM. + ```bash bash /etc/swizzin/setup.sh --local ``` + ### Updating mechanism + The updater will always reset `/etc/swizzin` to the latest commit in `master`, which you don't necessarily always want. We have made a couple ways to make sure that you can skip that, so that you can then manipulate the content of the directory on your own. -* Running `box update --local` -* Making `/etc/swizzin` a symlink to some other directory on your FS - * This should be done for you if you ran `setup.sh` when it was located outside of `/etc/swizzin` with `--local` -* Adding `.dev.lock` to `/etc/swizzin/` - * This should be done for you if you ran `setup.sh` when it was located in `/etc/swizzin` with `--local` - * You can do `touch /etc/swizzin/.dev.lock` - +* Running `box update --local` +* Making `/etc/swizzin` a symlink to some other directory on your FS + * This should be done for you if you ran `setup.sh` when it was located outside of `/etc/swizzin` with `--local` +* Adding `.dev.lock` to `/etc/swizzin/` + * This should be done for you if you ran `setup.sh` when it was located in `/etc/swizzin` with `--local` + * You can do `touch /etc/swizzin/.dev.lock` ## Testing mechanism + You can run `box test` to test whether all packages are performing as intended. You can supply a specific set of packages (e.g. `box test app1 app2`) to test specifically those. If you create `.test.lock` in `/etc/swizzin`, the test will be performed on every applicable `box` command executed (package and user management ones) - ## Working across forks + If you need a branch from someplace else, please use the GitHub CLI tool `gh` You can read how to install and use the tool on the [GitHub CLI website](https://cli.github.com/). -You can then just run `gh pr checkout 401` to checkout PR #401 \ No newline at end of file +You can then just run `gh pr checkout 401` to checkout PR #401 diff --git a/docs/dev/structure.md b/docs/dev/structure.md index 2fa5ac559..bf47738d6 100644 --- a/docs/dev/structure.md +++ b/docs/dev/structure.md @@ -11,11 +11,13 @@ This sub-chapter goes over what each of the folders in swizzin contains, why the A lot of swizzin logic **depends** on lockfiles and script files following a naming convention. Scripts will be called `.sh` and their lockfiles will be called `/install/..lock`. This means that the naming of these **must** stay in sync in order for swizzin to function correctly. Plase bare this in mind. Exceptions to this rule are explained in the chapters where they apply. ## Scripts + These scripts are to be called directly from their respective `box` calls. Each category is expected to follow the same general structure. **Please familiarise yourself with the "rules of thumb" of the code that is present around the code you are making.** ### Install + `scripts/install/` This directory contains the script that will be executed when `box install ` is executed, which will directly invoke `scripts/install/.sh`. @@ -23,36 +25,39 @@ This directory contains the script that will be executed when `box install The script should generally do the following, if it applies. - Gathering information from the user required for installation - - Please make sure to expose an option to skip these through defining environment variables to provide the answers, and checking their presence. These will need to also be documented. + - Please make sure to expose an option to skip these through defining environment variables to provide the answers, and checking their presence. These will need to also be documented. - Checking incompatibilities - - Possibly migrate from previous major versions/forks of the same application, such as Sonarr v2 -> v3. + - Possibly migrate from previous major versions/forks of the same application, such as Sonarr v2 -> v3. - Installing dependencies - Installing the application (through `apt`, a binary or a script) - Handling user addition in case the app is Multi-user compatible. - Creating and starting the `systemd` service - Installing an nginx config for the application - - _Note: Please make sure to print the application's port to the user when nginx is not installed!_ + - _Note: Please make sure to print the application's port to the user when nginx is not installed!_ - **Creating the lock for the application** It is _heavily_ encouraged to compartmentalise your code into bash functions which are then executed in sequence at the bottom of the file. This provides a better visual segmentation of the code, as well as a better semantic separation which helps with maintenance. ### Test + This dir contains logic to run when `box test [app]*` is executed directly, or indirectly after some `box` commands while on "unstable" or "development" installs. **Unless a file for the specific application is present in this directory**, the default test is ran with the application's name passed to it. Generally, a testing scenario (be it via the default script or the ad-hoc script) should achieve the following: + - Check if services are running - Check if the application has open ports on the local network (e.g. checking port `8080` is open and being listened to) - Check if the port is responding to HTTP requests (e.g. checking `localhost:56789`) - Check if the application is accessible via the reverse proxy (e.g. `localhost/deluge`) - - This should include an authentication to the proxy unless the authentication is outside of nginx's control + - This should include an authentication to the proxy unless the authentication is outside of nginx's control - Any additional functional test to verify that the system is responding correctly - - e.g. if the system user is able to read/write into a user's directory + - e.g. if the system user is able to read/write into a user's directory There are cases when no tests really apply (e.g. `ffmpeg`), and so a "dummy" test file can be required in some instances. ### Remove + `scripts/remove/` This directory contains the script that will be executed when `box remove ` is executed, which will directly invoke `scripts/remove/.sh` @@ -63,14 +68,16 @@ The script should generally do the following, if it applies. - Remove application files (e.g. from `/opt`) - **Removing the lock for the application** -**Please note**: Removing the application's user data/config is something we are currently debating and assessing on a per-application basis. +**Please note**: Removing the application's user data/config is something we are currently debating and assessing on a per-application basis. ### Nginx + `scripts/nginx/` This directory holds scripts that enable an application to work with the `nginx` reverse proxy. There are two times this can be triggered, so please take that into account when writing these scripts + - When nginx is already installed and an application is being installed via `box install app` - After an application is already installed and `nginx` is being via `box install nginx` @@ -79,22 +86,25 @@ This means that all changes to an app's configuration which is require for the r **Handle the nginx reload outside of these scripts**. If you add nginx reloads, this would mean that while the `nginx` installer is running, it will have to reload after every config is installed, which is a bit unnecessary. ### Upgrade + `scripts/upgrade/` This directory contains the script that will be executed when `box upgrade ` is executed, which will directly invoke `scripts/upgrade/.sh` The aim of the scripts in here is to ensure that applications get upgraded across versions when one of the following scenarios is true + - Application is **not** managed through the `apt` package manager - - e.g. `lounge` is installed via `npm` + - e.g. `lounge` is installed via `npm` - There is not built in updater in the application - - e.g. `lounge` has no "update" button in the application itself - - however `radarr` has a built-in self-updater, so no `upgrade` script is necessary + - e.g. `lounge` has no "update" button in the application itself + - however `radarr` has a built-in self-updater, so no `upgrade` script is necessary - A new major version needs to be opted-in by the user - - e.g. the Sonarr v2 to Sonarr v3 migration has to be made by user's choice, and additional functionality needs to be executed to complete a succesful migration between the version. + - e.g. the Sonarr v2 to Sonarr v3 migration has to be made by user's choice, and additional functionality needs to be executed to complete a succesful migration between the version. Before any of the upgrade scripts are ran, the `box update` procedure is done. ### Update + `scripts/update/` These scripts intend to make sure that the user's installation is up to spec with what we expect in our code, so that we do not need to keep track of all the different changes and the history of the package in all the scripts above. @@ -102,15 +112,16 @@ These scripts intend to make sure that the user's installation is up to spec wit **All scripts in this directory will be executed in alphabetical order when `box update` is ran**. It is therefore required that scripts here have their "main functionality" wrapped in `if` statements which verify if the script should run. Each update statement is required to have the following implemented: + - Conditional checks whether execution is necessary (exceptions apply, but discussed at PR-time) - - In general, this would usually consist of: + - In general, this would usually consist of: 1. Top-level check for whether an application is installed 2. Per-segment check whether the conditions for the update are present - A comment describing the condition for the update to trigger - - Any further context should be provided + - Any further context should be provided - Handled echos - - `echo_info` for the start of an update segment and `echo_success` at the end of it - - An `echo_log` in case the update is being skipped. + - `echo_info` for the start of an update segment and `echo_success` at the end of it + - An `echo_log` in case the update is being skipped. These scripts are meant to ensure that older installations behave the exact same way that a fresh installation would. They do not upgrade packages themselves at all. They are purely maintenance scripts ran to update the installation. @@ -124,6 +135,7 @@ While not exactly kosher, you _can_ use this folder for other scripts that shoul --> ## Sources + `sources` This directory contains a lot of helper scripts in general. @@ -131,6 +143,7 @@ This directory contains a lot of helper scripts in general. You can read what each of these functions does in the [functions chapter](functions.md) ### `globals.sh` + Contains the sourcing of all the functions that are "taken for granted" in all the scripts above. This script gets ran as the first thing when `box` functions are triggered, and when running the `setup.sh`. In case you're running `box`-less, you will need to source this into your shell before running your scripts. @@ -138,6 +151,7 @@ This script gets ran as the first thing when `box` functions are triggered, and All of the files mentioned in this file **must** have their functions and variables `export`ed so that they are accessible in the parent shell. ### Functions + `sources/functions` This directory contains all reusable helper functions. All the files within here are expected to be `source`d (often done via the bash `.` alias). This means that all the files here should **only** contain functions which are re-used later, and that these files do not execute anything when being sourced. diff --git a/docs/getting-started/box-basics.md b/docs/getting-started/box-basics.md index f48e6c4f1..ebbabb380 100644 --- a/docs/getting-started/box-basics.md +++ b/docs/getting-started/box-basics.md @@ -7,9 +7,11 @@ sidebar_label: Getting started with box `box` is a homegrown application that will help you install applications on your server and manage their services. ## Introduction + In order to use the installer and management functions on your slot, you'll need to use the included management script: `box`. `box` has several functions, which we'll go over here: + - help - install - remove @@ -26,91 +28,113 @@ Since `box` is considered a complete box management script, its functions requir ::: ## box + When run alone, `box` will start a guided tutorial with install and remove options for availible applications. This option is intended for unfamiliar Swizzin or Linux users. Most users will find `install`, `remove` and `upgrade` to be more viable options, after the initial setup procress. Syntax: + ```bash box ``` ## help + This function provides basic information and usage examples for all availible box commands. Syntax: + ```bash box help ``` ## install + This function installs applications on the server. If you need help with specific commands, please see the `Applications` section on the left side of the website. You can specify multiple applications to install at the same time. Syntax: + ```bash box install rtorrent deluge ``` ## remove + This function removes applications from the server. If you need help with specific commands, please see the `Applications` section on the left side of the website. You can specify multiple applications to remove at once. Syntax: + ```bash box remove rtorrent deluge ``` ## update + This function updates to the latest swizzin release, and applies configuration fixes to already installed applications. This typically fixes issues with the install procress. It is often a requirement for upgrading applications or fixing broken aspects of the seedbox solution. Note: It does _not_ upgrade versions of applications, please see `upgrade` below. Syntax: + ```bash box update ``` ## upgrade -This function upgrades a specific application to a newer version. It can also recompile applications without versions to install the latest fixes. Only some applications have upgrade scripts and their name is required to upgrade them. You can view the specialized list on GitHub. https://github.com/swizzin/swizzin/tree/master/scripts/upgrade + +This function upgrades a specific application to a newer version. It can also recompile applications without versions to install the latest fixes. Only some applications have upgrade scripts and their name is required to upgrade them. You can view the specialized list on GitHub. Syntax: + ```bash box upgrade nginx ``` ## adduser + This function adds additional users to your server. Please note, only the primary user has access to a significant portion of applications. Syntax: + ```bash box adduser faithfulfriend ``` ## deluser + This function removes a user from your server. Please proceed with caution because all of the user data will be destroyed. Syntax: + ```bash box deluser exgirlfriend ``` ## chpasswd + This function changes a user password. `chpasswd` will change the password for SSH, FTP, HTTP, Deluge, and most if-not-all applications. Please specify `chpasswd` followed by the username you wish to change the password. Syntax: + ```bash box chpasswd forgetfulfriend ``` ## list + This function lists and describes all applications currently available for installation. Syntax: + ```bash box list ``` ## test + This function is intended for swizzin developers. It will perform sanity checks about the status of installed applications. Syntax: + ```bash box test # Tests all installed apps box test sonarr radarr # Tests only specified app(s) diff --git a/docs/getting-started/faqs.md b/docs/getting-started/faqs.md index afa1379f2..5f6e82d83 100644 --- a/docs/getting-started/faqs.md +++ b/docs/getting-started/faqs.md @@ -4,7 +4,7 @@ title: Frequently Asked Questions sidebar_label: Frequently Asked Questions --- -## I literally just installed my machine and the dashboard says swizzin is using XXXGB. WHY?! That's simply absurd. +## I literally just installed my machine and the dashboard says swizzin is using XXXGB. WHY?! That's simply absurd swizzin hasn't used the space, don't worry. By default, when using the ext4 partition format, the disk reserves 5% of the space in the partition for the potential scenario whereby the disk runs out of space. If this happens, and your whole server is formatted under a root partition scheme (i.e. no separate /home directory), your server will still have some space reserved to perform essential tasks such as (but not limited to): system updates, logging and various other things, such as bash auto(tab)-completion (crazy, right?). @@ -37,6 +37,7 @@ If you just installed every package just because and you don't actually need quo Please see the chapter above. ## Application XYZ is not running! Everything is broken! What do I do? + Please consult the [Troubleshooting](/guides/troubleshooting) guide for more information. ## ... Docker? @@ -45,6 +46,6 @@ No. You cannot run Swizzin in a docker. The way docker works does not mix well with the amount of different resources swizzin relies on that are present in a standard Debian/Ubuntu Installation. -Swizzin installs all applications in their non-containerized, bare-metal form. This for performance and maintainability reasons. +Swizzin installs all applications in their non-containerized, bare-metal form. This for performance and maintainability reasons. - However you could away with a proper LXC container, using something like Proxmox or with systemd if you know your stuff. Many folks have reported success with those methods. \ No newline at end of file + However you could away with a proper LXC container, using something like Proxmox or with systemd if you know your stuff. Many folks have reported success with those methods. diff --git a/docs/getting-started/how-do-i-connect.md b/docs/getting-started/how-do-i-connect.md index 0bcf531e8..ba7e81b27 100644 --- a/docs/getting-started/how-do-i-connect.md +++ b/docs/getting-started/how-do-i-connect.md @@ -17,13 +17,14 @@ We'll use all of these pieces of information to connect to your server ## Step-by-step guide (Linux/OS X/Windows 10+) Connecting to your slot via Linux or OSX is trivial: + 1. Open a terminal or command prompt/powershell 2. Type: `ssh @` eg: `ssh liara@server.swizzin.ltd` 3. If this is your first time connecting, you will be asked to accept the host's public key. Type "yes" to verify. 4. Enter your password -- (Recommended) Setup [public/private keypair](https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/) authentication -- (Bonus) Encrypt your key with a password during creation + - (Recommended) Setup [public/private keypair](https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/) authentication + - (Bonus) Encrypt your key with a password during creation 5. Done! ## Step-by-step guide (PuTTY) @@ -47,4 +48,4 @@ Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. ➜ ~ -``` \ No newline at end of file +``` diff --git a/docs/guides/advanced-setup.md b/docs/guides/advanced-setup.md index 8267ce2c0..a37089b17 100644 --- a/docs/guides/advanced-setup.md +++ b/docs/guides/advanced-setup.md @@ -13,54 +13,76 @@ If you find some application that is breaking the unattended setup or has no Ins ::: ## Options + :::warning Please note that none of the values that you set here are checked for validity or comaptibility. Make sure you programatically check them before. Setting wrong values here could break your system. ::: + ### `--unattend` - * Disables interactive queries within the `setup.sh` script such as the greeting and installation applications queries. - * **Does not disable interactive queries within package installers**, as those are disabled based on whether environment variables are set. + +* Disables interactive queries within the `setup.sh` script such as the greeting and installation applications queries. +* **Does not disable interactive queries within package installers**, as those are disabled based on whether environment variables are set. * If you find some interactive elements you can't seem to work around, please open an issue on github. + ### `--user` - * Takes the `username` of the master user for swizzin to create as positional argument (i.e. `--user masteruser`) - * _Setting this flag will disable the greeting popup during installation_ + +* Takes the `username` of the master user for swizzin to create as positional argument (i.e. `--user masteruser`) +* _Setting this flag will disable the greeting popup during installation_ + ### `--pass` - * Takes the `password` of the master user for siwzzin to create as positional argument (i.e. `--pass 'P@55w0rd'`) - * To generate a random password, use `--pass ""` - * Shell variables will expand when not in single quotes! - * _Setting this flag will disable the greeting popup during installation_ - * Same as `--password` + +* Takes the `password` of the master user for siwzzin to create as positional argument (i.e. `--pass 'P@55w0rd'`) +* To generate a random password, use `--pass ""` +* Shell variables will expand when not in single quotes! +* _Setting this flag will disable the greeting popup during installation_ +* Same as `--password` + ### `--domain` - * Takes `domain` as positional argument (i.e. `--domain domain.tld`) - * _In the event_ `letsencrypt` is being installed, this will set the domain against which to verify, enable the certificate in the default `nginx` config, and skip cloudflare integration + +* Takes `domain` as positional argument (i.e. `--domain domain.tld`) +* _In the event_ `letsencrypt` is being installed, this will set the domain against which to verify, enable the certificate in the default `nginx` config, and skip cloudflare integration * Shorthand for `LE_hostname=domain.tld`, `LE_defaultconf=yes` and `LF_bool_cf=no` as described in the [Letsencrypt install options](/applications/letsencrypt#install-options). If you need something else, check the [`--env`](#--env) or [environment variables](#environment-variables) options. - * **Please note:** This does not imply that `nginx` and `letsencrypt` will be installed, you still have to pass those as packages to install in order for this to apply. +* **Please note:** This does not imply that `nginx` and `letsencrypt` will be installed, you still have to pass those as packages to install in order for this to apply. + ### `--local` - * Instead of cloning the repository to `/etc/swizzin/`, it will link the folder where `setup.sh` is located to `/etc/swizzin`. - * **Note:** If you (re)move the folder where `setup.sh` was sitting, the link will break, and so will your `box` commands etc. + +* Instead of cloning the repository to `/etc/swizzin/`, it will link the folder where `setup.sh` is located to `/etc/swizzin`. +* **Note:** If you (re)move the folder where `setup.sh` was sitting, the link will break, and so will your `box` commands etc. + ### `--env` - * Takes a path to file as positional argument (e.g. `--env /path/to/env/file.env`) - * Ingests variables and settings from a file for use later through the installer.Please see the [Env File](#env-file) Chapter below - * _Using this implies using [`--unattend`](#--unattend)_ - * If `--env` is specified after other arguments, contents of env file will override the arguments. If arguments are specified after the `--env file`, they will override the content of the env file. + +* Takes a path to file as positional argument (e.g. `--env /path/to/env/file.env`) +* Ingests variables and settings from a file for use later through the installer.Please see the [Env File](#env-file) Chapter below +* _Using this implies using [`--unattend`](#--unattend)_ +* If `--env` is specified after other arguments, contents of env file will override the arguments. If arguments are specified after the `--env file`, they will override the content of the env file. * if you do `bash setup.sh --env /path/to/file.env --user otheruser`, all of the env file contents will be ingested, and then the user will be overridden to `otheruser` * The only exception to this are the packages specified on the CLI. If they are specified after the `--env`, they will get added to the list. + ### `--post-command` - * Takes a string variable with commands to execute at the end of the installation script + +* Takes a string variable with commands to execute at the end of the installation script + ### `--tests` - * When set, all packages will be tested using `box test` after the installation. + +* When set, all packages will be tested using `box test` after the installation. + ### `[package(s)]` - * Any other arguments are treated as a name of a swizzin package to install. - * **The order of packages matters**, if a package requires another as a dependency and its absence would make an installer fail, make sure to put the dependency first - * e.g. when installing `ruTorrent`, you need to ensure that both `nginx` and `rtorrent` come before `rutorrent`, as the installation of that package will fail. - * If any package is specified, the application installation picker will be skipped during the installation - * If you want no packages to be installed, make sure to specify [the `--unattend` flag](#--unattend) + +* Any other arguments are treated as a name of a swizzin package to install. +* **The order of packages matters**, if a package requires another as a dependency and its absence would make an installer fail, make sure to put the dependency first + * e.g. when installing `ruTorrent`, you need to ensure that both `nginx` and `rtorrent` come before `rutorrent`, as the installation of that package will fail. +* If any package is specified, the application installation picker will be skipped during the installation +* If you want no packages to be installed, make sure to specify [the `--unattend` flag](#--unattend) + ### Environment variables - * You can pass environment variables to the script either through... + +* You can pass environment variables to the script either through... * `export` within your shell before running `bash setup.sh` * you can use something like `var1=value var2=value bash setup.sh` - * Same options are available as are for the [env file](#env-file). +* Same options are available as are for the [env file](#env-file). ## Env file + :::warning Please note that none of the values that you set here are checked for validity or comaptibility. Please test your env file thoroughly before deployment. ::: @@ -69,13 +91,14 @@ You can use a file with recorded variables for `setup.sh` to use, instead of usi An example file is included in the root of the swizzin git repo. -If a package has an "Install Options" chapter, you can specify those values in this file. Please note that these options can change over time. An example of these can be found [here](/applications/letsencrypt#install-options), or in the source code. +If a package has an "Install Options" chapter, you can specify those values in this file. Please note that these options can change over time. An example of these can be found [here](/applications/letsencrypt#install-options), or in the source code. **Please take these precauttions into account**: + * Some variables gett exported, some only sourced - * Variables starting with **caps** (`[A-Z]`) will get `export`ed - * Variables starting with **miniscules** (`[a-z]`) will get `source`d - * Please make sure to read the env file example in the repo, and the docs of the application you intend to configure + * Variables starting with **caps** (`[A-Z]`) will get `export`ed + * Variables starting with **miniscules** (`[a-z]`) will get `source`d + * Please make sure to read the env file example in the repo, and the docs of the application you intend to configure * You cannot set the option to make a local install in an env file, you will need to append [`--local`](#--local) on the command line. ```bash @@ -101,19 +124,23 @@ LE_cf_zone="some.zone.asdasdasdasd" # or LE_cf_zoneexists=yes if you don't need ``` ## Examples + A fully automated install with everything in an env file, and user and password which override the env file + ```bash bash <(wget -qO - s5n.sh) \ --env /path/to/file.env --user tester --pass tester123 ``` Quickly get a local environment with a user installed, using your local fork clone instead of upstream, and no apps installed + ```bash git clone bash /path/to/swizzin/setup.sh --user tester --pass tester123 --local --unattend ``` Get a quick transmission installation + ```bash arg_transmissionsource="Repo" \ bash <(wget -qO - s5n.sh) \ @@ -121,12 +148,14 @@ bash <(wget -qO - s5n.sh) \ ``` Get the Dan Martini(TM) (A username, password, domain, nginx and letsencrypt only. Shaken, not interrupted) + ```bash bash <(wget -qO - s5n.sh) \ --unattend --user tester --pass tester123 --domain testing.com nginx letsencrypt ``` The sausage multipass developer menu (this definitely is not me just saving my command recipe for later) + ```powershell multipass delete --all --purge; multipass launch -n swiz; \ multipass mount .\Git\Fun\swizzin\ swiz:/home/ubuntu/swizzin; \ diff --git a/docs/guides/cloudflare-qb.md b/docs/guides/cloudflare-qb.md index cb814039d..6419e2064 100644 --- a/docs/guides/cloudflare-qb.md +++ b/docs/guides/cloudflare-qb.md @@ -18,292 +18,299 @@ Once you understand what’s involved, grab a cup of coffee and let’s get to w 1. Sign up for CloudFlare -The first step is to sign up with an account at CloudFlare and move the nameservers of your domain over to the one’s provided during CloudFlare’s setup. Once CloudFlare is setup, make sure you add your failover IP to a new subdomain, i.e. plex.yourdomain.com. Until we setup Let’s Encrypt for the subdomain, ensure server traffic is not being routed through CloudFlare just yet. (grey icon) Further, under the crypto tab, ensure SSL is set to either Full or Full (Strict) + The first step is to sign up with an account at CloudFlare and move the nameservers of your domain over to the one’s provided during CloudFlare’s setup. Once CloudFlare is setup, make sure you add your failover IP to a new subdomain, i.e. plex.yourdomain.com. Until we setup Let’s Encrypt for the subdomain, ensure server traffic is not being routed through CloudFlare just yet. (grey icon) Further, under the crypto tab, ensure SSL is set to either Full or Full (Strict) 2. Add a second IP to your server -As your new nameservers propagate throughout the network, take this time to bring up the second IP on your server. We need this second IP to bind an instance of NGINX to, so that there are no conflicts with our currently running Apache server. If you want to reverse proxy apache through nginx, you could run this all off a single IP, but that won’t be covered here. + As your new nameservers propagate throughout the network, take this time to bring up the second IP on your server. We need this second IP to bind an instance of NGINX to, so that there are no conflicts with our currently running Apache server. If you want to reverse proxy apache through nginx, you could run this all off a single IP, but that won’t be covered here. -The setup of an IP may vary from host to host; however for a dedicated machine running Ubuntu, this method should work for most. A failover ip can be brought online by editing the file/etc/network/interfaces to bring a new ip address online for your network interface. + The setup of an IP may vary from host to host; however for a dedicated machine running Ubuntu, this method should work for most. A failover ip can be brought online by editing the file/etc/network/interfaces to bring a new ip address online for your network interface. -``` -sudo nano /etc/network/interfaces -``` -Insert at the bottom of interface eth0 (before ipv6 if your server supports it). Replace IP.OF.FAIL.OVER with the IP you were given by your provider and replace eth0 with the name of your adapter if necessary (e.g. enp2s0): + ``` + sudo nano /etc/network/interfaces + ``` -``` -up ip addr add IP.OF.FAIL.OVER/32 dev eth0 -down ip addr del IP.OF.FAIL.OVER/32 dev eth0 -``` -Save and exit. Bring the new interface online with the command + Insert at the bottom of interface eth0 (before ipv6 if your server supports it). Replace IP.OF.FAIL.OVER with the IP you were given by your provider and replace eth0 with the name of your adapter if necessary (e.g. enp2s0): -``` -ip addr add IP.OF.FAIL.OVER/32 dev eth0 -``` -You should now be able to ping your new IP. Confirm with a local test:ping IP.OF.FAIL.OVER If your new IP fails to respond to ping, consider consulting your host’s documentation for help. + ``` + up ip addr add IP.OF.FAIL.OVER/32 dev eth0 + down ip addr del IP.OF.FAIL.OVER/32 dev eth0 + ``` + + Save and exit. Bring the new interface online with the command + + ``` + ip addr add IP.OF.FAIL.OVER/32 dev eth0 + ``` + + You should now be able to ping your new IP. Confirm with a local test:ping IP.OF.FAIL.OVER If your new IP fails to respond to ping, consider consulting your host’s documentation for help. 3. Bind Apache to the main IP of your server -If you don’t know the IP address of your server you can attempt to be lazy and grab it with this one-liner: - -``` -sudo ifconfig | grep -m1 "inet addr" | cut -d: -f2 | cut -d" " -f1 -``` - -If that doesn’t work, check the email that your host sent you :sweat_smile: - -Now we need to edit two files in apache to prevent Apache2 from binding to all available interfaces: - -``` -sudo nano /etc/apache2/ports.conf -``` - -It should look something like this: - -``` -# If you just change the port or add more ports here, you will likely also -# have to change the VirtualHost statement in -# /etc/apache2/sites-enabled/000-default.conf - -Listen 80 - - -Listen 443 - - - -Listen 443 - - -# vim: syntax=apache ts=4 sw=4 sts=4 sr noet -``` - -Alter the file as such: - -``` -# If you just change the port or add more ports here, you will likely also -# have to change the VirtualHost statement in -# /etc/apache2/sites-enabled/000-default.conf - -Listen ORIG.IP.OF.SRV:80 - - -Listen ORIG.IP.OF.SRV:443 - - - -Listen ORIG.IP.OF.SRV:443 - - -# vim: syntax=apache ts=4 sw=4 sts=4 sr noet -``` - -Save, exit and load up the next file: - -``` -sudo nano /etc/apache2/sites-enabled/default-ssl.conf -``` - -Find the sections where it says and. Replace the asterisks with the ORIG.IP.OF.SRV: - -``` -... - -... - -``` - -Now, stop Apache2. - -``` -sudo systemctl stop apache2 -``` + If you don’t know the IP address of your server you can attempt to be lazy and grab it with this one-liner: + + ``` + sudo ifconfig | grep -m1 "inet addr" | cut -d: -f2 | cut -d" " -f1 + ``` + + If that doesn’t work, check the email that your host sent you :sweat_smile: + + Now we need to edit two files in apache to prevent Apache2 from binding to all available interfaces: + + ``` + sudo nano /etc/apache2/ports.conf + ``` + + It should look something like this: + + ``` + # If you just change the port or add more ports here, you will likely also + # have to change the VirtualHost statement in + # /etc/apache2/sites-enabled/000-default.conf + + Listen 80 + + + Listen 443 + + + + Listen 443 + + + # vim: syntax=apache ts=4 sw=4 sts=4 sr noet + ``` + + Alter the file as such: + + ``` + # If you just change the port or add more ports here, you will likely also + # have to change the VirtualHost statement in + # /etc/apache2/sites-enabled/000-default.conf + + Listen ORIG.IP.OF.SRV:80 + + + Listen ORIG.IP.OF.SRV:443 + + + + Listen ORIG.IP.OF.SRV:443 + + + # vim: syntax=apache ts=4 sw=4 sts=4 sr noet + ``` + + Save, exit and load up the next file: + + ``` + sudo nano /etc/apache2/sites-enabled/default-ssl.conf + ``` + + Find the sections where it says and. Replace the asterisks with the ORIG.IP.OF.SRV: + + ``` + ... + + ... + + ``` + + Now, stop Apache2. + + ``` + sudo systemctl stop apache2 + ``` 4. Install NGINX, Let’s Encrypt and bind to the failover IP Start by installing nginx: -``` -sudo apt update -sudo apt install nginx -``` + ``` + sudo apt update + sudo apt install nginx + ``` + + Also, if you do not have Let’s Encrypt installed, now would be the time to do that + + ``` + sudo apt install letsencrypt + ``` + + Now, we need to alter nginx to bind to our new IP and also connect with the Let’s Encrypt servers so that they can issue you an SSL certificate. + + ``` + sudo nano /etc/nginx/sites-enabled/default + ``` -Also, if you do not have Let’s Encrypt installed, now would be the time to do that + Underneath the block you should see -``` -sudo apt install letsencrypt -``` + ``` + server { + listen 80 default_server; + ``` -Now, we need to alter nginx to bind to our new IP and also connect with the Let’s Encrypt servers so that they can issue you an SSL certificate. + Insert your failover IP and the .well-known location for Let’s Encrypt: -``` -sudo nano /etc/nginx/sites-enabled/default -``` + ``` + server { + listen IP.OF.FAIL.OVER:80 default_server; + + location ~ /.well-known { + allow all; + } + ``` -Underneath the block you should see + Save and exit. Run the command `sudo nginx -t` to ensure your configuration is valid. If yes, hooray! Let’s take this opportunity to restart nginx and bring our apache2 server back online. -``` -server { -listen 80 default_server; -``` + ``` + sudo systemctl restart nginx + sudo systemctl restart apache2 + ``` -Insert your failover IP and the .well-known location for Let’s Encrypt: + Ensure there are no conflicts and both services are currently running (`systemctl status apache2` & `systemctl status nginx`) -``` -server { -listen IP.OF.FAIL.OVER:80 default_server; - -location ~ /.well-known { -allow all; -} -``` + Now we can use Let’s Encrypt to grab an SSL certificate. Make sure your DNS is pointing at your failover (and not through cloudflare) -Save and exit. Run the command `sudo nginx -t` to ensure your configuration is valid. If yes, hooray! Let’s take this opportunity to restart nginx and bring our apache2 server back online. + ``` + sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d plex.yourdomain.com + ``` -``` -sudo systemctl restart nginx -sudo systemctl restart apache2 -``` + If all goes well you now have shiny new SSL certs for plex.yourdomain.com. -Ensure there are no conflicts and both services are currently running (`systemctl status apache2` & `systemctl status nginx`) + Now we will beef up security just a bit more: -Now we can use Let’s Encrypt to grab an SSL certificate. Make sure your DNS is pointing at your failover (and not through cloudflare) + ``` + sudo bash + cd /etc/letsencrypt/live/plex.yourdomain.com/ + ``` -``` -sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d plex.yourdomain.com -``` + Check the issuing authority of your certificate as per: source -If all goes well you now have shiny new SSL certs for plex.yourdomain.com. + ``` + sudo openssl x509 -noout -text -in fullchain.pem | grep Issuer: + ``` -Now we will beef up security just a bit more: + You’ll see something like: -``` -sudo bash -cd /etc/letsencrypt/live/plex.yourdomain.com/ -``` + ``` + Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3 + ``` -Check the issuing authority of your certificate as per: source + Download the corresponding pem: -``` -sudo openssl x509 -noout -text -in fullchain.pem | grep Issuer: -``` + ``` + wget -O chain.pem "https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem" + ``` -You’ll see something like: -``` -Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3 -``` -Download the corresponding pem: + Change x3 if necessary to correlate to the authority who issued your certificate. -``` -wget -O chain.pem "https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem" -``` + Now we will generate a dhparam for nginx -Change x3 if necessary to correlate to the authority who issued your certificate. + ``` + mkdir -p /etc/nginx/ssl + cd /etc/nginx/ssl + openssl dhparam -out dhparam.pem 2048 + ``` -Now we will generate a dhparam for nginx + We now have everything we need to configure our Plex Reverse Proxy: -``` -mkdir -p /etc/nginx/ssl -cd /etc/nginx/ssl -openssl dhparam -out dhparam.pem 2048 -``` + ``` + cd /etc/nginx/sites-enabled + wget -O plex.conf https://raw.githubusercontent.com/toomuchio/plex-nginx-reverseproxy/master/nginx.conf + ``` -We now have everything we need to configure our Plex Reverse Proxy: + Now we must alter the file to include our failover IP, ssl certificates and dhparam. -``` -cd /etc/nginx/sites-enabled -wget -O plex.conf https://raw.githubusercontent.com/toomuchio/plex-nginx-reverseproxy/master/nginx.conf -``` + ``` + nano plex.conf + ``` -Now we must alter the file to include our failover IP, ssl certificates and dhparam. + Find and insert your failover IP into the two listen parameters -``` -nano plex.conf -``` + ``` + listen 80; + listen 443 ssl http2; + ``` -Find and insert your failover IP into the two listen parameters + becomes -``` -listen 80; -listen 443 ssl http2; -``` -becomes + ``` + listen IP.OF.FAIL.OVER:80; + listen IP.OF.FAIL.OVER:443 ssl http2; + ``` -``` -listen IP.OF.FAIL.OVER:80; -listen IP.OF.FAIL.OVER:443 ssl http2; -``` + Next find: -Next find: + ``` + ssl_certificate + ssl_certificate_key + ``` -``` -ssl_certificate -ssl_certificate_key -``` -Insert your letsencrypt certificates here: + Insert your letsencrypt certificates here: -``` -ssl_certificate /etc/letsencrypt/live/plex.yourdomain.com/fullchain.pem; -ssl_certificate_key /etc/letsencrypt/live/plex.yourdomain.com/privkey.pem; -``` + ``` + ssl_certificate /etc/letsencrypt/live/plex.yourdomain.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/plex.yourdomain.com/privkey.pem; + ``` -Now add our trusted certificate (chain.pem): + Now add our trusted certificate (chain.pem): -``` -ssl_trusted_certificate /etc/letsencrypt/live/plex.yourdomain.com/chain.pem; -``` + ``` + ssl_trusted_certificate /etc/letsencrypt/live/plex.yourdomain.com/chain.pem; + ``` -And the dhparam a bit further down: + And the dhparam a bit further down: -``` -ssl_dhparam /etc/nginx/ssl/dhparam.pem; -``` + ``` + ssl_dhparam /etc/nginx/ssl/dhparam.pem; + ``` -That’s all the edits we need to make to this file so save and exit. Test your config and cross your fingers! + That’s all the edits we need to make to this file so save and exit. Test your config and cross your fingers! -``` -nginx -t -``` + ``` + nginx -t + ``` -If all goes well, start your server + If all goes well, start your server -``` -systemctl start nginx -``` + ``` + systemctl start nginx + ``` -Now your Plex should be accessible viahttps://plex.yourdomain.com + Now your Plex should be accessible viahttps://plex.yourdomain.com 5. Alter your Plex Server settings -Make sure “Show Advanced Settings” is on. Under the Network tab add a custom access url: + Make sure “Show Advanced Settings” is on. Under the Network tab add a custom access url: -``` -https://plex.yourdomain.com:443 -``` + ``` + https://plex.yourdomain.com:443 + ``` -Under Remote Access, disable remote access + Under Remote Access, disable remote access 6. Update firewall to prevent external pinging of port 32400 -``` -iptables -A INPUT -p tcp -s localhost --dport 32400 -j ACCEPT -iptables -A INPUT -p tcp --dport 32400 -j DROP -``` + ``` + iptables -A INPUT -p tcp -s localhost --dport 32400 -j ACCEPT + iptables -A INPUT -p tcp --dport 32400 -j DROP + ``` -The first rule ensures our localhost is still able to talk with Plex. This allows our proxy to communicate, with the internal server, but the second rule prevents all other access. As such, you should still be able to access your plex installation from both plex.tv/web/app and plex.yourdomain.com. Confirm you are able to, then once you have, ensure these rules stay persistent upon a reboot with iptables-persistent: + The first rule ensures our localhost is still able to talk with Plex. This allows our proxy to communicate, with the internal server, but the second rule prevents all other access. As such, you should still be able to access your plex installation from both plex.tv/web/app and plex.yourdomain.com. Confirm you are able to, then once you have, ensure these rules stay persistent upon a reboot with iptables-persistent: -``` -apt install iptables-persistent -``` + ``` + apt install iptables-persistent + ``` -Choose yes during installation to save your current iptables (note if you have any fail2ban rules, they may get included in here. Make sure you have no firewall rules you don’t want to save, though you can remove unintentional additions if needed. + Choose yes during installation to save your current iptables (note if you have any fail2ban rules, they may get included in here. Make sure you have no firewall rules you don’t want to save, though you can remove unintentional additions if needed. -At this point, no data should be served from your server via port 32400 and all traffic should flow exclusively through port 443 (you can verify this with tcptrack – your server will not establish connections via port 32400 during playback though it will try- SYN_CONNECT). + At this point, no data should be served from your server via port 32400 and all traffic should flow exclusively through port 443 (you can verify this with tcptrack – your server will not establish connections via port 32400 during playback though it will try- SYN_CONNECT). 7. Enable CloudFlare CDN for plex.mydomain.com -Change over that grey cloud icon to the orange one! + Change over that grey cloud icon to the orange one! -Your data is now being proxied through CloudFlare’s servers. Congratulations!! Once the DNS switches over to your CloudFlare IP you should see a noticeable improvement in your speeds and jitter. + Your data is now being proxied through CloudFlare’s servers. Congratulations!! Once the DNS switches over to your CloudFlare IP you should see a noticeable improvement in your speeds and jitter. -Please note this may not be perfect – I will do my best to answer questions and update and errors in the guide. Please let me know if you run into issues! + Please note this may not be perfect – I will do my best to answer questions and update and errors in the guide. Please let me know if you run into issues! -If you’re worried about sending all of your data through cloudflare, the same basic principle could apply to a VPS such as Linode, Vultr or other. \ No newline at end of file + If you’re worried about sending all of your data through cloudflare, the same basic principle could apply to a VPS such as Linode, Vultr or other. diff --git a/docs/guides/cloudflare.md b/docs/guides/cloudflare.md index a4158159e..23bb5ad11 100644 --- a/docs/guides/cloudflare.md +++ b/docs/guides/cloudflare.md @@ -15,121 +15,124 @@ Once you understand what’s involved, grab a cup of coffee and let’s get to w 1. Sign up for CloudFlare -The first step is to sign up with an account at CloudFlare and move the nameservers of your domain over to the one’s provided during CloudFlare’s setup. Once CloudFlare is setup, make sure you add your server's IP to a new subdomain, i.e. plex.yourdomain.com. Make sure to turn on routing to CloudFlare (orange cloud icon). Further, under the crypto tab, ensure SSL is set to either Full or Full (Strict) + The first step is to sign up with an account at CloudFlare and move the nameservers of your domain over to the one’s provided during CloudFlare’s setup. Once CloudFlare is setup, make sure you add your server's IP to a new subdomain, i.e. plex.yourdomain.com. Make sure to turn on routing to CloudFlare (orange cloud icon). Further, under the crypto tab, ensure SSL is set to either Full or Full (Strict) 2. Grab the SSL certificate for your domain: -First install acme.sh if you have not run the let's encrypt installer from swizzin yet. Ignore the warning about socat if you receive one. We will not be using the standalone webserver to issue certificates + First install acme.sh if you have not run the let's encrypt installer from swizzin yet. Ignore the warning about socat if you receive one. We will not be using the standalone webserver to issue certificates -``` -curl https://get.acme.sh | sh -``` + ``` + curl https://get.acme.sh | sh + ``` -Now, we will issue a certificate, but first we will define a couple variables: + Now, we will issue a certificate, but first we will define a couple variables: -``` -hostname={YOUR HOSTNAME. eg plex.yourdomain.com} -export CF_Key={YOUR CF API KEY} -export CF_Email={YOUR CF EMAIL} -``` + ``` + hostname={YOUR HOSTNAME. eg plex.yourdomain.com} + export CF_Key={YOUR CF API KEY} + export CF_Email={YOUR CF EMAIL} + ``` -Once you have defined these variables then get the certificates and install them to your nginx directory. You can copy and paste these commands if you have defined your variables correctly, as above: + Once you have defined these variables then get the certificates and install them to your nginx directory. You can copy and paste these commands if you have defined your variables correctly, as above: -``` -mkdir -p /etc/nginx/ssl/${hostname} -/root/.acme.sh/acme.sh --issue --dns dns_cf -d ${hostname} -/root/.acme.sh/acme.sh --install-cert -d ${hostname} --key-file /etc/nginx/ssl/${hostname}/key.pem --fullchain-file /etc/nginx/ssl/${hostname}/fullchain.pem --ca-file /etc/nginx/ssl/${hostname}/chain.pem --reloadcmd "service nginx force-reload" -``` -We now have everything we need to configure our Plex Reverse Proxy: + ``` + mkdir -p /etc/nginx/ssl/${hostname} + /root/.acme.sh/acme.sh --issue --dns dns_cf -d ${hostname} + /root/.acme.sh/acme.sh --install-cert -d ${hostname} --key-file /etc/nginx/ssl/${hostname}/key.pem --fullchain-file /etc/nginx/ssl/${hostname}/fullchain.pem --ca-file /etc/nginx/ssl/${hostname}/chain.pem --reloadcmd "service nginx force-reload" + ``` + + We now have everything we need to configure our Plex Reverse Proxy: 3. Configure nginx -``` -cd /etc/nginx/sites-enabled -wget -O plex.conf https://raw.githubusercontent.com/toomuchio/plex-nginx-reverseproxy/master/nginx.conf -``` + ``` + cd /etc/nginx/sites-enabled + wget -O plex.conf https://raw.githubusercontent.com/toomuchio/plex-nginx-reverseproxy/master/nginx.conf + ``` + + Now we must alter the file to include our failover IP, ssl certificates and dhparam. + + ``` + nano plex.conf + ``` -Now we must alter the file to include our failover IP, ssl certificates and dhparam. + Find: -``` -nano plex.conf -``` -Find: + ``` + server_name + ``` -``` -server_name -``` + and replace plex.EXAMPLE.COM with your own hostname -and replace plex.EXAMPLE.COM with your own hostname + Then find: -Then find: + ``` + ssl_certificate + ssl_certificate_key + ``` -``` -ssl_certificate -ssl_certificate_key -``` -Insert your letsencrypt certificates here: + Insert your letsencrypt certificates here: -``` -ssl_certificate /etc/nginx/ssl/{YOUR HOSTNAME}/fullchain.pem; -ssl_certificate_key /etc/nginx/ssl/{YOUR HOSTNAME}/key.pem; -``` + ``` + ssl_certificate /etc/nginx/ssl/{YOUR HOSTNAME}/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/{YOUR HOSTNAME}/key.pem; + ``` -Now add our trusted certificate (chain.pem): + Now add our trusted certificate (chain.pem): -``` -ssl_trusted_certificate /etc/nginx/ssl/{YOUR HOSTNAME}/chain.pem; -``` + ``` + ssl_trusted_certificate /etc/nginx/ssl/{YOUR HOSTNAME}/chain.pem; + ``` -And the dhparam already generated on a default swizzin install a bit further down: + And the dhparam already generated on a default swizzin install a bit further down: -``` -ssl_dhparam /etc/nginx/ssl/dhparam.pem; -``` + ``` + ssl_dhparam /etc/nginx/ssl/dhparam.pem; + ``` -That’s all the edits we need to make to this file so save and exit. Test your config and cross your fingers! + That’s all the edits we need to make to this file so save and exit. Test your config and cross your fingers! -``` -nginx -t -``` + ``` + nginx -t + ``` -If all goes well, reload your server configuration + If all goes well, reload your server configuration -``` -systemctl reload nginx -``` + ``` + systemctl reload nginx + ``` -Now your Plex should be accessible via https://plex.yourdomain.com + Now your Plex should be accessible via 4. Alter your Plex Server settings -Make sure “Show Advanced Settings” is on. Under the Network tab add a custom access url: + Make sure “Show Advanced Settings” is on. Under the Network tab add a custom access url: -``` -http://plex.yourdomain.com:80,https://plex.yourdomain.com:443 -``` + ``` + http://plex.yourdomain.com:80,https://plex.yourdomain.com:443 + ``` -Under Remote Access, disable remote access + Under Remote Access, disable remote access 5. Update firewall to prevent external pinging of port 32400 -``` -iptables -A INPUT -p tcp -s localhost --dport 32400 -j ACCEPT -iptables -A INPUT -p tcp --dport 32400 -j DROP -``` + ``` + iptables -A INPUT -p tcp -s localhost --dport 32400 -j ACCEPT + iptables -A INPUT -p tcp --dport 32400 -j DROP + ``` -The first rule ensures our localhost is still able to talk with Plex. This allows our proxy to communicate, with the internal server, but the second rule prevents all other access. As such, you should still be able to access your plex installation from both plex.tv/web/app and plex.yourdomain.com. Confirm you are able to, then once you have, ensure these rules stay persistent upon a reboot with iptables-persistent: + The first rule ensures our localhost is still able to talk with Plex. This allows our proxy to communicate, with the internal server, but the second rule prevents all other access. As such, you should still be able to access your plex installation from both plex.tv/web/app and plex.yourdomain.com. Confirm you are able to, then once you have, ensure these rules stay persistent upon a reboot with iptables-persistent: -``` -apt install iptables-persistent -``` + ``` + apt install iptables-persistent + ``` -Choose yes during installation to save your current iptables (note if you have any fail2ban rules, they may get included in here. Make sure you have no firewall rules you don’t want to save, though you can remove unintentional additions if needed. + Choose yes during installation to save your current iptables (note if you have any fail2ban rules, they may get included in here. Make sure you have no firewall rules you don’t want to save, though you can remove unintentional additions if needed. -At this point, no data should be served from your server via port 32400 and all traffic should flow exclusively through port 443 (you can verify this with tcptrack – your server will not establish connections via port 32400 during playback though it will try- SYN_CONNECT). + At this point, no data should be served from your server via port 32400 and all traffic should flow exclusively through port 443 (you can verify this with tcptrack – your server will not establish connections via port 32400 during playback though it will try- SYN_CONNECT). 6. Test and enjoy! -Please note this may not be perfect – I will do my best to answer questions and update and errors in the guide. Please let me know if you run into issues! + Please note this may not be perfect – I will do my best to answer questions and update and errors in the guide. Please let me know if you run into issues! -If you’re worried about sending all of your data through cloudflare, the same basic principle could apply to a VPS such as Linode, Vultr or other. \ No newline at end of file + If you’re worried about sending all of your data through cloudflare, the same basic principle could apply to a VPS such as Linode, Vultr or other. diff --git a/docs/guides/dist-upgrade.md b/docs/guides/dist-upgrade.md index e80d1e927..24beee698 100644 --- a/docs/guides/dist-upgrade.md +++ b/docs/guides/dist-upgrade.md @@ -45,15 +45,17 @@ The absolute best time to perform an upgrade is **before you install swizzin**; swizzin currently supports these distributions: Debian: + - Buster (oldoldstable) - Bullseye (oldstable) - Bookworm Ubuntu: + - Focal (20.04 LTS) - Jammy (22.04 LTS) -Before updating anything, please ensure you're on the latest commit. If you are not, things could not work as intended after you're done the distribution upgrade. +Before updating anything, please ensure you're on the latest commit. If you are not, things could not work as intended after you're done the distribution upgrade. ```bash sudo box update @@ -67,10 +69,12 @@ WARN is not supported by swizzin at this stage. ``` Then, assuming swizzin has released support for your upgrade path, you'll need to manually pull down the latest version of the swizzin master branch: + ``` cd /etc/swizzin git pull ``` + ::: If you don't know the OS or version you're running, you can determine it here with the command `lsb_release -a`. Your `codename` will hopefully correspond to a value above. The codename is the release that's in your current apt sources list (`/etc/apt/sources.list`). We will be changing this to the version you'd like to upgrade to. @@ -120,7 +124,6 @@ Pray to your lucky stars that nothing goes wrong and your server comes back up w If you haven't installed swizzin yet, feel free to start the installer now. If you have already installed packages, we have a bit more updating to do. - ### Updating packages after an upgrade A few things are known to be broken after a `dist-upgrade` and will need to be fixed. Major breakers typically include things like php version upgrades and library upgrades (like openSSL), which packages (such as rtorrent) are compiled against. @@ -174,5 +177,3 @@ Depending on the application and the amount of configuration you have done, it m #### Other packages Distribution upgrades haven't been tested rigorously. It's entirely possible other packages may have broken during the upgrade. You'll need to start doing your own troubleshooting here if anything else is broken. You can consult [the Troubleshooting guide](/guides/troubleshooting) for a quick start. You can find out if any of your systemd services are failing to start with `systemctl list-units --failed`. If there are failed units there, you can start debugging with `systemctl status `. However, you're on your own from here. - - diff --git a/docs/guides/migrating.md b/docs/guides/migrating.md index 61e2028d0..3c2b98cbd 100644 --- a/docs/guides/migrating.md +++ b/docs/guides/migrating.md @@ -9,17 +9,22 @@ This guide should be used as a generic reference for when you wanna get onto a n This is still a WIP guide, any experience or suggestions are welcome. If things go wrong, don't blame me. Make sure to always have a backup with a verification plan before doing something stoopet. ::: - ## 1. Update everything on old server + ### Server itself + Do a full `apt update && apt upgrade` run + ### Swizzin source code -`sudo box update` before + +`sudo box update` before ### Any other applications + `sudo box upgrade` any other application remaining ### (Optional) De-dupe your stuff + If you want to make sure you aren't transferring some files that are 100% carbon copies over, you can run `fdupes` to hardlink any file that matches another on the same disk 100%. **Make sure you know what you are doing before getting into this, it could lead to some pretty dumb mistakes** @@ -28,7 +33,7 @@ I highly suggest only running this for a set of files that you know belong to on After you install `fdupes`, you can run this command which will ensure that all the files within these directories of the logged in user are hardlinked, and only take up the space of one instance of the file on a disk. -This obviously will not work if these directories mount over multiple disks, they all have to be on the same disk for this to work. +This obviously will not work if these directories mount over multiple disks, they all have to be on the same disk for this to work. ```bash fdupes -r ~/sonarr/ ~/radarr/ ~/transmission/ ~/torrents/rtorrent -n -L @@ -43,17 +48,21 @@ Install the latest version of your OS so that you don't have to do a dist upgrad Ensure that your drives are set up just the way you want them _before_ doing _anything_. Swizzin relies on `/root` and `/home` a lot so just mount everything how you want to, and swizzin will just blindly follow that filesystem to wherever it leads to. ### Swizzin + Run the script, maybe check out the advanced options while you're at it so that you can set it and forget it. #### Users + Create all your users with **the same usernames and passwords**. If you want to change passwords for the users, you'll have to do that after the installation #### Apps + Install the same apps you got on your old system. Make sure to shut them down after you're done installing them so that the configs and everything will not get overwritten after you transfer your stuff. ## 3. Spin down apps on old server + You **absolutely** need to stop everything that's happening on the old server. Otherwise you'll be transferring data that might be written into, which is no bueno. You might as well reboot your system into rescue, `mount` and `chroot` your old setup in, and start an SSH server. @@ -73,6 +82,7 @@ rsync -ahH --info=progress2 -e'ssh -p $portNumber' root@oldserver:/home/.transmission.conf` files from `/etc/nginx/conf.d/` after all users are created and transmission is installed. - Deluge - - Generally same as transmission + - Generally same as transmission - qbittorrent - - After all data is transferred, run `box upgrade nginx` and login normally. - - If migrating between two servers on which different versions of qbittorrent are installed, check that the two instances are using the same data directory. Some versions may use `~/.local/share/data/qBittorrent` while others may use `~/.local/share/qBittorrent`. Make sure that the data is transferred into the correct data directory. + - After all data is transferred, run `box upgrade nginx` and login normally. + - If migrating between two servers on which different versions of qbittorrent are installed, check that the two instances are using the same data directory. Some versions may use `~/.local/share/data/qBittorrent` while others may use `~/.local/share/qBittorrent`. Make sure that the data is transferred into the correct data directory. - R**u**Torrent - - Reinstall rutorrent after all data is moved - - Nothing specific should be necessary to do for rtorrent itself. + - Reinstall rutorrent after all data is moved + - Nothing specific should be necessary to do for rtorrent itself. - Plex - - More in [this guide](https://support.plex.tv/articles/201370363-move-an-install-to-another-system/) and in [this guide specifically for Linux](https://forums.plex.tv/t/pms-migration-linux/678445/2) + - More in [this guide](https://support.plex.tv/articles/201370363-move-an-install-to-another-system/) and in [this guide specifically for Linux](https://forums.plex.tv/t/pms-migration-linux/678445/2) - ombi - - More [here](https://github.com/Ombi-app/Ombi/wiki/Backups) or [here](https://docs.ombi.app/info/backing-up/) + - More [here](https://github.com/Ombi-app/Ombi/wiki/Backups) or [here](https://docs.ombi.app/info/backing-up/) - tautulli - - More [here](https://github.com/Tautulli/Tautulli/wiki/Frequently-Asked-Questions#q-i-need-to-movereinstall-tautulli-can-i-keep-my-history-and-statistics) + - More [here](https://github.com/Tautulli/Tautulli/wiki/Frequently-Asked-Questions#q-i-need-to-movereinstall-tautulli-can-i-keep-my-history-and-statistics) - Lounge IRC - - Last time I asked, I was told this:\ + - Last time I asked, I was told this:\ `[19:51:21] xnaas: just move your entire thelounge folder over flying_sausages; that's it`\ So make sure to install lounge via `box`, stop teh service, and then transfer over the files from `/home/thelounge` to `/home/thelounge` - znc - - More [here](https://wiki.znc.in/FAQ#How_do_I_migrate_ZNC_from_one_machine_to_another.3F) + - More [here](https://wiki.znc.in/FAQ#How_do_I_migrate_ZNC_from_one_machine_to_another.3F) - nextcloud - - Loosely follow [this guide](https://docs.nextcloud.com/server/21/admin_manual/maintenance/migrating.html) but make sure to check in with us in the discord because I don't have time to write all the differences right now + - Loosely follow [this guide](https://docs.nextcloud.com/server/21/admin_manual/maintenance/migrating.html) but make sure to check in with us in the discord because I don't have time to write all the differences right now - letsencrypt - - Install before and also after just for good measure + - Install before and also after just for good measure - organizr - - Shut down nginx on old server, then transfer the `config.php` and `users.db` files in `/srv/organizr` and its db folder + - Shut down nginx on old server, then transfer the `config.php` and `users.db` files in `/srv/organizr` and its db folder - quota - quassel - rclone - mango - Flood - _... and probably a couple more ..._ - diff --git a/docs/guides/troubleshooting.md b/docs/guides/troubleshooting.md index e3812e51d..c1c3b4247 100644 --- a/docs/guides/troubleshooting.md +++ b/docs/guides/troubleshooting.md @@ -26,7 +26,7 @@ If you do find your problem, you can subscribe to those issues to get updates wh ## Logs -### Accessing swizzin/`box` logs +### Accessing swizzin/`box` logs Swizzin stores its logs into the `/root/logs` directories. The installer installs into `install.log`, and any other command you run with `box` will end up in `swizzin.log`. You can access the logs by running the following commands. @@ -40,7 +40,9 @@ sudo less -r +G /root/logs/swizzin.log Please consult these logs for any errors or other bad-sounding messages before continuing. ### "Verbose" `box` output + If you would like to see "verbose" output of the box command, you can run the following command before any `box` function. This will print all the information stored into the log into your current terminal session as well. + ```bash # to start the verbose output tail -f /root/logs/swizzin.log & @@ -54,23 +56,25 @@ kill %1 #Assuming that the tail is the only background job in the shell, otherwi ### Checking the system logs You can always check the logs of the system as a whole by running the following command. + ```bash sudo journalctl -xe ``` + You can use your arrow keys o navigate up down left and right. Please consult the manpage of `less` for more handy features like search and others. You can also open the last `syslog` file which often has useful information. You can do that by running the following command. + ```bash sudo less +G /var/log/syslog ``` + You can always filter the output of the `less` command by typing `&`, followed by your filter pattern. -There are many other log files available under the `/var/log` directory which are often a very large trove of information. Please see if any of the other log files might have any relevant information +There are many other log files available under the `/var/log` directory which are often a very large trove of information. Please see if any of the other log files might have any relevant information - - ## Sharing logs and output You can always share large logs using termbin straight from your terminal. @@ -81,28 +85,29 @@ Want to show us your swizzin logs? ```bash sudo cat /root/logs/swizzin.log | nc 9999 -``` +``` Below is an example for sharing the content of your syslog. ```bash cat /var/log/syslog | nc 9999 -``` +``` Or if you want to share a unit's systemd logs ```bash journalctl -u panel | nc 9999 -``` +``` Nginx failing and you don't know why? ```bash sudo nginx -T | nc 9999 -``` +``` ### Where to find logs -Logs are all over the system. Below are just a couple ways to find some things that might be relevant. + +Logs are all over the system. Below are just a couple ways to find some things that might be relevant. - Issues with `box` - `sudo tail -200 /root/logs/swizzin.log` @@ -138,13 +143,13 @@ If your machine is not accessible, see if it is online, and the networking is se ### I'm getting a `502` when accessing the server + The most likely scenario is that the application you're trying to access is not responding. `nginx` is running just fine but it just does not know who to talk to at the end, and so it comes back with empty hands and throws a `502`. You should [check the status of the app](#checking-if-an-application-is-running) which you're trying to access. Remember, if you're accessing the server's dashboard itself, you're trying to actually access the [panel](/applications/panel.mdx) application. Unless you have custom configurations you want to keep, an easy way to fix a lot of issues is to `box remove panel && box install panel` - ### Checking NGINX configuration @@ -163,18 +168,21 @@ sudo nginx -T ``` If any changes have been done recently, you can always trigger a reload of the nginx configuration by running the following command + ```bash sudo nginx -s reload # or alternatively sudo systemctl reload nginx ``` - ### Troubleshooting failed SSH + You can always determine what is causing your SSH connectivity issues by running the following command. + ```bash ssh -v ``` + You can add the amount of `v`s to increase the level of verbosity. _Pro-tip: You can quickly kill an unresponsive SSH session by hitting `ENTER ~ .` in that order._ @@ -186,6 +194,7 @@ _Pro-tip: You can quickly kill an unresponsive SSH session by hitting `ENTER ~ . Most applications installed through swizzin have a `systemd` unit available. This allows you to control the applications as services through the `systemctl` interface. You can always check the current status of an app by running the command under. This will return the whether the application is Active or not, and some of the latest log messages coming from it. It is always a good idea to read those. + ```bash sudo systemctl status ``` @@ -193,6 +202,7 @@ sudo systemctl status Please refer to your application's docs page to see if there are any deviations to this, such as per-user configuration. ### Identifying failed services + You can quickly get an overview of which services have had a problem and are currently nor running by executing the following command. ```bash @@ -212,6 +222,7 @@ A good start to do that would be to inspect the output of the following command, ```bash sudo systemctl cat ``` + The command above will produce output like the one under. This is an example output of `sudo systemctl cat transmission@`. ```systemd @@ -238,20 +249,25 @@ You can therefore switch your user (by running `sudo su `) and execute the Please consult the manpage or `--help` page of the application you are about to run before you do it, to understand what some of the options might mean. ## Home-lab connectivity + Issues in this area usually stem from not setting up port-forwarding correctly on your router, or not setting a static IP right. ### Resources for setting static IP on Debian/Ubuntu + - [Configuring static addresses on Debian/Ubuntu](https://www.cyberciti.biz/faq/linux-configure-a-static-ip-address-tutorial/) ### Resources for setting a static IP on your router + - [Ensuring your router will hand out he right IP to your system](https://www.howtogeek.com/184310/ask-htg-should-i-be-setting-static-ip-addresses-on-my-router/) ### Resources for port-forwarding on router's + - [Guides for forwarding ports on multiple routers](https://portforward.com/router.htm) - [Generic port forwarding guide](https://www.howtogeek.com/66214/how-to-forward-ports-on-your-router/) - [Tool to check if ports are open](http://www.portchecktool.com/) **Please ensure to forward the following ports:** + - 22 (Or your custom SSH/SFTP port) - 80 (HTTP) - 443 (HTTPS) @@ -261,11 +277,12 @@ You might additionally forward/open the ports for your torrent clients, FTP or o Consider using a Dynamic DNS (DDNS) provider like the swizzin-available [Duck DNS](/applications/duckdns) for your home IP to gain a free domain that can be used for something such as letsencrypt. ## Starting from scratch + We generally advise against this scenario as you lose the opportunity to learn from the mistakes that happened somewhere along the line. This experience can help you save time in the future and restore the functionality of the system in case it goes very awry on your own. **Please attempt the steps above first before nuking the system. We will happily guide you through the process on Discord if you're up for it.** There is currently no convenient way to uninstall the entire swizzin suite and return all files and settings to their byte-for-byte original state. You can, however, attempt to remove all the treaces it can leave on your system in order to be able to re-staret without trying to lose everything. -If you are having problems with a specific application, we advise to re-install that application first, and if necessary the underlying dependencies (these could be `nginx`, `rtorrent`, or others depending on the application). +If you are having problems with a specific application, we advise to re-install that application first, and if necessary the underlying dependencies (these could be `nginx`, `rtorrent`, or others depending on the application). Remember to also remove any additional users you created. You can also attempt to remove swizzin by removing every app you have installed through it as well as any loose configuration files and directories that belong to it; and then removing the following files and directories recursively. diff --git a/docs/scripts/rtx.md b/docs/scripts/rtx.md index a6ad4e415..6482d9943 100644 --- a/docs/scripts/rtx.md +++ b/docs/scripts/rtx.md @@ -10,4 +10,4 @@ You can invoke it by running `box rtx` as root, or after `sudo`. You will then have a whiptail-based, interactive quasi-UI through which you can both install and remove additions which will be available to **all** users which use RuTorrent. -![Rtx in action](https://i.imgur.com/qFzAfvv.gif) \ No newline at end of file +![Rtx in action](https://i.imgur.com/qFzAfvv.gif) diff --git a/docs/scripts/setdisk.md b/docs/scripts/setdisk.md index 52e516105..49c7c54b0 100644 --- a/docs/scripts/setdisk.md +++ b/docs/scripts/setdisk.md @@ -10,21 +10,22 @@ It is run during the `box adduser` command as well. By default, the master user does not have a quota set which can result in odd UI behavior. You can use this command to rectify such issues. Please consider if you truly need the quota functionality if you are the sole user of a machine. -## Format for the size. +## Format for the size You can specify the format in one of the following formats: + - Specific size - - Available units are MBs, GBs and TBs. - - This format does not allow for decimals, therefore only `12GB`, `123456MB` or etc. will work; not `12.3GB`, `1.45TB` etc. + - Available units are MBs, GBs and TBs. + - This format does not allow for decimals, therefore only `12GB`, `123456MB` or etc. will work; not `12.3GB`, `1.45TB` etc. - Maximum - - This will retrieve the disk that quotas are set on, and set the maximum. - - **Please note the following caveats**: - - This size can be slightly larger than what the disk can actually store due to how partitioning works. - - The "Available" is purely a subtraction of the user's used space minus the quota, therefore it does not take into account space used by anything else other than the user. + - This will retrieve the disk that quotas are set on, and set the maximum. + - **Please note the following caveats**: + - This size can be slightly larger than what the disk can actually store due to how partitioning works. + - The "Available" is purely a subtraction of the user's used space minus the quota, therefore it does not take into account space used by anything else other than the user. ## Running interactively -You can run `sudo setdisk` and specify the user and size interactively on the command line. +You can run `sudo setdisk` and specify the user and size interactively on the command line. ## Running with parameters @@ -35,4 +36,4 @@ You can run `sudo setdisk` and specify the user and size interactively on the co sudo setdisk user1 #Set size as parameter sudo setdisk user1 20GB -``` \ No newline at end of file +``` diff --git a/docs/snippets/installoptswarning.md b/docs/snippets/installoptswarning.md index 922185309..d6bbffbc2 100644 --- a/docs/snippets/installoptswarning.md +++ b/docs/snippets/installoptswarning.md @@ -8,6 +8,6 @@ None of the options are sanity-checked on install so setting something wrong cou Again, you do not need to set these if you don't know what you're doing. ::: -There are a couple options you can set **before** installing transmission through export. +There are a couple options you can set **before** installing transmission through export. -If you'd like to use one of these, run `export option=value` **before** running the install command. \ No newline at end of file +If you'd like to use one of these, run `export option=value` **before** running the install command. diff --git a/docs/snippets/missingdocs.md b/docs/snippets/missingdocs.md index 1c3c1928f..a92a19de9 100644 --- a/docs/snippets/missingdocs.md +++ b/docs/snippets/missingdocs.md @@ -1,3 +1,3 @@ :::caution Not a 404, but almost The docs for this application are not properly written yet. If you need them, please let us know in the [Discord](https://discord.gg/sKjs9UM) and we'll take the time to make them for you. -::: \ No newline at end of file +::: diff --git a/docs/snippets/troubleshooting.md b/docs/snippets/troubleshooting.md index d32e0c740..c26095c26 100644 --- a/docs/snippets/troubleshooting.md +++ b/docs/snippets/troubleshooting.md @@ -1,3 +1,3 @@ -:::tip +:::tip You can always also try the [general troubleshooting tips written in our guide](/guides/troubleshooting). They might or might not apply, but asking these questions can often make you understand what is under the hood better and help you find what needs to be fixed. It's always worth a shot! -::: \ No newline at end of file +:::