DEV Community

Cover image for Hosting a Python Discord Bot for Free with Fly.io
Jonah Lawrence
Jonah Lawrence

Posted on • Edited on • Originally published at jonahlawrence.hashnode.dev

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

Mac OS

If you have the Homebrew package manager installed, flyctl can be installed by running:

brew install flyctl
Enter fullscreen mode Exit fullscreen mode

If not, you can run the install script:

curl -L https://fly.io/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

Windows

Run the Powershell install script:

iwr https://fly.io/install.ps1 -useb | iex
Enter fullscreen mode Exit fullscreen mode

Arch Linux

Run the package installer:

yay -S flyctl-bin
Enter fullscreen mode Exit fullscreen mode

Linux

Run the install script:

curl -L https://fly.io/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Nextcord example:

nextcord>=2.1.0,<3
python-dotenv==0.20.0
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 in 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:

  1. Run flyctl auth token to get a Fly API token
  2. Go to your repo's Settings > Secrets > Actions and click New repository secret
  3. Enter FLY_API_TOKEN as the name and your token from step 1 as the value
  4. 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
Enter fullscreen mode Exit fullscreen mode

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)