Running Python Scripts on a Schedule with Docker (Cron)
Running a Python script periodically inside a Docker container is a common requirement. While you can use external schedulers (like host cron or Kubernetes CronJobs), sometimes you want a self-contained container that manages its own schedule using the classic Unix cron utility.
Prerequisites
- Docker installed.
- A Python script you want to run.
Step 1: The Python Script
Create a simple script named task.py.
import datetime
# We write to a log file so we can see the output easily via 'docker logs' later
with open("/var/log/cron.log", "a") as f:
f.write(f"Task executed at {datetime.datetime.now()}\n")
print("Task ran successfully.")
Step 2: The Crontab File
Create a file named crontab (no extension). This defines the schedule.
# Run every minute
* * * * * /usr/local/bin/python /app/task.py >> /var/log/cron.log 2>&1
# Don't forget the empty line at the end of this file!
Note: We use absolute paths (/usr/local/bin/python) to ensure cron finds the correct interpreter.
Step 3: The Dockerfile
We need to install cron on top of the Python image.
FROM python:3.11-slim
WORKDIR /app
# 1. Install cron
RUN apt-get update && apt-get install -y cron && rm -rf /var/lib/apt/lists/*
# 2. Copy files
COPY task.py .
COPY crontab /etc/cron.d/my-cron-job
# 3. Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/my-cron-job
# 4. Apply cron job
RUN crontab /etc/cron.d/my-cron-job
# 5. Create the log file to be able to run tail
RUN touch /var/log/cron.log
# 6. Run the command on container startup
# We run cron and tail the log so the container doesn't exit.
CMD cron && tail -f /var/log/cron.log
Step 4: Build and Run
# Build
docker build -t python-cron .
# Run
docker run -d --name my-cron-runner python-cron
Important Considerations
- Environment Variables: Cron runs with a very limited environment. It does not automatically see environment variables passed to
docker run -e .... You often need to explicitly declare them in the crontab or dump them to/etc/environmentat runtime. - Timezones: Docker containers default to UTC. If you need the schedule to run at a specific local time, mount the timezone file:
docker run -v /etc/localtime:/etc/localtime:ro ...