diff --git a/.env.example b/.env.example index cc76ef84..4494f3b0 100644 --- a/.env.example +++ b/.env.example @@ -49,6 +49,8 @@ DOCKER_DEV_SSH_PASSWORD=password DOCKER_PROD_DOMAIN= DOCKER_PROD_WEB_PORT=443 +# The MySQL database running in the container is exposed to the host on this port, +# allowing access with database tools such as DBeaver DOCKER_PROD_MYSQL_PORT=3001 # Password for the Zeppelin database user DOCKER_PROD_MYSQL_PASSWORD= diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 0edbbc88..90f2c2ca 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -2,7 +2,7 @@ Zeppelin's development environment runs entirely within a Docker container. Below you can find instructions for setting up the environment and getting started with development! -👉 **No support is offered for self-hosting the bot!** 👈 +**Note:** If you'd just like to run the bot for your own server, see 👉 **[PRODUCTION.md](./PRODUCTION.md)** 👈 ## Starting the development environment diff --git a/MANAGEMENT.md b/MANAGEMENT.md new file mode 100644 index 00000000..a6d12ef5 --- /dev/null +++ b/MANAGEMENT.md @@ -0,0 +1,34 @@ +# Management +After starting Zeppelin -- either in the [development](./DEVELOPMENT.md) or [production](./PRODUCTION.md) environment -- you have several tools available to manage it. + +## Note +Make sure to add yourself to the list of staff members (`STAFF`) in `.env` and allow at least one server by default (`DEFAULT_ALLOWED_SERVERS`). Then, invite the bot to the server. + +In all examples below, `@Bot` refers to a user mention of the bot user. Make sure to run the commands on a server with the bot, in a channel that the bot can see. + +In the command parameters, `` refers to a required parameter (don't include the `< >` symbols) and `[this]` refers to an optional parameter (don't include the `[ ]` symbols). `` refers to being able to list multiple values, e.g. `value1 value2 value3`. + +## Allow a server to invite the bot +Run the following command: +``` +@Bot allow_server [userId] +``` +When specifying a user ID, that user will be given "Bot manager" level access to the server's dashboard, allowing them to manage access for other users. + +## Disallow a server +Run the following command: +``` +@Bot disallow_server +``` + +## Grant access to a server's dashboard +Run the following command: +``` +@Bot add_dashboard_user +``` + +## Remove access to a server's dashboard +Run the following command: +``` +@Bot remove_dashboard_user +``` diff --git a/PRODUCTION.md b/PRODUCTION.md new file mode 100644 index 00000000..a45bf50d --- /dev/null +++ b/PRODUCTION.md @@ -0,0 +1,32 @@ +# Zeppelin production environment +Zeppelin's production environment - that is, the **bot, API, and dashboard** - uses Docker. + +## Starting the production environment +1. Install Docker on the machine running the bot +2. Make a copy of `.env.example` called `.env` +3. Fill in the missing values in `.env` +4. Run `docker-compose -f docker-compose.production.yml -d up` + +## Updating the bot + +### One-click script +If you've downloaded the bot's files by cloning the git repository, you can use `update.sh` to update the bot. + +### Manual instructions +1. Shut the bot down: `docker-compose -f docker-compose.production.yml down` +2. Update the files (e.g. `git pull`) +3. Start the bot again: `docker-compose -f docker-compose.production.yml -d up` + +### Ephemeral hotfixes +If you need to make a hotfix to the bot's source files directly on the server: +1. Shut the bot down: `docker-compose -f docker-compose.production.yml down` +2. Make your edits +3. Start the bot again: `docker-compose -f docker-compose.production.yml -d up` + +Note that you can't edit the compiled files directly as they're overwritten when the environment starts. +Only edit files in `/backend/src`, `/shared/src`, and `/dashboard/src`. + +Make sure to revert any hotfixes before updating the bot normally. + +## View logs +To view real-time logs, run `docker-compose -f docker-compose.production.yml -t logs` diff --git a/README.md b/README.md index 4d11bbe5..52f60f07 100644 --- a/README.md +++ b/README.md @@ -19,52 +19,15 @@ Zeppelin is a moderation bot for Discord, designed with large servers and reliab See https://zeppelin.gg/ for more details. +## Usage documentation +For information on how to use the bot, see https://zeppelin.gg/docs + ## Development -👉 **No support is offered for self-hosting the bot!** 👈 +See [DEVELOPMENT.md](./DEVELOPMENT.md) for instructions on running the development environment. -See [DEVELOPMENT.md](./DEVELOPMENT.md) for instructions on running the development environment! +Once you have the environment up and running, see [MANAGEMENT.md](./MANAGEMENT.md) for how to manage your bot. -### Config format example -Configuration is stored in the database in the `configs` table +## Production +See [PRODUCTION.md](./PRODUCTION.md) for instructions on how to run the bot in production. -```yml -prefix: '!' - -# role id: level -levels: - "12345678": 100 # Example admin - "98765432": 50 # Example mod - -plugins: - mod_plugin: - config: - kick_message: 'You have been kicked' - can_kick: false - overrides: - - level: '>=50' - config: - can_kick: true - - level: '>=100' - config: - kick_message: 'You have been kicked by an admin' - - other_plugin: - config: - categories: - mycategory: - opt: "something" - othercategory: - enabled: false - opt: "hello" - overrides: - - level: '>=50' - config: - categories: - mycategory: - enabled: false - - channel: '1234' - config: - categories: - othercategory: - enabled: true -``` +Once you have the environment up and running, see [MANAGEMENT.md](./MANAGEMENT.md) for how to manage your bot. diff --git a/docker-compose.development.yml b/docker-compose.development.yml index 4a28033e..d64aa393 100644 --- a/docker-compose.development.yml +++ b/docker-compose.development.yml @@ -1,7 +1,6 @@ version: '3' name: zeppelin-dev volumes: - mysql-data: {} vscode-remote: {} vscode-server: {} jetbrains-data: {} @@ -27,7 +26,7 @@ services: ports: - ${DOCKER_DEV_MYSQL_PORT:?Missing DOCKER_DEV_MYSQL_PORT}:3306 volumes: - - mysql-data:/var/lib/mysql + - ./docker/development/data/mysql:/var/lib/mysql command: --authentication-policy=mysql_native_password devenv: diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 1b03bd00..109cb3bb 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -1,7 +1,5 @@ version: '3' name: zeppelin-prod -volumes: - mysql-data: {} services: nginx: build: @@ -24,7 +22,7 @@ services: ports: - ${DOCKER_PROD_MYSQL_PORT:?Missing DOCKER_PROD_MYSQL_PORT}:3306 volumes: - - mysql-data:/var/lib/mysql + - ./docker/production/data/mysql:/var/lib/mysql command: --authentication-policy=mysql_native_password prepare_backend: @@ -44,15 +42,18 @@ services: - prepare_backend volumes: - ./:/zeppelin - - # Wait for the build_backend container to finish before starting the bot - # See: https://github.com/docker/compose/issues/5007#issuecomment-335815508 user: node - command: |- - bash -c ' \ - while ping -c1 prepare_backend &>/dev/null; do sleep 1; done; \ - cd /zeppelin/backend && npm run start-api-prod \ - ' + command: ["/bin/bash", "/zeppelin/docker/production/start-api.sh"] + + bot: + image: node:16.16 + restart: on-failure + depends_on: + - prepare_backend + volumes: + - ./:/zeppelin + user: node + command: ["/bin/bash", "/zeppelin/docker/production/start-bot.sh"] build_dashboard: image: node:16.16 diff --git a/docker/development/data/mysql/.gitignore b/docker/development/data/mysql/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/docker/development/data/mysql/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker/production/config/mysql.conf.d/.gitignore b/docker/production/config/mysql.conf.d/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/docker/production/config/mysql.conf.d/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker/production/data/mysql/.gitignore b/docker/production/data/mysql/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/docker/production/data/mysql/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker/production/start-api.sh b/docker/production/start-api.sh new file mode 100755 index 00000000..00e9359a --- /dev/null +++ b/docker/production/start-api.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# This wrapper script is used for two purposes: +# 1. Waiting for the prepare_backend container to finish before starting (see https://github.com/docker/compose/issues/5007#issuecomment-335815508) +# 2. Forwarding signals to the app (see https://unix.stackexchange.com/a/196053) + +# Wait for the backend preparations to finish before continuing +echo "Waiting for prepare_backend to finish before starting the API..." +while ping -c1 prepare_backend &>/dev/null; do sleep 1; done; + +echo "Starting the API" +cd /zeppelin/backend +exec npm run start-api-prod diff --git a/docker/production/start-bot.sh b/docker/production/start-bot.sh new file mode 100644 index 00000000..d9214465 --- /dev/null +++ b/docker/production/start-bot.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# This wrapper script is used for two purposes: +# 1. Waiting for the prepare_backend container to finish before starting (see https://github.com/docker/compose/issues/5007#issuecomment-335815508) +# 2. Forwarding signals to the app (see https://unix.stackexchange.com/a/196053) + +# Wait for the backend preparations to finish before continuing +echo "Waiting for prepare_backend to finish before starting the bot..." +while ping -c1 prepare_backend &>/dev/null; do sleep 1; done; + +echo "Starting the bot" +cd /zeppelin/backend +exec npm run start-bot-prod diff --git a/update.sh b/update.sh index bf615aa5..8a32cf94 100755 --- a/update.sh +++ b/update.sh @@ -1,4 +1,9 @@ #!/bin/bash -. ./update-backend.sh -. ./update-dashboard.sh +echo Updating Zeppelin... + +docker-compose -f docker-compose.production.yml down +git pull +docker-compose -f docker-compose.production.yml -d up + +echo Update finished!