From fb0b224807a82420c0b5e4b642e74ab2cc1d5afb Mon Sep 17 00:00:00 2001 From: Henrik Soerensen Date: Thu, 1 Feb 2024 16:07:52 -0500 Subject: [PATCH] Improve documentation by adding mkdocs material, as well as guide on how to setup one specific notification mechanism (#21) --- .github/workflows/publish_mkdocs.yml | 28 ++ .gitignore | 3 +- .markdownlint.json | 5 +- README.md | 263 ++---------------- .../Voi_Logo_Purple_on_White_Background.png | Bin 0 -> 23156 bytes .../Voi_Logo_White_on_Purple_Background.png | Bin 0 -> 24004 bytes docs/assets/favicon.ico | Bin 0 -> 40895 bytes docs/cli-tools.md | 95 +++++++ docs/index.md | 32 +++ docs/installation/installation.md | 50 ++++ docs/installation/prerequisites.md | 16 ++ docs/installation/uninstall.md | 27 ++ docs/notification-guides/pushbullet.md | 64 +++++ docs/operating/participation-keys.md | 16 ++ docs/operating/running-your-node.md | 19 ++ docs/operating/setup-notifications.md | 58 ++++ docs/stylesheets/extra.css | 5 + docs/troubleshooting.md | 33 +++ docs/updating/swarm-update.md | 10 + docs/updating/telemetry.md | 9 + mkdocs.yml | 97 +++++++ 21 files changed, 582 insertions(+), 248 deletions(-) create mode 100644 .github/workflows/publish_mkdocs.yml create mode 100644 docs/assets/Voi_Logo_Purple_on_White_Background.png create mode 100644 docs/assets/Voi_Logo_White_on_Purple_Background.png create mode 100644 docs/assets/favicon.ico create mode 100644 docs/cli-tools.md create mode 100644 docs/index.md create mode 100644 docs/installation/installation.md create mode 100644 docs/installation/prerequisites.md create mode 100644 docs/installation/uninstall.md create mode 100644 docs/notification-guides/pushbullet.md create mode 100644 docs/operating/participation-keys.md create mode 100644 docs/operating/running-your-node.md create mode 100644 docs/operating/setup-notifications.md create mode 100644 docs/stylesheets/extra.css create mode 100644 docs/troubleshooting.md create mode 100644 docs/updating/swarm-update.md create mode 100644 docs/updating/telemetry.md create mode 100644 mkdocs.yml diff --git a/.github/workflows/publish_mkdocs.yml b/.github/workflows/publish_mkdocs.yml new file mode 100644 index 0000000..d72ffad --- /dev/null +++ b/.github/workflows/publish_mkdocs.yml @@ -0,0 +1,28 @@ +name: Publish mkdocs to gh-pages +on: + push: + branches: + - main +permissions: + contents: write +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v4 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install mkdocs-material + - run: mkdocs gh-deploy --force diff --git a/.gitignore b/.gitignore index e525806..0201b46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -./.idea/**/* +/.idea +/site /docker/notification.yml diff --git a/.markdownlint.json b/.markdownlint.json index 816c57f..590746e 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,5 +1,8 @@ { "MD013": { - "line_length": 120 + "line_length": 256 + }, + "MD033": { + "allowed_elements": ["img"] } } diff --git a/README.md b/README.md index 8466427..68973b0 100644 --- a/README.md +++ b/README.md @@ -1,257 +1,28 @@ -# Voi Swarm Participation Node Setup +# Voi Swarm -## Prerequisites +## About -- `curl` -- `apt-get` +This repository contains the installation script and configuration files for setting up a Voi participation node on a +Linux system. -If any package is not available on your system, or if you do not have permission to use said package, follow operating -system guidance on installation and setup. +Success criteria for the installation script are: -## Supported Operating Systems and Compute Platforms +> 1. Offer easy ways for users to operate and maintain their nodes as healthy participants in the Voi network. +> 2. Provide a simple and easy way to onboard new participants. +> 3. The package should be as cheap as possible to run for individual participants. -### Operating Systems +To achieve the above the package is an opinionated way to join the network, and may thus not be suitable for +all use cases. -- Debian -- Ubuntu +## Documentation -### Compute Platforms +Documentation can be found on [https://voinetwork.github.io/voi-swarm/](https://voinetwork.github.io/voi-swarm/) -- arm64 -- amd64 (x86_64) +## Contributing -## New to Voi +Contributions are welcome! Please join the [Voi Network Discord server](https://discord.com/invite/vnFbrJrHeW) to discuss +with other community members and contributors. You can also open an issue or a pull request on GitHub. -To set up a new Voi node, run the following command: +## License -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" -``` - -## Using an Existing Account/Address with Mnemonic - -If you have an existing account/address with a mnemonic that you want to use, set the VOINETWORK_IMPORT_ACCOUNT -environment variable to 1 and run the installation script: - -```bash -export VOINETWORK_IMPORT_ACCOUNT=1 -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" -``` - -## Installing Without Wallet Setup - -If you want to install without including wallet setup, set the VOINETWORK_SKIP_WALLET_SETUP environment variable to 1 -and run the installation script: - -```bash -export VOINETWORK_SKIP_WALLET_SETUP=1 -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" -``` - -## Updating Your Participation Key - -If your Voi node's participation key is nearing its expiry date (less than 14 days left), you can renew it by running -the installation script again. This script is programmed to create new participation keys when the current ones are -close to expiring. So, to keep your Voi node active, make sure your participation key is up-to-date. If it's about to -expire, rerun the installation script to generate a new key. - -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" -``` - -## Setting up Participation Key Expiry Notifications (Recommended) - -Each online account has a participation key that needs to be valid for the account to participate in the Voi network. -A participation key is valid for a certain number of rounds, which is approximately 14 days. When the participation key -expires the node runner will no longer be able to propose or vote on blocks. To avoid this situation you need to renew -the participation key before expiration. - -To receive a notification when the participation key is about to expire, you can do the following: - -### Copy the Example File - -Start by copying the example notification.yml file to the voi/docker directory: - -`cp ~/voi/docker/notification.yml.example ~/voi/docker/notification.yml` - -### Update the notification.yml File - -Update the notification.yml file with your preferred notification mechanism by updating the NOTIFICATION_URLS -environment variable. The notification mechanism can be a webhook, email, push, or any other notification mechanism that -is available via [Apprise notifications](https://github.com/caronc/apprise?tab=readme-ov-file#supported-notifications) - -If you want to use multiple mechanisms, separate them with a comma. For example, to use both Discord and Pushbullet for -notification, you would set the `NOTIFICATION_URLS` value in the `notification.yml` file to: - -```yaml -NOTIFICATION_URLS="discord:///,pushbullet://" -``` - -### Updating Notification Schedule - -To modify the notification schedule, adjust the `- swarm.cronjob.schedule=0 16 * * *` label in the copied example file. -This is by default set to run daily at 4 PM UTC. Adjust this to your preferred time, accounting for your -timezone's UTC offset. Use a resource like [dateful.com](https://dateful.com/time-zone-converter) for timezone conversion. - -The format of the schedule is following the standard [cronjob format](https://en.wikipedia.org/wiki/Cron#Overview). - -### Applying Notification Configuration to the Stack - -To apply your notification configuration to the stack, rerun the installation script: - -```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" -``` - -### Testing Your Notification Configuration - -To test your notification configuration, you can manually trigger the notification service by running the following command: - -```bash -~/voi/bin/notification-test -``` - -## Setting a Custom Telemetry Name - -To set a custom telemetry name, set the VOINETWORK_TELEMETRY_NAME environment variable to your desired name: - -```bash -export VOINETWORK_TELEMETRY_NAME="my_custom_telemetry_name" -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" -``` - -Custom telemetry name can be combined with other environment variables. - -## Uninstalling - -To uninstall, execute the following commands: - -- Leave the Swarm with `docker swarm leave --force` -- Remove the `voi` directory with `rm -rf /voi/` -- Remove the `data` directory with `sudo rm -rf /var/lib/voi` - -## Useful Scripts - -This section provides a collection of useful scripts for managing your Voi participation node. These scripts are -designed to be executed within a running Docker container. They closely follow the commands outlined in the -[D13 guide](https://d13.co/posts/set-up-voi-participation-node/) for setting up a Voi participation node under Ubuntu 22.04. - -### Creating a Node Wallet - -Create a new wallet with the following command: - -```bash -~/voi/bin/create-wallet -``` - -### Creating an Account - -Create a new account with the following command: - -```bash -~/voi/bin/create-account -``` - -### Retrieving Account Mnemonic - -Retrieve the mnemonic of an existing account with the following command: - -```bash -~/voi/bin/get-account-mnemonic -``` - -### Importing an Account - -Import an existing account with the following command: - -```bash -~/voi/bin/import-account -``` - -### Generating Participation Key - -Generate a participation key for an existing account with the following command: - -```bash -~/voi/bin/generate-participation-key -``` - -### Checking Participation Status - -Check the participation status of an existing account with the following command: - -```bash -~/voi/bin/get-participation-status -``` - -### Going Online - -Bring an existing account online with the following command: - -```bash -~/voi/bin/go-online -``` - -### Going Offline - -Take an existing account offline with the following command: - -```bash -~/voi/bin/go-offline -``` - -### Executing Goal Commands - -Execute goal commands with the following command: - -```bash -~/voi/bin/goal -``` - -### Opening a Bash Shell in the AVM Container - -Open a bash shell in the AVM container with the following command: - -```bash -~/voi/bin/start-shell -``` - -### Getting Basic Node Health - -To retrieve basic health information about your node, execute the following command: - -```bash -~/voi/bin/get-node-status -``` - -The `get-node-status` command performs checks using: - -- `goal node status` to connect to the running daemon and retrieve basic node information -- `/health`: This API endpoint checks the reported health of the node. [REST API /health documentation](https://developer.algorand.org/docs/rest-apis/algod/#get-health). -- `/ready`: This API endpoint checks the reported readiness of the node and if fully caught up. [REST API /ready documentation](https://developer.algorand.org/docs/rest-apis/algod/#get-ready). - -### Testing Notifications - -To test notifications execute the following command: - -```bash -~/voi/bin/notification-test -``` - -## Debugging - -### Startup state for services in stack - -`docker stack ps --no-trunc voinetwork` - -### Replication state for services in stack - -`docker service ls` - -### Pull log files - -`docker service logs voinetwork_algod` - -### Inspect service - -`docker inspect voinetwork_algod` +AGPL-3.0. See [LICENSE](LICENSE) for more information. diff --git a/docs/assets/Voi_Logo_Purple_on_White_Background.png b/docs/assets/Voi_Logo_Purple_on_White_Background.png new file mode 100644 index 0000000000000000000000000000000000000000..376bfbb8c61fd9382700f0523a051d66b85de2d9 GIT binary patch literal 23156 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 Tc$X+(=QT%cPaH0`IUoHWv*~l; literal 0 HcmV?d00001 diff --git a/docs/assets/Voi_Logo_White_on_Purple_Background.png b/docs/assets/Voi_Logo_White_on_Purple_Background.png new file mode 100644 index 0000000000000000000000000000000000000000..c40e1293c441051e20f54492eebae57a66b2d427 GIT binary patch literal 24004 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 LnO!U~xOMmcfN&K& literal 0 HcmV?d00001 diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..13944c7e5d369f9079e490608293b921493e6f7e GIT binary patch literal 40895 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 +``` + +## Creating an Account + +Create a new account with the following command: + +```bash +~/voi/bin/create-account +``` + +### Retrieving Account Mnemonic + +Retrieve the mnemonic of an existing account with the following command: + +```bash +~/voi/bin/get-account-mnemonic +``` + +### Importing an Account + +Import an existing account with the following command: + +```bash +~/voi/bin/import-account +``` + +### Generating Participation Key + +Generate a participation key for an existing account with the following command: + +```bash +~/voi/bin/generate-participation-key +``` + +### Checking Participation Status + +Check the participation status of an existing account with the following command: + +```bash +~/voi/bin/get-participation-status +``` + +### Going Online + +Bring an existing account online with the following command: + +```bash +~/voi/bin/go-online +``` + +### Going Offline + +Take an existing account offline with the following command: + +```bash +~/voi/bin/go-offline +``` + +### Executing Goal Commands + +Execute goal commands with the following command: + +```bash +~/voi/bin/goal +``` + +### Opening a Bash Shell in the AVM Container + +Open a bash shell in the AVM container with the following command: + +```bash +~/voi/bin/start-shell +``` + +### Getting Basic Node Health + +To retrieve basic health information about your node, execute the following command: + +```bash +~/voi/bin/get-node-status +``` + +The `get-node-status` command performs checks using: + +- `goal node status` to connect to the running daemon and retrieve basic node information +- `/health`: This API endpoint checks the reported health of the node. [REST API /health documentation](https://developer.algorand.org/docs/rest-apis/algod/#get-health). +- `/ready`: This API endpoint checks the reported readiness of the node and if fully caught up. [REST API /ready documentation](https://developer.algorand.org/docs/rest-apis/algod/#get-ready). diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..ee3eb7b --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +# Home + +swarm-cronjob + +--- + +## What is Voi Swarm? + +Voi Swarm is an opinionated set of scripts and configurations that allows a user to easily to join the Voi n etwork as +a participant . + +Tenets for the Voi Swarm package are: + +> 1. Offer easy ways for users to operate and maintain their nodes as healthy participants in the Voi network. +> 2. Provide a simple and easy way to onboard new participants. +> 3. The package should be as cheap as possible to run for individual participants. + +To achieve the above the package is an opinionated way to join the network, and may thus not be suitable for +all use cases. + +## Features + +- **Effortless Installation**: Deploy a Voi node on Linux with a single command. +- **Rapid Deployment**: Built for swift setup and onboarding. +- **Automatic Updates**: Seamless application of Docker image updates. +- **Health Monitoring**: System auto-restarts the node if needed. +- **Optional Notification**: Get notified when actions are required. +- **Economical**: Supports arm64 and amd64 (x86_64). + +## License + +This project is licensed under AGPL-3.0. diff --git a/docs/installation/installation.md b/docs/installation/installation.md new file mode 100644 index 0000000..0ced605 --- /dev/null +++ b/docs/installation/installation.md @@ -0,0 +1,50 @@ +# Setting up a new Voi Node + +## New to Voi + +!!! tip + Start here if you are new to Voi and want to set up a new Voi node. + During the process you will be asked for a few details to set up your node, and where we have automated as much as possible. + +To set up a new Voi node, run the following command: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +## Using an Existing Account/Address with Mnemonic + +If you have an existing account/address with a mnemonic that you want to use, set the **VOINETWORK_IMPORT_ACCOUNT** +environment variable to **1** and run the installation script: + +```bash +export VOINETWORK_IMPORT_ACCOUNT=1 +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +## Installing Without Wallet Setup + +If you want to install without including wallet setup, set the **VOINETWORK_SKIP_WALLET_SETUP** environment variable to +**1** and run the installation script: + +```bash +export VOINETWORK_SKIP_WALLET_SETUP=1 +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +## Setting a Custom Telemetry Name as part of installation (advanced) + +!!! info + This is an advanced feature and is not required to have telemetry configured. + +During installation, you will be prompted to set a custom telemetry name, if however you prefer to set a name through +the environment you can do so by setting the **VOINETWORK_TELEMETRY_NAME** environment variable to your desired name. + +This would typically be done if you are automating the installation process. + +```bash +export VOINETWORK_TELEMETRY_NAME="my_custom_telemetry_name" +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +A custom telemetry name can be combined with other environment variables. diff --git a/docs/installation/prerequisites.md b/docs/installation/prerequisites.md new file mode 100644 index 0000000..7dcea39 --- /dev/null +++ b/docs/installation/prerequisites.md @@ -0,0 +1,16 @@ +# Prerequisites + +## Package Prerequisites + +- `curl` +- `apt-get` + +If any package is not available on your system, or if you do not have permission to use said package, follow operating +system guidance on installation and setup. + +## Supported Operating Systems and Compute Platforms + +| Operating Systems | Compute Platforms | +|-------------------|-------------------| +| Debian | arm64/amd64 | +| Ubuntu | arm64/amd64 | diff --git a/docs/installation/uninstall.md b/docs/installation/uninstall.md new file mode 100644 index 0000000..8c7cad5 --- /dev/null +++ b/docs/installation/uninstall.md @@ -0,0 +1,27 @@ +# Uninstalling Voi + +## Removing Your Installation + +!!! danger + Make sure to [keep your account mnemonics](../../cli-tools/#retrieving-account-mnemonic) in a safe place. If you lose them, you will lose access to your account, + including any Voi and Via tokens you have. + +To uninstall, execute the following commands: + +- Leave the Swarm + + ```bash + docker swarm leave --force + ``` + +- Remove the **~/voi** directory + + ```bash + rm -rf /voi/ + ``` + +- Remove the **/var/lib/voi** directory + + ```bash + rm -rf /var/lib/voi + ``` diff --git a/docs/notification-guides/pushbullet.md b/docs/notification-guides/pushbullet.md new file mode 100644 index 0000000..c33c3a6 --- /dev/null +++ b/docs/notification-guides/pushbullet.md @@ -0,0 +1,64 @@ +# Pushbullet + +!!! info + Follow guidance on [enabling notifications](../../operating/setup-notifications/) first. + +## What It Is? + +[Pushbullet](https://www.pushbullet.com) is a free and easy-to-use notification service that can be used to send notifications to your phone, tablet, or computer. + +## Supported Ways To Receive Notifications + +- Push notifications to your phone, tablet, or computer + +## How To Set Up Pushbullet + +### Get Started + +!!! info inline end + Full configuration options and capabilities are available via [Apprise](https://github.com/caronc/apprise/wiki/Notify_pushbullet) + +1. Create a Pushbullet account if you don't already have one. Sign up links are on their [homepage](https://www.pushbullet.com). +2. Install the Pushbullet app on your phone, tablet, or computer. +3. Follow the instructions to set up the app on your device. +4. Go to [https://www.pushbullet.com/#settings](https://www.pushbullet.com/#settings) and create an access token. +5. Copy the access token and store securely. +6. Copy the example `notification.yml.example` file to the `notification.yml` file: + + ```bash + cp ~/voi/docker/notification.yml.example ~/voi/docker/notification.yml + ``` + +7. Update the **NOTIFICATION_URLS** value in `notification.yml` file with your Pushbullet access token: + + ```yaml + NOTIFICATION_URLS="pbul://" + ``` + +!!! tip + If you want to use multiple notification mechanisms, separate them with a comma. + For example, to use both Discord and Pushbullet for notification, you would set the **NOTIFICATION_URLS** value + in the `notification.yml` file to: + ```yaml + NOTIFICATION_URLS="discord:///,pbul://" + ``` + +## Testing Your Notification Configuration + +With your configuration in place it's now time to test it. + +First we need to make sure that your changes to notification.yml is picked up by the stack. +To do this, rerun the installation script: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +After the script has run and applied changes to the environment we need to send a test notification to make sure +everything is working as expected. + +To do this, run the following command: + +```bash +~/voi/bin/notification-test +``` diff --git a/docs/operating/participation-keys.md b/docs/operating/participation-keys.md new file mode 100644 index 0000000..5e83cea --- /dev/null +++ b/docs/operating/participation-keys.md @@ -0,0 +1,16 @@ +# Keep Your Participation Keys Up-to-Date + +To participate in the Voi network, you need to keep your participation key up-to-date. +The Participation key is used to sign blocks and participate in the consensus process. +If your participation key is not up-to-date, your node will not be able to participate in the consensus process. + +To keep your participation key up-to-date, you can run the installation script again. The script will create a new key +if your current key is expected to expire within the next 14 days. + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +!!! tip + Setup expiration notifications to receive a reminder when your participation key is about to expire. + [Learn more](./setup-notifications.md) diff --git a/docs/operating/running-your-node.md b/docs/operating/running-your-node.md new file mode 100644 index 0000000..7bc539a --- /dev/null +++ b/docs/operating/running-your-node.md @@ -0,0 +1,19 @@ +# Keeping Your Node Healthy + +!!! info inline end "A healthy node is a happy node" + We are working on improving the running experience by automating and simplifying as much as possible. Join the [Discord](https://discord.com/invite/vnFbrJrHeW) and provide your feedback! + +To operate your node and manage your accounts, you can use the Voi CLI tools. The Voi CLI tools are a set of scripts +that allow you to manage common blockchain actions. The Voi CLI tools are installed with the Voi Swarm package. + +As a participant it's important that you continuously monitor the health of your node, this includes monitoring system +metrics, node health as well as ensuring participation keys are up-to-date. + +| Metrics | Description | How to Monitor | Feature in Voi Swarm | +|--------------------------|-----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| +| Compute platform metrics | CPU load, disk usage, network bandwidth, etc. | Use cloud / system monitoring tools, [Voi Checker](https://github.com/crypto-morph/voi-checker) | :material-minus: | +| Node health | Node status, participation status, etc. | Use [Voi Checker](https://github.com/crypto-morph/voi-checker) and [Voi Proposer Data](https://cswenor.github.io/voi-proposer-data/health.html) | :material-minus: | +| Participation keys | Participation key status and expiration | Use [CLI tools](../cli-tools.md) to check participation status and setup. Voi Swarm offers [notifications on key expiration](../setup-notifications) | :material-plus: | + +Contributions to improve the health monitoring of the Voi node are welcome. +Please join the [Voi Network Discord server](https://discord.com/invite/vnFbrJrHeW) to discuss with other community members and contributors. You can also open an issue or a pull request on GitHub. diff --git a/docs/operating/setup-notifications.md b/docs/operating/setup-notifications.md new file mode 100644 index 0000000..378a83d --- /dev/null +++ b/docs/operating/setup-notifications.md @@ -0,0 +1,58 @@ +# Setup notifications + +## Enabling Notifications + +Voi Swarm offers the ability to receive notifications when the participation key is about to expire, helping you to keep +your node healthy and active. + +## Get Started + +The notification.yml file is an example file that you can use to set up notifications. +Start by copying the example `~/voi/docker/notification.yml.example` file to the `~/voi/docker` directory +without the .example extension + +```bash +cp ~/voi/docker/notification.yml.example ~/voi/docker/notification.yml` +``` + +## Adding Your Notification Choices + +Update the notification.yml file with your preferred notification mechanism by updating the **NOTIFICATION_URLS** +environment variable. The notification mechanism can be a webhook, email, push, or any other notification mechanism that +is available via [Apprise notifications](https://github.com/caronc/apprise?tab=readme-ov-file#supported-notifications) + +If you want to use multiple mechanisms, separate them with a comma. For example, to use both Discord and Pushbullet for +notification, you would set the **NOTIFICATION_URLS** value in the **notification.yml** file to: + +```yaml +NOTIFICATION_URLS="discord:///,pbul://" +``` + +## Updating Participation Key Checker Schedule + +To modify the participation key notification schedule, adjust the labels in the notification.yml file. + +| Label | Description | +|--------------------------|------------------------| +| `swarm.cronjob.schedule` | `0 16 * * *` (default) | + +This is by default set to run daily at 4 PM UTC. Adjust this to your preferred time, accounting for your +timezone's UTC offset. Use a resource like [dateful.com](https://dateful.com/time-zone-converter) for timezone conversion. + +The format of the schedule is following the [CRON format](https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format). + +## Applying Notification Configuration to the Stack + +To apply your notification configuration to the stack, rerun the installation script: + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` + +## Testing Your Notification Configuration + +To test your notification configuration, you can manually trigger the notification service by running the following command: + +```bash +~/voi/bin/notification-test +``` diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..3abed4d --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,5 @@ +:root { + --md-primary-fg-color: #702AE2; + --md-primary-fg-color--light: #702AE2; + --md-primary-fg-color--dark: #702AE2; +} \ No newline at end of file diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..7d3ae72 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,33 @@ +# Troubleshooting + +## Startup State for Services in Stack + +```bash +docker stack ps --no-trunc voinetwork` +``` + +## Replication State for Services in a Stack + +```bash +docker service ls +``` + +## Pull Log Files for a Service + +```bash +docker service logs voinetwork_algod +``` + +## Inspect Service + +```bash +docker inspect voinetwork_algod +``` + +## Testing Notifications + +To test notifications execute the following command: + +```bash +~/voi/bin/notification-test +``` diff --git a/docs/updating/swarm-update.md b/docs/updating/swarm-update.md new file mode 100644 index 0000000..1785f49 --- /dev/null +++ b/docs/updating/swarm-update.md @@ -0,0 +1,10 @@ +# Updating Voi Swarm + +## Updating the Voi Swarm Package + +To update the Voi Swarm package, you can run the installation script again. This will update the Voi Swarm package to the +latest version, including Docker configuration and utility commands. + +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/VoiNetwork/voi-swarm/main/install.sh)" +``` diff --git a/docs/updating/telemetry.md b/docs/updating/telemetry.md new file mode 100644 index 0000000..70d003e --- /dev/null +++ b/docs/updating/telemetry.md @@ -0,0 +1,9 @@ +# Setting Up Telemetry + +## Updating Your Telemetry Name After Installation + +To update your telemetry name after installation, or to opt-out, you can run the following command: + +```bash +~/voi/bin/update-telemetry-name +``` diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..68d446b --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,97 @@ +# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json +site_name: Voi Swarm +site_description: Create and run a Voi Network Participation Node +site_url: https://voinetwork.github.io/voi-swarm/ +repo_url: https://github.com/VoiNetwork/voi-swarm +edit_uri: edit/main/docs/ + +theme: + name: material + language: en + logo: assets/Voi_Logo_White_on_Purple_Background.png + favicon: assets/favicon.ico + palette: + primary: custom + features: + - navigation.instant + - navigation.instant.progress + - content.action.edit + - content.code.copy + - search.suggest + - search.highlight + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/VoiNetwork/voi-swarm + - icon: fontawesome/brands/discord + link: https://discord.com/invite/vnFbrJrHeW + consent: + title: Cookie consent + description: >- + We use cookies to recognize your repeated visits and preferences, as well + as to measure the effectiveness of our documentation and whether users + find what they're searching for. With your consent, you're helping us to + make our documentation better. + actions: + - accept + - reject + - manage + analytics: + provider: google + property: G-FXJF968XD5 + feedback: + title: Was this page helpful? + ratings: + - icon: material/emoticon-happy-outline + name: This page was helpful + data: 1 + note: >- + Thanks for your feedback! + - icon: material/emoticon-sad-outline + name: This page could be improved + data: 0 + note: >- + Thanks for your feedback! Help us improve this page by + joining our Discord. + +copyright: + Change cookie settings + +markdown_extensions: + - attr_list + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - admonition + - pymdownx.details + - pymdownx.superfences + +plugins: + - search + - social + - git-revision-date-localized: + enabled: true + enable_creation_date: true + - git-authors + +extra_css: + - stylesheets/extra.css + +nav: + - Home: index.md + - Installation: + - Prerequisites: installation/prerequisites.md + - Installation: installation/installation.md + - Uninstall: installation/uninstall.md + - Updating: + - Updating package: updating/swarm-update.md + - Telemetry name: updating/telemetry.md + - Operating: + - Running your node: operating/running-your-node.md + - Participation keys: operating/participation-keys.md + - Setup notifications: operating/setup-notifications.md + - Notification Guides: + - Pushbullet: notification-guides/pushbullet.md + - CLI Tools: cli-tools.md + - Troubleshooting: troubleshooting.md