Hosting a Python Discord Bot for Free with Fly.io
Intro
As Heroku is no longer going to be free after November 28, 2022, I am sharing another way to host a Discord bot 24/7 for free.
You will be able to host any kind of bot on Fly.io with few limitations by following the steps below. You can also optionally attach a PostgreSQL database for storing data.
Deploying a Python Discord Bot to Fly.io
This article was originally a video tutorial, which you can check out here:
1. Install the flyctl
command line tool
If you have the Homebrew package manager installed, flyctl can be installed by running:
brew install flyctl
If not, you can run the install script:
curl -L https://fly.io/install.sh | sh
Windows
Run the Powershell install script:
iwr https://fly.io/install.ps1 -useb | iex
Arch Linux
Run the package installer:
yay -S flyctl-bin
Linux
Run the install script:
curl -L https://fly.io/install.sh | sh
More info: https://fly.io/docs/getting-started/installing-flyctl/
2. Create an account by running flyctl auth signup
and finishing through the browser
After installing flyctl, you should now be able to use it in the command line. Use flyctl auth signup
to launch your browser and complete the account creation steps. If you already have an account, you can use flyctl auth login
.
3. Add a Dockerfile
with the Python version and dependency install method
Method 1: requirements.txt
Create a list of your dependencies in a requirements.txt
. You can find out what you have installed using pip freeze
.
Discord.py example:
discord.py>=2.0.0,<3
python-dotenv==0.20.0
Nextcord example:
nextcord>=2.5.0,<3
python-dotenv==0.20.0
To tell Fly.io to install these dependencies, create a file called Dockerfile
(no file extension) with the following contents:
FROM python:3.10
WORKDIR /bot
COPY requirements.txt /bot/
RUN pip install -r requirements.txt
COPY . /bot
CMD python bot.py
In this case python bot.py
is the command used to run the bot. If your bot starts in a different file, you should change that here.
Method 2: Using Poetry
If you are using Poetry for dependencies, your Dockerfile
will look more like this:
FROM python:3.10
RUN pip install poetry
WORKDIR /bot
COPY poetry.lock pyproject.toml /bot/
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi
COPY . /bot
CMD python bot.py
(Poetry Dockerfile is based on this tutorial by Replicate.com)
4. flyctl launch
In the project folder, run flyctl launch
Give your project a name, type Y or N depending on if you want a Postgresql database or not, type N to not have it deploy.
This will create a fly.toml
, but you can delete most of it so that it looks similar to this:
app = "my-bot-name" # your bot's app name
primary_region = "den" # a region of your choice
[[services]]
internal_port = 8080
protocol = "tcp"
auto_start_machines = true
auto_stop_machines = false # prevent automatic suspension
min_machines_running = 1 # keep a machine running at all times
5. flyctl deploy
Type flyctl deploy
to deploy the first version!
Once it is completed, your bot will be running on Fly.io!
6. Set the environment vars
If you will be deploying your bot without your .env
or configuration files, you will need to set secrets for fly.io to know about.
This will include all environment variables, for example:
flyctl secrets set 'DISCORD_TOKEN=My.TOken.3213.example' 'LOG_CHANNEL_ID=1234567890'
See https://fly.io/docs/reference/secrets/#setting-secrets
You're done!
To deploy further versions, you can run flyctl deploy
or see below for automatic deploys from GitHub.
Note: If your bot is responding to commands twice, this may mean your bot is running on multiple machines. To fix this, try running the command
fly scale count 1
to remove the extra machine(s). Also, you should ensure your bot is only running in one location; you should not run the bot on fly.io and locally or on another host at the same time.Keep in mind that only shared-cpu-1x 256mb VMs are included for free. Run
fly scale show
to identify the VM resources you are using and update a group by name to be free usingfly scale vm shared-cpu-1x --group app
.
Continuous deployment from GitHub
You can find the video for this part here:
Run
flyctl auth token
to get a Fly API tokenGo to your repo's
Settings > Secrets > Actions
and clickNew repository secret
Enter
FLY_API_TOKEN
as the name and your token from step 1 as the valueCreate a folder,
.github/workflows/
and inside create a file that uses the flyctl action on push. You may name it what you like, for example,fly.yml
.
Example fly.yml
:
name: Fly Deploy
on:
push:
branches:
- main
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
Make sure the branch name is correct for your default branch.
More info: https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/
Conclusion
Thanks for reading!
I hope you found this tutorial useful.
Check out the full videos for further explanations and be sure to like and subscribe!
Part 1 (Setup and Hosting) - https://youtu.be/J7Fm7MdZn_E
Part 2 (Continuous Deployment) - https://youtu.be/6u9BrDaSHJc
- Jonah Lawrence
GitHub: DenverCoder1
YouTube: Jonah Lawrence - Dev Pro Tips
Discord server: https://discord.gg/fPrdqh3Zfu
Subscribe to my newsletter
Read articles from Jonah Lawrence directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jonah Lawrence
Jonah Lawrence
๐ป Full Stack Dev ๐จ UI designer ๐ Student ๐บ Youtuber @ youtube.com/DevProTips ๐ git.io/DenverCoder1