我正在创建一些使用“make”命令来执行 python 脚本的 cronjobs。这些 cronjobs 在 Docker 容器内执行。当我在 Windows 笔记本电脑上使用 docker 桌面时,我可以使用容器内的 make 命令来运行我的 cronjobs,并且像
* * * * * cd /code && make help
这样的命令会返回预期的输出,这是我的项目可用的所有 make 命令的回显输出。我在 mac 上测试了这些 cronjobs,它也能工作。
然而,当我尝试在运行“fedora 服务器”的 Linux 笔记本电脑上运行相同的 cronjob 时,我似乎无法让“make”正常工作(这是一台物理计算机,而不是虚拟机)。
Cronjobs 从容器内的“/etc/crontabs/root”目录运行。在我的 Linux 安装上的 docker 容器内执行的 cronjob
* * * * * cd /code && make help
给出了响应
crond: USER root pid 132 cmd cd /code && make help '. Stop. No rule to make target 'help
。
像
* * * * * echo 'Hello world'
这样的基本 cronjobs 在两台机器上输出预期的响应。我还可以在“/code”目录(例如 make help
)内的任何一台计算机上手动运行 make 命令。
我使用 FileZilla 客户端将项目文件夹从我的 Windows 笔记本电脑导出到目录“notroot@localhost:~/compose”,该目录由我的 Linux 笔记本电脑上的非 root 用户拥有(任何更好的方法的提示是非常欢迎)。我使用“docker compose”从目录“notroot@localhost:~/compose/xcron”创建并运行我的容器。
我的项目的结构如下所示:
/xcron
- .env
- requirements.txt
- Makefile
- /api
- /spotify
- ...
- /leetcode
- ...
- ...
我的撰写文件,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:
我的项目中使用的Dockerfile如下。有些文件不是从项目文件中复制的,例如永远不会在容器内部使用的 python venv 文件夹。 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"]
运行“docker compose up”后,docker 容器内的文件的结构与以前相同(除了 Dockerfile 中被忽略的文件),但基本文件夹现在名为“code”。
/code
- .env
- Makefile
- /api
- /spotify
- ...
- /leetcode
- ...
- ...
我尝试在“code/Makefile”、“code/.env”文件、“/etc/crontabs/root”上使用
chmod 777 <filename>
将 docker 容器内的权限添加到我的文件中。我尝试使用绝对路径(例如“/usr/bin/make -C /code help
”)以及“-C”和“-f”标志的大量变体来更改我的cronjob。我尝试运行进入我的工作区存储库cd /code && make -f /code/Makefile help
,并退出“root” “我认为我的 cronjobs 是从 cd .. && make -f /code/Makefile -C /code help
运行的。
我尝试通过 bash 显式运行 cronjobs
/bin/bash -c 'cd /code && make help'
。
这些 cronjob 的输出结果与之前相同
crond: USER root pid 123 cmd /usr/bin/make -C /code help '. Stop. No rule to make target 'help
。
在 @MadScientist 的帮助下,通过从 crontab 文件中删除 Windows 结束符 (^M$) 解决了这个问题。