Deploying Your Bots
Deployment, Schedulers, and Keeping Bots Alive
Youโve built incredible automation scripts. But if they only run when your laptop is open, they aren't production systems. In this module, we transition from developer to DevOps. We will learn how to deploy bots to a remote server, schedule them to run automatically, and ensure they automatically restart if they crash.
โฑ๏ธ Task Schedulers (Cron jobs)
If you have a script that needs to run exactly at 8:00 AM every day (like our News Email Digest), you use Cron. Cron is a time-based job scheduler built into Linux/Unix systems.
You open the crontab editor via terminal: crontab -e
# CRON SYNTAX: [Minute] [Hour] [Day of Month] [Month] [Day of Week] [Command] # Run every day at 8:00 AM 0 8 * * * /usr/bin/python3 /home/user/bots/news_digest.py >> /home/user/logs/news.log 2>&1 # Run every 15 minutes (Great for price trackers!) */15 * * * * /usr/bin/python3 /home/user/bots/price_tracker.py
๐งโโ๏ธ Keeping Bots Alive (PM2)
Unlike scheduled scripts, Discord/Telegram bots must run 24/7. If they encounter an unhandled exception, they crash, and your bot goes offline. To prevent this, we use a process manager like PM2.
# Install PM2 (Requires Node.js installed on your server) npm install -g pm2 # Start your Python bot with PM2 pm2 start my_discord_bot.py --interpreter python3 --name "CommunityBot" # Check the status of your bots pm2 status # View real-time logs pm2 logs CommunityBot
With PM2, if your bot crashes due to a network error, PM2 instantly restarts it. Furthermore, you can configure PM2 to start your bots automatically if the server itself reboots: pm2 startup.
โ ๏ธ Handling Failures Gracefully
Even with PM2 restarting your bot, you should handle failures in code so the bot doesn't crash in the first place. The golden rule of deployment: Assume the network will fail.
import requests
from time import sleep
import logging
# Set up logging instead of 'print'
logging.basicConfig(filename='bot_errors.log', level=logging.ERROR)
def robust_fetch(url, retries=3):
for attempt in range(retries):
try:
# Add a timeout! Infinite hangs will freeze your bot.
response = requests.get(url, timeout=10)
response.raise_for_status() # Raise error on 404/500
return response.json()
except requests.exceptions.RequestException as e:
logging.error(f"Attempt {attempt + 1} failed: {e}")
if attempt < retries - 1:
sleep(5) # Backoff before retrying
else:
# Final failure
send_developer_telegram_alert(f"FATAL ERROR: {url} is unreachable.")
return NoneKnowledge Check
Ready to test your understanding of Deploying Your Bots?