Running Python Scripts in a Virtualenv with Cron

Illustration of a cron config file

Cron is a scheduling service available on Unix-based operating systems. It allows you to automate tasks by running scripts or binaries at fixed times, intervals, or specific dates.
Common use cases include automated backups, maintenance tasks, log cleanup routines, or any job that should run periodically.

In short: cron can run any script or application installed on the system at a defined time. It is supported on most Unix platforms, including Linux and macOS.

In this article, I’ll walk you through how to run Python scripts inside a dedicated Python virtual environment using cronjobs.

Before that, let’s quickly review the syntax of a cron expression.

Cron Expressions Explained

This example runs /path/to/script.sh every minute:

┌───────────── Minute (0...59)
│ ┌───────────── Hour (0...23)
│ │ ┌───────────── Day of month (1...31)
│ │ │ ┌───────────── Month (1...12)
│ │ │ │ ┌───────────── Weekday (0...6; 0: Sunday, 6: Saturday)
│ │ │ │ │
* * * * * /path/to/script.sh

Another example – which runs the script on the 10th day of every month at 08:20:

20 8 10 * * /path/to/script.sh

Managing Cronjobs from the Terminal

By default, many systems open cronjobs in vi. If you prefer nano (as I do), you can switch the editor temporarily for the current terminal session:

export EDITOR=nano

To view all active cronjobs for the current user:

crontab -l

Each system user has their own crontab, managed independently.

To edit your cronjobs:

crontab -e

Here’s an example entry that runs a Python script every minute using the system-wide Python interpreter. Output is redirected to a log file:

* * * * * python3 /opt/my_python_app/main_app.py > /opt/my_python_app/log.txt

Running a Python Script in a Virtualenv via Cron

Now let’s look at how to run a script inside a Python virtual environment. Assume the following setup:

  • Your script is located at: /opt/my_python_app/main_app.py
  • Your virtualenv is located at: /opt/venv_my_python_app
  • Created with the command: python3 -m venv venv_my_python_app
  • Normally, you'd activate it with: source ./venv_my_python_app/bin/activate

To run the script inside the virtualenv via cron every minute, use this cron entry:

* * * * * cd /opt/my_python_app && /opt/venv_my_python_app/bin/python main_app.py

Here’s what happens:

  • cd /opt/my_python_app switches into the directory containing the script.
  • Instead of using the system Python, we call the python binary from the virtualenv.
  • The script main_app.py is executed using that environment’s interpreter and packages.

If you want to log the output:

* * * * * cd /opt/my_python_app && /opt/venv_my_python_app/bin/python main_app.py > my_app_log.txt

Depending on how your script handles file paths, the initial cd may or may not be required. If the script uses relative paths, keeping the cd is recommended.