Redis, tasks, and scheduled jobs¶
Redis sidecar¶
add_django_website(..., redis_sidecar=True) (default) attaches a Redis container (mcr.microsoft.com/mirror/docker/library/redis:7.2) to the Web App and sets REDIS_SIDECAR=true.
Django settings then configure django_redis against redis://localhost:6379/0, with exceptions ignored so the site can start if Redis is briefly unavailable.
Django tasks¶
django_tasks=True (default) requires redis_sidecar=True and sets DJANGO_TASKS=true. Settings wire:
RQ_QUEUESusing the Redis cacheTASKSbackenddjango_tasks_rq.RQBackend
patch_django_settings_for_azure adds django_rq and django_tasks_rq to INSTALLED_APPS.
When DJANGO_TASKS=true, startup starts the worker through supervisorctl:
(with a long timeout so Entra credentials can refresh). The program is defined with autostart=false, so an app that disables tasks never runs it, and its output goes to the container's stdout/stderr so it appears in the App Service log stream.
Worker only accepts django.tasks Tasks
The worker uses django_tasks_rq.Job, which rejects plain callables with
SuspiciousOperation: Task … does not point to a Task. Background work must
be defined with @task / @task() and enqueued via .enqueue().
Scheduled tasks (rqcron)¶
django_rq_cron=True (default False) requires redis_sidecar=True and sets:
DJANGO_RQ_CRON=trueRQ_CRON_CONFIGdefaulting tocron_config.py
Override the config path by passing RQ_CRON_CONFIG in environment_variables before the default is applied.
At startup, supervisord runs the RQ worker. When DJANGO_RQ_CRON=true, startup also starts the cron program (defined in cicd/supervisord.conf with autostart=false):
(with the same 6-hour timeout pattern as the RQ worker).
Registering cron jobs (required pattern)¶
Because the worker only accepts django-tasks Tasks, do not call rq.cron.register with a plain function, and do not pass a Task object directly to rq.cron.register (Task has no __name__, so config import fails).
Use pulumi_django_azure.cron.register_task with a @task-decorated callable:
# cron_config.py
from django.tasks import task
from pulumi_django_azure.cron import register_task
@task()
def send_report() -> None:
...
register_task(send_report, queue_name="default", cron="0 9 * * *")
Or register a Task defined elsewhere:
# cron_config.py
from myapp.tasks import send_report
from pulumi_django_azure.cron import register_task
register_task(send_report, queue_name="default", cron="0 9 * * *")
Use queue_name="default" so the existing supervisord RQ worker picks up scheduled jobs.
Why a helper?
register_task adapts the Task for RQ cron registration and enqueues via
task.enqueue() so jobs carry the metadata django_tasks_rq.Job expects.
Plain rq.cron.register(func) and rq.cron.register(task) are both broken
under the default django_tasks=True worker.
Enable in Pulumi:
Custom config path:
django.add_django_website(
# ...
environment_variables={"RQ_CRON_CONFIG": "myapp/cron_config.py"},
django_rq_cron=True,
)
Setting django_rq_cron=True with redis_sidecar=False raises ValueError.
Disabling¶
Setting django_tasks=True with redis_sidecar=False raises ValueError.