How to Deploy a Python Script and Run It on a Schedule

How to Deploy a Python Script and Run It on a Schedule
You’ve got a Python script that works on your laptop: it syncs two spreadsheets, posts a daily summary to Slack, or checks a price. Now you want it to run every hour, or every morning, without your laptop being on.
Here’s how to get that in three steps, with no server to rent and no crontab to edit.
Step 1: Put the schedule in the script
Your script will run in a container that stays on. So instead of asking a cron daemon to start it, the script repeats itself: do the work, wait, go again.
For “every N minutes”, a loop is enough:
import time
import traceback
def job():
print("checking the price…")
while True:
try:
job()
except Exception:
traceback.print_exc()
time.sleep(10 * 60)
For “every day at 08:00”, add schedule to your requirements.txt and use it:
import time
import schedule
def daily_summary():
print("posting today's summary")
schedule.every().day.at("08:00").do(daily_summary)
while True:
schedule.run_pending()
time.sleep(30)
Two things to know:
- Times are UTC. 08:00 in the script is 08:00 UTC.
- Don’t let the script end. If it finishes, it stays stopped until your
next deploy. The
while Trueloop is what keeps it scheduled. Thetry/exceptin the first example keeps one bad run from taking the loop down with it.
Step 2: Deploy it
cd price-checker
pbc deploy --name price-checker
The script is detected and started with python main.py, with your
dependencies installed from requirements.txt, pyproject.toml, a Pipfile,
or a lockfile. If your folder has more than one script, pick the one to run
with --start "python checker.py".
Step 3: Add secrets and watch it run
Put tokens in a .env next to the script. pbc deploy sends them along and
the script reads them with os.environ["SLACK_TOKEN"]. They never go into
your code.
Then watch the output:
pbc logs backend --name price-checker -f
Every print() shows up straight away, in the terminal and on the backend’s
Logs page in the portal.
What it costs
Scheduled scripts run as a backend, and backends are on the Pro plan: a flat monthly price, not billed per run or per minute. So a script that wakes up every minute costs the same as one that runs once a day. Details are on the pricing page.
If the job only touches your PocketBase data, you can skip the backend: a
cronAdd hook runs it inside
PocketBase itself.
Next steps
- Run a Python Script on a Schedule: the reference version of this guide
- How to deploy a Flask, Django, or FastAPI app
- Backend Environment Variables