Hosting a Python Discord Bot for Free with

Hosting a Python Discord Bot for Free with

Aug 29, 2022ยท

4 min read


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

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 | sh


Run the Powershell install script:

iwr -useb | iex

Arch Linux

Run the package installer:

yay -S flyctl-bin


Run the install script:

curl -L | sh

More info:

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. example:>=2.0.0,<3

Nextcord example:


To tell to install these dependencies, create a file called Dockerfile (no file extension) with the following contents:

FROM python:3.10
COPY requirements.txt /bot/
RUN pip install -r requirements.txt
COPY . /bot
CMD python

In this case python 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
COPY poetry.lock pyproject.toml /bot/
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi
COPY . /bot
CMD python

(Poetry Dockerfile is based on this tutorial by

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

  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!

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 to know about.

This will include all environment variables, for example:

flyctl secrets set 'DISCORD_TOKEN=My.TOken.3213.example' 'LOG_CHANNEL_ID=1234567890'


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 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 using fly scale vm shared-cpu-1x --group app.

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
      - main

  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

    name: Deploy app
    runs-on: ubuntu-latest
      - 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:


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) -

Part 2 (Continuous Deployment) -

- Jonah Lawrence

GitHub: DenverCoder1

YouTube: Jonah Lawrence - Dev Pro Tips

Discord server: