Emily T. Burak
Discord bots in Python on Kubernetes with Google Kubernetes Engine: some notes
(Photo by Frank Eiffert on Unsplash)
One of my hobbies is building Discord bots, used for automation and interaction in the popular chat(and a lot more) app. In this blog post, I'll focus on my lessons learned deploying a Python-based Discord (using Nextcord) to Kubernetes(via. Google Kubernetes Engine), as I've found a dearth of tutorials on implementing DevOps with Discord bots. Discord bots are a great entry point to coding for new developers, as it's a platform a lot of tech-savvy people use and want to get a customized experience or new features when using. Discord bots involve unique challenges in testing, deployment, and hosting, all of which I've hit, but I'm going to focus on deployment to GKE for now.
Today, specifically, I'm going to focus on how I code Discord bots, Docker for Discord bots, Kubernetes challenges I faced, and my solutions.
First, for context, I have been coding Discord bots since quarantines began in the U.S. (shocker, Discord's popularity jumped immensely in these remote times, as mentioned in this Mashable article) and have been increasingly interested in how to make them work well, as well as the ecosystem of rather impressive bots out there. This post is going to focus on deploying a Nextcord (a maintained fork of Discord.py, the late and great OG of Python libraries for Discord) bot to Google Kubernetes Engine in a Docker container. My bots are admittedly pretty simple, following the cog pattern and utilizing a .env file for environmental variables with python-dotenv, as seems to be common practice in the community. This works great for local development, but can cause some real issues in deployment.
The first step to deployment on GKE for me is to create a Dockerfile for the bot. These can be rather simple, Dockerfiles tend to be pretty readable and easy to setup on a high level, but it's a rabbit hole for those not familiar with containerization or DevOps techniques. I would recommend Docker's docs, which are quite good, as well as
Techworld With Nana's videos on Docker, where I've learned a lot about the technology. The important takeaway is that a Dockerfile is the first step to Kubernetes deployment of a Discord bot, and can be pretty simple (as often bots can be run with a simple "python3 bot.py" and lack a lot of the complexity of full web apps, for instance.) Docker can be used to run a Discord bot on a VM such as an AWS EC2 instance, or to help with deployment to a PaaS like Heroku, which is probably a better option for simple deployment. I'm just extra and like Kubernetes' power and options.
The main challenges I faced on Kubernetes vs. vanilla Docker was what ended up pushed up and built to GKE through Cloud Build (Google's build service for CI/CD, an important part of DevOps) to Artifact Registry, (which is a place to store Docker container images and other packages) a process that was made easier by this tutorial. I had set up my bot to use a .env file as mentioned and to utilize some configuration files. In addition to some issues getting those up to Artifact Registry, I realized that Kubernetes approach to security -- to put it overly simply for at least configuration files: "pretty much, you handle it" -- left something to be desired in the world of Discord bots, where your token is a very important environmental variable that can compromise the entire security of your bot and where additional sensitive configuration files might be needed.
My solutions to the sensitive information issue with Discord bots ended up being two-fold. The odd problems I had getting the actual folders and files that were sensitive up onto the final pod were solved with using explicitly the ADD command in my Dockerfile to make sure the files were present along with echoing out an ls -l during the build phase of the Dockerfile to confirm the files present on the image. Still digging into what caused that, but good to know that ADD can supplement the usual COPY . /app paradigm I see in a lot of Python Dockerfiles if there's issues. As far as the sensitivity of the information, Secrets are built into Kubernetes and are a good first start over ConfigMaps for configuration of sensitive details. As this is pretty much a personal project combining my love of Discord bots and Kubernetes, I'm working from there and looking into Vault after my good experiences in general with Hashicorp's Infrastructure as Code offering in Terraform.
These have been some scattered thoughts and it's good you've made it this far, hopefully you've picked up some new knowledge or gotten some ideas from this post! Don't hesitate to connect on LinkedIn , where the bulk of my professional code type stuff lives in some form or another, or to leave a comment about, say, your experiences with DevOps and Discord bots!