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
.
This problem was solved with the help of @MadScientist, by removing Windows endline characters (^M$) from the crontab file, by using the crontab -e
command while inside of the docker container.
vim -b
was used to remove endline characters in the project files before using docker compose.