I am creating some cronjobs that use the "make" command to execute python scripts. These cronjobs are executed inside of a docker container. I can run my cronjobs using the make command fine inside of my container when using docker desktop on my windows laptop, and commands like * * * * * cd /code && make help return the expected output, which is an echo output of all make commands available for my project. I tested these cronjobs on mac as well where it also worked.
When I however attempt to run that same cronjob on a linux laptop running "fedora server" I don't seem to be able to get "make" working correctly, (this is a physical computer, not a VM).
Cronjobs are run from the directory "/etc/crontabs/root" inside of the container. The cronjob * * * * * cd /code && make help executing inside of my docker container on my linux installation, gives the response
crond: USER root pid 132 cmd cd /code && make help '. Stop. No rule to make target 'help.
Basic cronjobs like * * * * * echo 'Hello world' output the expected response on both machines. I can also run make commands manually on either computer while inside of the "/code" directory such as make help.
I export the project folder from my windows laptop to the directory "notroot@localhost:~/compose" which is owned by a non-root user on my linux laptop, using the FileZilla Client (any tips of a better way to this is very much welcomed). I use "docker compose" to create and run my containers from the directory "notroot@localhost:~/compose/xcron".
My project has a structure that looks like this:
/xcron
- .env
- requirements.txt
- Makefile
- /api
- /spotify
- ...
- /leetcode
- ...
- ...
My compose file, docker-compose.yml:
services:
xcron-app:
container_name: xcronapp
restart: always
build: .
networks:
- xcron_db_network
- xcron_web_network
volumes:
- xcronvol:/code
db:
container_name: xcronpostgres
image: postgres
restart: always
ports:
- "5432:5432"
environment:
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
volumes:
- postgresvolume:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_NAME}"]
interval: 10s
retries: 5
start_period: 30s
timeout: 10s
networks:
- xcron_db_network
networks:
xcron_db_network:
driver: bridge
xcron_web_network:
driver: bridge
volumes:
xcronvol:
postgresvolume:
The Dockerfile used in my project is given below. There are some files that are not copied over from the project files such as a python venv folder that is never meant to be used inside of the containers. Dockerfile:
FROM alpine:latest
COPY config/cronjobs /etc/crontabs/root
COPY requirements.txt /etc/requirements/requirements.txt
ENV PYTHONUNBUFFERED=1
RUN apk add --update --no-cache python3 py3-pip make bash util-linux vim && ln -sf python3 /usr/bin/python
COPY .env /code/.env
COPY api /code/api
COPY auth /code/auth
COPY migrations/down /code/migrations/down
COPY migrations/up /code/migrations/up
COPY migrations/down.py /code/migrations/down.py
COPY migrations/up.py /code/migrations/up.py
COPY tweets /code/tweets
COPY Makefile /code/Makefile
RUN python3 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install -r /etc/requirements/requirements.txt
RUN chmod 777 /etc/crontabs/root
WORKDIR /code
CMD ["crond", "-f", "-d", "8"]
After running 'docker compose up', my files inside of the docker container are structured in the same way as before, (except for files that were ignored in the Dockerfile), but the base folder is now named "code".
/code
- .env
- Makefile
- /api
- /spotify
- ...
- /leetcode
- ...
- ...
I have tried adding permissions inside of my docker container to my files using chmod 777 <filename> on my "code/Makefile", "code/.env" file, "/etc/crontabs/root". I have tried altering my cronjob with absolute paths such as /usr/bin/make -C /code help" along with plenty of variations of the "-C" and "-f" flag. I have tried running entering my workspace repository cd /code && make -f /code/Makefile help, and exiting the "root" where I figured my cronjobs were running from cd .. && make -f /code/Makefile -C /code help.
I have attempted running cronjobs via bash explicitly /bin/bash -c 'cd /code && make help'.
Output results from these cronjobs being the same as before crond: USER root pid 123 cmd /usr/bin/make -C /code help '. Stop. No rule to make target 'help.
'help? That almost certainly means you've cut and pasted the contents of your crontab file from Windows, and included the CRLF line endings from Windows rather than using the POSIX-style LF line ending. Usecrontab -l | cat -eand see if you can detect a weird line ending for your crontab line./code # crontab -l | cat -eand received* * * * * cd /code && make help^M$ ^M$as response. I then went and edited the file usingcrontab -einstead ofvimand removed all special characters (^M$), which solved my problem! When previously manually writing to the "etc/crontabs/root" file on docker desktop the file was edited as plaintext which allowed cronjobs to run without issue.