首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何让django-crontab在Docker容器中执行命令?

如何让django-crontab在Docker容器中执行命令?
EN

Stack Overflow用户
提问于 2021-11-01 20:42:17
回答 1查看 159关注 0票数 0

为了在我的Django应用程序中定期执行任务,我安装了django_crontab扩展。我的应用程序包括dockerized数据库和Django应用程序。

https://pypi.org/project/django-crontab/

我已经按照设置段落中的描述完成了每一步。

settings.py

代码语言:javascript
复制
INSTALLED_APPS = [
    ...
    'django_crontab',
]

...

CRONJOBS = [
    ('*/1 * * * *', 'config.cron.fun')
]

cron.py

代码语言:javascript
复制
def fun():
    print("hello cron")
    with open("./test.txt", "a") as f:
        f.write("Hello")

我还在docker-entrypoint.yml中添加了cron作业

代码语言:javascript
复制
python manage.py crontab add
python manage.py crontab show

输出:

代码语言:javascript
复制
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

代码语言:javascript
复制
RUN apt-get install -y cron && touch /var/log/cron.log

并且在运行容器后没有响应。

当我进入容器时,我可以看到cron看到了作业,但仍然没有执行它。

代码语言:javascript
复制
root@bar:/back# crontab -l
*/1 * * * * /usr/local/bin/python /back/manage.py crontab run ebcca28ea3199afe6d09a445db5d5fd8 # django-cronjobs for config

我怎么才能修复它?

编辑:整个Dockerfile:

代码语言:javascript
复制
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

代码语言:javascript
复制
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命令

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-01 23:54:41

Docker容器只运行一个进程。您需要运行两个不同的东西:主应用服务器和(在一些初始设置之后) cron守护进程。通过正确的设置,您可以直接运行两个单独的容器,运行同一映像中的两个单独的命令。

我在这里要做的第一个更改是将您当前作为拆分的ENTRYPOINTCMD合并到一个CMD

代码语言:javascript
复制
# no ENTRYPOINT, but
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8080"]

使用此设置,您可以使用此默认命令启动一个容器,并从相同的映像启动第二个命令,但会覆盖Compose设置中的command:

代码语言:javascript
复制
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,但它会运行passed the CMD as arguments。这里的一个非常典型的模式是,对执行一些首次设置的shell脚本使用ENTRYPOINT,然后以exec "$@"结束,以运行所提供的CMD/command:

代码语言:javascript
复制
#!/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

代码语言:javascript
复制
...
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的命令可以很好地工作;它们将通过该入口点脚本运行shell,并作为最终的exec "$@"行运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69802579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档