I am trying to install Python dependencies using Poetry
and then run a Python script in a Docker
container using a cronjob
. However, the python script doesn't execute as expected, and I can't figure out what tweaks to my Docker/crontab setup is causing problems. I have followed several different StackOverflow threads (like this one) on how to configure cron
in a container, but none of them are consistently working in my use case. Here is the Dockerfile
definition:
FROM python:3.11
RUN apt-get update && apt-get -y install cron
# Install Poetry
RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python3 && \
cd /usr/local/bin && \
ln -s /opt/poetry/bin/poetry && \
poetry config virtualenvs.create false
WORKDIR /app
# Copy using poetry.lock* in case it doesn't exist yet
COPY ./app/poetry.lock* ./app/pyproject.toml /app/
RUN poetry install --no-root --no-dev
COPY ./app/app/example.py /app/
# Copy hello-cron file to the cron.d directory
COPY ./app/cronjob /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
RUN chmod a+x /app/example.py
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
The cronjob
file that is being used to create the crontab
:
# Example crontab
* * * * * /app/example.py 2>&1
* * * * * echo $(date) >> /app/example.log 2>&1
# empty line
And the simple Python script (example.py):
#!/usr/local/bin/python
from loguru import logger
from pathlib import Path
f = Path("/app/info.log")
f = str(f) if f.exists() else "./info.log"
logger.add(
f,
format="{time:YYYY-MM-DD at HH:mm:ss} {level} {message}",
level="INFO",
rotation="10 MB",
)
logger.info("working")
I have tried several different options to get the python script to run every minute, such as removing the shebang and explicitly specifying the python path (/usr/local/bin/python
) in the crontab, but have had no luck. Interestingly, the second line of the crontab
that writes the time to /app/example.log
works as expected. Additionally, manually running the script from the container's bash
shell also works and creates the /app/info.log
file.
Are there any obvious issues with the Dockerfile/crontab setup?