Sign in with Discord, Google, GitHub, or email and password. Free hosting works with any sign-in method and requires a verified email address. Claim a free bot and choose discord.py, or See pricing if the bot needs more than the free allocation. Starter is $0.99 a month. Pro and Plus raise the memory and CPU limits. Paid plans do not renew each week.
Prepare the project
Pin discord.py in requirements.txt. Keep the project importable from the main file you name in MAIN_FILE. The default is main.py. Read the token from the environment. A typical line is to construct the client, then call start with the value of BOT_TOKEN. Do not print the token, and do not write it into a committed file. If you need other secrets, add them as panel variables or as an untracked file in the file manager.
Intents belong in the developer portal and in the client constructor. A bot that needs the message content intent will sit silent until that intent is enabled in both places. Privileged intents are a Discord setting, not a host setting. If the console shows a login error, the token is wrong or the bot was reset in the portal. Generate a new token and paste it again. The old one is dead.
Step-by-step: deploy a discord.py bot.
Install and start
On start, the template installs requirements.txt with pip when that file exists, then runs the main file. The first boot is slower because the image builds the environment. Later boots reuse the installed packages unless you change the file. If pip fails, the console shows the package name. Fix the pin, push or upload the file, and start again. A crash loop is treated as abuse when it restarts too often. Fix the exception instead of masking it with a restart script.
GitHub
Free supports public GitHub deploy within its disk limit; paid plans also support private tokens. Put the project in a repository. On the account page, connect owner/name and the branch you want, usually main. In the panel, set GIT_REPO to the clone URL, GIT_BRANCH to the same branch, and AUTO_UPDATE to 1. Private repositories on paid plans use GIT_TOKEN. The startup script passes that token through an ask-pass helper. It does not put the token in the remote URL. Add the webhook the account page shows. Content type is application/json, and the event is push only. Copy the secret when it is shown. A later visit does not reveal it. Connecting again mints a new secret and the old webhook stops working.
A push to that branch is checked with the GitHub signature. The host restarts the server. The startup fetches the branch with a depth of one and resets the tracked files to that commit. Untracked files such as .env stay. The console prints DEPLOY_COMMIT and the sha. A push to a different branch is ignored. Tags are ignored. A repeated delivery of the same push is ignored.
When Python is the wrong tool
A large music bot, a Java moderation suite, or a Node dashboard is a different template. The Python template is for discord.py and other Python processes. If you outgrow the free memory limit, the pricing page lists Starter, Pro, and Plus. RAM on every plan is an allocated limit.