Note: This was originally posted to the fabulous dev.to in March 2022
I had a problem:
How do I keep a Python Discord bot online, allow multiple people to contribute to it and then deploy it when new features are added?
Several Google searches had come up short, partial solutions; no clear answer.
Here is my attempt at a solution (though no promise that it is the smartest, or best.. it has just worked for me ¯\_(ツ)_/¯)
This project uses discord.py and discord-py-slash-command to patch the missing slash command functionality and is hosted here.
The aim of the project was to allow for any member of a private Discord to contribute custom functionality, test locally and then deploy for all to use.
For hosting, I am using DigitalOcean.
I am sure any other cloud hosting provider will work, just a few changes in the GitHub action script would be required.
To actually upload the code and implement the triggering of the workflow when a tag is created, I have used the following GitHub workflow script.
1 | name: Deploy Code to Digital Ocean |
The core of the script is the SSH portion. GitHub actions are designed for the repeating of others code. This action makes use of Gary Großgarten’s “Github Action SSH”.
A private key is stored within the repository, with the matching Public Key on the server.
The important part of the script is the following commands:
1 | cd beeb-bot/ |
pm2
in the script refers to a process manager, mainly used for Node.js projects – however it can run Python scripts.
pm2
is used used because just running something like python3 main.py
locks up the action, and it can never exit. Using this means the script no longer locks up, and the action succeeds/fails.
main_bot
is a short hand for pm2 start "pipenv run python3 main.py" --name main_bot --watch
. This project makes use of pipenv to manage dependencies, and to make sure the virtual environment is used, pipenv run
is called.
A git instance of repo is stored on the server. git pull
gets a copy from GitHub (which should be the latest release).
pipenv install
is run to ensure the virtual environment on the server matches the needed packages for the project.
pm2 start main_bot
is called to start the process again and run the freshly pulled main.py
script.
The initial set-up on the server has a few requirements. pipenv
and pm2
must then be installed.
Following this:
pipenv install
to establish the same Python packages that the project is expecting (mainly discord.py and discord-py-slash-command).env
file so that when the bot is run, it can talk to Discord and authenticate.pm2 start "pipenv run python3 main.py" --name main_bot
– _Note: This project expects the proccess to be called “main_bot”, but in reality, any name can be used._This is not entirely comprehensive, but hopefully is a good jumping off point for others.
I am certain that it is not perfect, I have missed something obvious or that there is something simpler.
One big gap, the release process relying on tags is very manual. The usage of Semantic Version could improve this.