Repository navigation
Installation
setup.sh installs a bot node or a relay node. A bot node is the Unraid server that the bot reports on. A relay node is a machine outside that network that runs the public service checks. For a bot node, the script also does steps 1 to 5 below, and it can install the Host helper.
Download the source archive, read the scripts, and then run setup.sh as root:
cd "$(mktemp -d)"
curl -fsSL https://github.com/mrchrisneal/shazzzbot/archive/refs/heads/main.tar.gz | tar -xz --strip-components=1
less setup.sh tools/setup_*
bash setup.shImportant
setup.sh needs the full source tree beside it: tools/, shazzzbot/, and shazzzbot-helper-unraid.py. A copy of setup.sh alone stops with an error.
The script also needs python3 3.11 or later before it starts. It stops when it runs from /boot. It also stops when other users can write to a source file or its directory.
The bot node must be an Unraid server. On any other system, use --role relay.
The script checks every prerequisite and shows the result in one table. Each line is ok, or MISSING with the command or Unraid step that fixes it. The menu then offers only the methods that have all their prerequisites. Type r to check again after a fix, or c to stop.
| Method | What it runs | Node |
|---|---|---|
compose-image |
Docker Compose with the published image ghcr.io/mrchrisneal/shazzzbot
|
bot or relay |
compose-build |
Docker Compose with an image built from a git clone of the --branch (default main) |
bot or relay |
docker-run |
docker run commands on the shazzzbot network, with no Compose |
bot or relay |
bot-only |
the bot container alone, with no docker-proxy | bot |
The image methods are compose-image, docker-run, and bot-only. They download the source archive of one release and check its SHA-256. They pin the image to the digest of that release. Use --version vX.Y.Z to choose the release. Without it, the script uses the latest release. If the latest release is older than the installed one, the script stops unless you give --version.
For each bot method except bot-only, the script installs docker-proxy/haproxy.cfg into the install directory. Without the docker-proxy, the Docker section and the /docker commands do not work.
The table covers these items:
- The tools:
root, Unraid (bot node),python33.11 or later,flock, Docker,docker composev2,git,curl, andtar. - Access to
github.comandghcr.io. - Free space for Docker, 1024 MiB or more.
- A trusted, writable install directory.
- The Docker socket, for the docker-proxy.
- Port
8443free, for a relay. - The Discord values or relay names, with
--unattended.
For the helper, the table also covers /usr/bin/python3 3.11 or later, the User Scripts plugin, and a writable flash drive. If only the helper prerequisites fail, type s to continue without the helper.
| Path | Content |
|---|---|
/mnt/user/appdata/shazzzbot |
The bot install: .env, config.toml, data/, and the Compose files. The script uses the real pool path of this share. Change it with --dir. |
/mnt/user/appdata/shazzzbot/backups |
The backups. Change it with SHAZZZBOT_BACKUP_DIR. |
/var/lib/shazzzbot-relay |
The relay install. |
/mnt/user/appdata/shazzzbot-helper |
The Host helper files. |
/boot/config/plugins/user.scripts/scripts/shazzzbot-helper |
The User Scripts hook that starts the helper. |
/tmp/shazzzbot-helper |
Temporary build files and the helper socket. |
For a bot node, the script asks these questions and prints direct links:
- Open https://discord.com/developers/applications and click New Application.
- Enter the Application ID. This is optional. With it, the script prints the links to
https://discord.com/developers/applications/<APP_ID>/informationandhttps://discord.com/developers/applications/<APP_ID>/bot. - On the bot page, click Reset Token and paste the token. The input is hidden. The bot needs no privileged intents.
- Open the invite link that the script prints:
https://discord.com/oauth2/authorize?client_id=<APP_ID>&scope=bot+applications.commands&permissions=117760. - Choose the server, then the status channels, the commands channel, and the audit channel from numbered menus. The script reads the lists from Discord with the bot token. If the bot is in no server yet, the script shows the invite link again.
After the choice, the script prints a link to each channel, https://discord.com/channels/<GUILD_ID>/<CHANNEL_ID>, so you can check it. Each status channel and the audit channel must be different. The commands channel and the audit channel are optional. To type an id by hand, type m in a menu. To copy an id, turn on User Settings > Advanced > Developer Mode in Discord. Then right-click the server or channel and click Copy ID.
The script also offers to set the Shazzzbot icon on the application and on the bot user. If Discord refuses, download https://raw.githubusercontent.com/mrchrisneal/shazzzbot/main/assets/icon.png and upload it on the General Information page.
The script writes .env and config.toml only if they do not exist. When it creates .env, it also asks for an optional relay: the RELAY_URL, RELAY_KEY, and RELAY_FINGERPRINT values. When it creates config.toml, it asks for these items:
- The time zone. The default is
UTC. - An optional NUT UPS, as
name@host:port. - Service checks.
- Up to 3 Forgejo or GitHub forges, only when it also creates
.env.
It checks each answer with the same rules as the bot.
Run bash setup.sh --role relay on the relay machine. The relay needs Docker, port 8443, and the names that it may check (--relay-allow). The script also asks for optional extra bot keys (RELAY_KEYS). The relay runs the same image with SHAZZZBOT_ROLE=relay.
After the first start, the script prints the RELAY_URL, RELAY_KEY, and RELAY_FINGERPRINT lines:
- Put the lines in the
.envfile of the bot. - Put the public address of the relay machine in
RELAY_URL. - Open TCP port
8443to the relay machine. - Recreate the bot.
If the relay kept its key from an earlier start, the script does not print the lines. The fingerprint is then in the relay log.
When the script finds an install, it offers these actions. --action NAME selects one with no menu.
| Action | What it does |
|---|---|
keep |
Changes nothing. The default in the menu. |
upgrade |
The same as --upgrade. |
migrate |
Bot node only. Adds the available defaults to config.toml as comments, and leaves the containers unchanged. |
repair |
An upgrade that also creates a missing .env or config.toml. |
reinstall |
An upgrade that also recreates the containers. |
Before migrate changes config.toml, it saves the old file as config.toml.bak-<version> beside it.
With --unattended or --dry-run and no --action, the script selects repair for a partial install. It selects keep for a current install, and upgrade for all other installs.
To change the method or the role of an install, stop it first. Then remove .setup-state from the install directory and run the script again.
To upgrade, run bash setup.sh --upgrade. The upgrade uses the role and the method that the last successful setup recorded. If --role names a different role, the script stops: a change of role needs a fresh install. An upgrade never creates .env or config.toml.
An image method pulls the new release and recreates the containers. compose-build clones the branch again and builds a new image. If the new version does not report healthy within 180 seconds, the script restores the backup. It then starts the previous version again.
An upgrade also updates an installed helper.
For cron, add --unattended and --method. The script then asks no questions. For a new bot install, it takes the token from SHAZZZBOT_DISCORD_TOKEN, and the ids from --guild-id and --status-channel. For a new relay install, it needs --relay-allow. --set-icon sets the icon with no question.
--dry-run shows each action and changes nothing. --help shows all options and the environment variables that change the paths.
| Option | Use |
|---|---|
--role bot|relay |
The node type. |
--method NAME |
The install method. |
--version vX.Y.Z |
The release for the image methods. |
--upgrade |
Upgrade the install. |
--action NAME |
keep, upgrade, migrate, repair, or reinstall. |
--helper, --no-helper
|
Install or update the helper, or leave it alone. |
--helper-only |
Install only the helper, with no bot deployment. |
--helper-bundle DIR |
Use a verified local helper bundle. |
--accept-flash-share |
Permit a writable SMB export of the flash drive for the helper. |
--unattended, -y, --yes
|
Ask no questions. |
--dry-run, -n
|
Show each action and change nothing. |
--dir DIR |
The install directory. |
--branch NAME |
The git branch for compose-build. The default is main. |
--keep N |
The number of backups to keep, 1 to 100. The default is 5. |
--app-id, --guild-id, --status-channel, --audit-channel, --commands-channel
|
The Discord ids. |
--timezone NAME |
The time zone, for example America/Los_Angeles. |
--relay-allow NAMES |
The names that a relay may check, separated by spaces. |
--set-icon |
Set the icon with no question. |
The exit codes are:
-
0: success. -
1: a failure, a missing value or prerequisite, or a cancel. -
2: an incorrect option. -
130or143: the script got an interrupt or a stop signal.
Warning
--accept-flash-share lets each person who can write to the flash share run code as root.
Note
Before a change, the script backs up .env, config.toml, the Compose files, haproxy.cfg, and the helper files to backups/. It keeps the last 5 backups. It never removes Docker images or volumes.
The script keeps the .env, config.toml, helper config.json, and api.key files that exist. In .env, it changes only the two helper lines: SHAZZZBOT_HELPER_KEY and HELPER_SOCKET_DIR.
unraid/shazzzbot.xml adds the bot in the Unraid Docker page with the published image. The template runs the bot container only. The Docker section and the /docker commands need the docker-proxy, and the Tasks section needs the host helper. setup.sh sets up both. Without them, the bot runs in bot-only mode: leave docker_proxy out of the [host] table in config.toml.
Before the first start, do these steps:
- Create
config.tomlwith mode600and owner10001. - Create a data directory with owner
10001. - Create the
shazzzbotDocker network:docker network create shazzzbot.
For a relay, set Node role to relay and fill in Relay names and Relay port.
- Open the Discord Developer Portal at https://discord.com/developers/applications.
- Click New Application, type a name, and accept the terms.
- On the Bot page, click Reset Token and copy the token. You need it in step 4.
- On the same page, set Public Bot to off, so that only you can add the bot to a server.
Warning
The bot token gives full control of the bot. Do not share it, paste it in a chat, or commit it. If it leaks, click Reset Token again.
The bot asks Discord only for the Guilds gateway intent (an intent is a category of events the bot receives). Guilds is not a privileged intent, so leave all three privileged intent switches on the Bot page off.
- On the OAuth2 page, open the URL Generator.
- Under Scopes, select
botandapplications.commands. - Under Bot Permissions, select these permissions:
- View Channels
- Send Messages
- Embed Links
- Attach Files
- Read Message History
- Open the generated URL in a browser and select your server.
The permission integer for that set is 117760. The bot needs the same five permissions in each status channel. In the audit channel and the commands channel, it needs View Channels and Send Messages. /blowup also needs Send Messages in the channel where you use it.
Note
The bot works in one Discord server only. When it finds itself in a different server, it leaves that server.
- In Discord, open User Settings > Advanced and set Developer Mode to on.
- Right-click the server icon and click Copy Server ID. This is
guild_id. - Right-click the status channel and click Copy Channel ID. This is the
channelof the first[[outputs]]block. - Right-click the audit channel and click Copy Channel ID. This is
audit_channel_id. - For each role that gets a permission tier, open Server Settings > Roles, right-click the role, and click Copy Role ID.
- For each person that gets a permission tier, right-click the name and click Copy User ID.
- Optional: copy the channel id of a commands channel, for
commands_channel_id, and the user id that/blowuppings, forblowup_user_id.
Use a separate, private channel for the audit channel. The bot posts there each time a person makes a change.
On the Unraid server, download the repository and create the two files:
cd /mnt/user/appdata
git clone https://github.com/mrchrisneal/shazzzbot.git shazzzbot
cd shazzzbot
cp .env.example .env
cp config.example.toml config.toml-
Open
.envand put the bot token afterDISCORD_TOKEN=. -
Add an install id to
.env. Compose anddeploy.shstop without it:echo "SHAZZZBOT_INSTALL_ID=$(openssl rand -hex 16)" >> .env
-
Keep
HELPER_SOCKET_DIR=/tmp/shazzzbot-helper/socketfrom.env.example. Docker creates the directory if it does not exist. -
Open
config.toml. Keepconfig_format = 1, and setguild_id,audit_channel_id, and thechannelof the first[[outputs]]block. Add one more[[outputs]]block for each more status channel (see Outputs). -
Each tier table has a
roleslist and auserslist:[perms.view],[perms.operate], and[perms.admin]. Add the ids that get that tier (see Permissions). -
Set
allowin the[restarts]table if people must restart containers from Discord (see Restarts). -
Protect the files and create the data directory. The bot runs as user id
10001inside its container:
chmod 600 .env config.toml
chown 10001 config.toml
mkdir -p data
chown 10001 dataImportant
Create config.toml before the first start. If the file does not exist, Docker creates an empty directory with that name, and the bot cannot start.
The bot reads tokens and keys only from the environment, that is from .env. A setting that config.toml does not know stops the bot with an unknown setting error. For the full list of variables, see Environment variables.
For every setting, see Configuration.
On the Unraid server, in the repository directory:
docker compose up -d --buildCompose builds one image from Dockerfile, pulls the haproxy image, and starts two services:
-
shazzzbot: the bot. -
docker-proxy: a filter in front of the Docker socket (see Security model).
For the Tasks section and the UPS shutdown setting, install the Host helper on the server.
The status message appears in the status channel after the first poll. The slash commands appear in your server when the bot connects.
deploy.sh copies the project to the server over SSH and rsync, and starts it there:
./deploy.sh tower
./deploy.sh tower /mnt/user/appdata/shazzzbotThe first argument is an SSH host name. The second argument is the directory on the server, and its default is /mnt/user/appdata/shazzzbot.
For each server, the script can use its own files. If config.<host>.toml or .env.<host> exists on the local machine, the script uses it in place of config.toml or .env. For example, ./deploy.sh tower uses config.tower.toml when that file exists. On the server, the files always get the names config.toml and .env.
The script does these steps in this order:
- It stops with an error if the selected
.envfile or config file is missing on the local machine. - It stops with an error if the selected
.envfile has noSHAZZZBOT_INSTALL_IDvalue. - It runs
./test.sh, and stops if a test fails. - It copies
VERSION,compose.yaml,Dockerfile,.dockerignore,requirements.txt,shazzzbot/,docker-proxy/,docs/demo/, andtools/preview_assets.pyto the server. It deletes files on the server that are not in the local copy. - It copies the two files to
.envandconfig.tomlwith mode600. - On the server, it creates
data/and givesdata/andconfig.tomlto user id10001. It stops ifdatais a symbolic link. - It runs
docker compose up -d --build --remove-orphans, then recreatesdocker-proxyso that it loads the new proxy configuration. Then it runsdocker compose ps.
The SSH user must be able to run docker and chown on the server. On Unraid, that is root.