A Discord chat bot for the Tardsquad guild (Discord name for server) written in Python with the popular library discord.py and deployed using Docker at Cloud Run Compute Engine.
- A general tutorial for a Discord bot can be found here
- discord.py Python library to work with Discord
- API Reference
- Commands Refernce from the extension module.
- Discord servers:
- Discord Developer Portal
- GCP
Cloud Run Service Application that runs our container for the image published to GCR.- The Cloud Run service is disabled by deploying the demo Hello World program, as there is no disable functionality.
- Set to use the container image
gcr.io/tardsquad-discord-bot/tardsquad-discord-bot:latest
.
- Compute Engine Where the VM
tardbot-vm
is defined and managed that runs our container for image thepublished to GCR via Cloud Build Triggers.- The envvar
DISCORD_TOKEN
is configured where the container is selected for the VM.
- The envvar
- Cloud Build
- Build History shows current triggered builds.
- Cloud Build Triggers
- Sets up build/push/deploy on git version tag push by pointing to .google-cloud/cloudbuild.yaml.
- Manually triger a build from the UI withou making a new git tag.
- Container Registry
- Storage Bucket for the above containers
- Service Account used to publish Docker images to GCR.
Secret Manager is whereDISCORD_TOKEN
is stored, which is hooked up as envvar in the Cloud Run service.- Envvars are managed directly in Compute Engine now.
Make sure to use a supported python version. See the key python
in the section tool.poetry.dependencies
at pyproject.toml. It's recommended to install e.g. pyenv
to manage python versions.
- Get the discord token by asking @erikw or from the bot tab in the tardsquad-discord-bot application in the Discord developer portal
git clone https://github.com/tardsquad/tardsquad-discord-bot.git && cd $(basename "$_" .git)
echo "DISCORD_TOKEN=the-token" > .env
docker-compose up
Continue reading for how to setup local development envionment, with our without Docker below:
-
Make sure to
$ poetry shell
before using tools like pyright LSP, so that it can find the installed dependency modules -
Reference for how to structure a python project: https://realpython.com/pypi-publish-python-package/
-
Clone this git
git clone https://github.com/tardsquad/tardsquad-discord-bot.git
cd tardsquad-discord-bot
- Install Poetry
pip install poetry
- Install project dependencies
poetry install
- Set up envionment. We must make sure to only use the staging envionment so that our local runs don't endup in production the server. Fetch the bot token from the bot tab in the tardsquad-discord-bot-staging application in the Discord developer portal. Either set this as as an envionmental variable together with the guild (server name), or more preffered in the git-ignored
.env
file in the project directory:
echo "DISCORD_TOKEN=the-token" > .env
- Now tardsquad-discord-bot should work!
poetry run tardsquad-discord-bot
- To install locally:
poetry build
pip install dist/tardsquad_discord_bot-*.whl
- Build and run Docker image using the local
.env
file with secrets:
docker build -t tardsquad-discord-bot .
docker run --env-file=.env -t tardsquad-discord-bot
# or more simply
docker-compose up
- Drop in to a shell like
- New container
docker run --env-file=.env --rm -it --entrypoint bash tardsquad-discord-bot
- Runnning container
docker ps docker exec -it <container-id> bash
- First setup
- Install gcloud cli e.g.
$ brew install google-cloud-sdk
- Set up first time
gcloud init
- Install gcloud cli e.g.
- To pull a Docker image stored in Google Cloud Registry:
docker pull gcr.io/tardsquad-discord-bot/tardsquad-discord-bot:latest
- To ssh in to the Compute VM
- SSH
gcloud compute ssh --project=tardsquad-discord-bot --zone=us-central1-a tardbot-vm # or if defaults were set in gcloud-init gcloud compute ssh tardbot-vm
- Restart the VM
gcloud compute instances stop tardbot-vm gcloud compute instances start tardbot-vm
- Force update to latest container image in GCR and reboot VM:
gcloud compute instances update-container --project=tardsquad-discord-bot --zone=us-central1-a --container-image gcr.io/tardsquad-discord-bot/tardsquad-discord-bot:latest tardbot-vm
- TODO next time document: creating a new VM instance from scratch using
gcloud compute instances create-with-container \ --project=tardsquad-discord-bot \ --zone=us-central1-a \ --container-image gcr.io/tardsquad-discord-bot/tardsquad-discord-bot:latest \ --container-env DISCORD_TOKEN=... \ tardbot-vm
- First verify that the bot works
poetry run tardsquad-discord-bot docker-compose up
- Now update version and create corresponding git tag
vi CHANGELOG.md poetry version minor && ver="v$(poetry version -s)" git commit -am "Bump version to $ver" && git tag $ver && git push --atomic origin main $ver
- A newly pushed tag with the pattern
v.*
will trigger a Cloud Build Triggers. This build trigger will execute .google-cloud/cloudbuild.yaml. The last step will spin up a container for the new image at for the Cloud Run Service that runs our container for image published to GCR. - Head over to the production discord and try a command like
!version
and it should work!
- Even though the Cloud Run revision is configured to only have one container active at once, on a new deploymet the old one will live on for a while. This means that for some moment of time, multiple instances of the bot-client will be conntected and thus one will multiple replies on commands. Cloud Run is designed for web services, not chat bots :).