為了在我的 Django 應用程式中定期執行任務,我安裝了django_crontab擴展程式。我的應用程式由 dockerized 資料庫和 Django 應用程式組成。
https://pypi.org/project/django-crontab/
我已經完成了設定段落中描述的每一步。
settings.py
INSTALLED_APPS = [
...
'django_crontab',
]
...
CRONJOBS = [
('*/1 * * * *', 'config.cron.fun')
]
cron.py
def fun():
print("hello cron")
with open("./test.txt", "a") as f:
f.write("Hello")
我還在以下位置添加了 cron 作業docker-entrypoint.yml:
python manage.py crontab add
python manage.py crontab show
輸出:
webapp | no crontab for root
webapp | adding cronjob: (ebcca28ea3199afe6d09a445db5d5fd8) -> ('*/1 * * * *', 'config.cron.fun')
webapp | Currently active jobs in crontab:
webapp | ebcca28ea3199afe6d09a445db5d5fd8 -> ('*/1 * * * *', 'config.cron.fun')
在Dockerfile我使用python:3.8影像并安裝cron:
RUN apt-get install -y cron && touch /var/log/cron.log
運行容器后沒有回應。
當我進入容器時,我可以看到cron看到了作業,但仍然沒有執行它。
root@bar:/back# crontab -l
*/1 * * * * /usr/local/bin/python /back/manage.py crontab run ebcca28ea3199afe6d09a445db5d5fd8 # django-cronjobs for config
我該如何解決?
編輯:整個 Dockerfile:
FROM python:3.8
ENV PYTHONUNBUFFERED 1
RUN mkdir /back
WORKDIR /back
COPY . /back/
RUN apt-get update
RUN apt-get install -y cron && touch /var/log/cron.log
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ENTRYPOINT ["python3", "manage.py"]
CMD ["runserver", "0.0.0.0:8080"]
docker-compose.yml:
version: "3"
services:
db:
image: postgres:latest
restart: unless-stopped
container_name: database
env_file:
- .env
webapp:
build: ./back
container_name: webapp
restart: unless-stopped
ports:
- "8000:8000"
env_file:
- .env
depends_on:
- db
links:
- db:db
volumes:
- ./back:/back
entrypoint: "bash /back/docker-entrypoint.sh"
command: "runserver 0.0.0.0:8000"
docker-entrypoint.yml- 這里進行了遷移,等待db和提到的crontab命令
uj5u.com熱心網友回復:
一個 Docker 容器只運行一個行程。您需要運行兩個獨立的東西:主應用程式服務器和(在一些初始設定之后)cron 守護行程。您可以使用正確的設定直接運行兩個單獨的容器,這些容器運行來自同一映像的兩個單獨的命令。
我會讓這里的第一個變化是結合你目前擁有的分裂ENTRYPOINT和CMD成單CMD:
# no ENTRYPOINT, but
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8080"]
通過此設定,您可以使用此默認命令啟動一個容器,以及來自同一映像但command:在 Compose 設定中覆寫的第二個命令。
version: '3.8'
services:
db: { ... }
webapp:
build: ./back
restart: unless-stopped
ports:
- "8000:8000"
env_file:
- .env
depends_on:
- db
# run the default command: from the image; no override
# skip unnecessary links:, container_name:, volumes: options
cron:
build: ./back # same as main application
restart: unless-stopped
env_file:
- .env
depends_on:
- db
command: cron -f # as a long-running foreground process
我們在這里沒有做的事情是在容器啟動時填充 crontab。這是ENTRYPOINT可以進來的地方:如果你有ENTRYPOINT,它會運行而不是CMD,但它會作為引數傳遞CMD。這里一個非常典型的模式是ENTRYPOINT用于執行一些首次設定的 shell 腳本,然后exec "$@"以運行所提供的CMD/結束command:。
#!/bin/sh
# docker-entrypoint.sh
# If this is going to be a cron container, set up the crontab.
if [ "$1" = cron ]; then
./manage.py crontab add
fi
# Launch the main container command passed as arguments.
exec "$@"
然后在 Dockerfile 中,將此腳本指定為ENTRYPOINT.
...
WORKDIR /back
COPY . ./ # including docker-entrypoint.sh
...
ENTRYPOINT ["./docker-entrypoint.sh"] # must be JSON-array syntax
CMD ["./manage.py", "runserver", "0.0.0.0:8080"] # as before
你不需要在entrypoint:這里覆寫。docker-compose run web app bash獲得互動式除錯 shell 之類的命令可以正常作業;他們將通過那個入口點腳本,并在最后exec "$@"一行運行 shell 。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/346249.html
