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
Mac OS
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.1.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.11
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.11
RUN pip install poetry
WORKDIR /bot
COPY . /bot/
COPY poetry.lock pyproject.toml /bot/
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi
CMD python bot.py
Poetry Dockerfile is based on this tutorial by Replicate.com. Thanks Abraham Murciano for the correction.
  
  
  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 1in order 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.
Continuous deployment from GitHub
You can find the video for this part here:
- Run flyctl auth tokento get a Fly API token
- Go to your repo's Settings > Secrets > Actionsand clickNew repository secret
- Enter FLY_API_TOKENas the name and your token from step 1 as the value
- Create 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 video 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
 
 
              
 
    
Top comments (0)