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, which runs our container for the image published 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 trigger a build from the UI without 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 set up a local development environment, with or 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 environment. We must make sure to only use the staging environment so that our local runs don't end up on the production 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 an environmental variable together with the guild (server name), or more preferred 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 into a shell like
- New container
docker run --env-file=.env --rm -it --entrypoint bash tardsquad-discord-bot
- Running 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 into 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 the 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 the version and create the 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 for the Cloud Run Service that runs our container for the 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 deployment, 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 connected and thus one will receive multiple replies to commands. Cloud Run is designed for web services, not chatbots :).