fix: send-reminder cron

This commit is contained in:
Loïc Gremaud 2026-07-17 18:21:34 +02:00
parent 0277502e47
commit a66d8f9e8e
Signed by: Legrems
GPG Key ID: D4620E6DF3E0121D
4 changed files with 19 additions and 32 deletions

View File

@ -1,8 +1,7 @@
# Copy to .env (which is gitignored) — `make env` generates one with fresh secrets.
# Both the systemd service and the reminder cron job read this file.
#
# Values must stay shell-safe and unquoted: the cron wrapper sources this file, so
# a secret containing ')' or '$' would break it. `make env` uses a URL-safe alphabet.
# Read by the systemd service (EnvironmentFile) and the reminder cron job
# (uv run --env-file), both of which want plain unquoted KEY=value lines.
# `make env` uses a URL-safe alphabet for the generated secrets.
DJANGO_SECRET_KEY=change-me
DJANGO_DEBUG=0

View File

@ -6,10 +6,13 @@ USER := $(shell id -un)
PORT ?= 8000
SERVICE := osiris
UNIT_FILE := /etc/systemd/system/$(SERVICE).service
REMINDER_SH := $(PROJECT_DIR)/deploy/send-reminders.sh
CRON_SCHED ?= * * * * *
CRON_LOG ?= $(PROJECT_DIR)/reminders.log
MANAGE := $(UV) run python manage.py
# The reminder job as one line: cron's environment is nearly empty, so uv is
# called by absolute path and loads .env (VAPID keys) itself via --env-file.
# --no-sync: don't resolve dependencies (needs network) on a cron tick.
REMINDER_CMD := cd $(PROJECT_DIR) && $(UV) run --no-sync --env-file .env python manage.py send_reminders
.PHONY: help
help: ## Show this help
@ -88,24 +91,23 @@ service-uninstall: ## Stop and remove the systemd service
# --- cron ------------------------------------------------------------------
# The script path is the marker: it identifies our line without needing a literal
# '#' comment, which make would strip as a comment of its own.
# 'send[-_]reminders' is the marker identifying our line, so reinstalling stays
# idempotent and also cleans up entries from the old wrapper-script era.
.PHONY: cron
cron: ## Install the reminder cron job (every 10 minutes, idempotent)
@chmod +x $(REMINDER_SH)
@( crontab -l 2>/dev/null | grep -vF '$(REMINDER_SH)' ; \
echo "$(CRON_SCHED) $(REMINDER_SH) >> $(CRON_LOG) 2>&1" ) | crontab -
cron: ## Install the reminder cron job (idempotent)
@( crontab -l 2>/dev/null | grep -vE 'send[-_]reminders' ; \
echo "$(CRON_SCHED) $(REMINDER_CMD) >> $(CRON_LOG) 2>&1" ) | crontab -
@echo "Installed:"
@crontab -l | grep -F '$(REMINDER_SH)'
@crontab -l | grep -F 'send_reminders'
.PHONY: cron-remove
cron-remove: ## Remove the reminder cron job
@crontab -l 2>/dev/null | grep -vF '$(REMINDER_SH)' | crontab -
@crontab -l 2>/dev/null | grep -vE 'send[-_]reminders' | crontab -
@echo "Removed."
.PHONY: cron-test
cron-test: ## Run the reminder job once, reporting what it would send
$(REMINDER_SH) --dry-run
@$(REMINDER_CMD) --dry-run
# --- Frontend --------------------------------------------------------------

View File

@ -122,10 +122,12 @@ and so on. A dose with no reminder time never notifies.
**3. Turn reminders on** in the Reminders card on the Today page, and use **Send
test** there to confirm the whole chain works before trusting it with the cat.
**4. Run the sender from cron**, every ten minutes:
**4. Run the sender from cron** — `make cron` installs the line below. Cron's
environment is nearly empty, so `uv` is called by absolute path and loads
`.env` (the VAPID keys) itself:
```cron
*/10 * * * * cd /path/to/Osiris && uv run python manage.py send_reminders >> /var/log/osiris-reminders.log 2>&1
*/10 * * * * cd /path/to/Osiris && /path/to/uv run --no-sync --env-file .env python manage.py send_reminders >> reminders.log 2>&1
```
The command only pushes a dose that is due and not already ticked off, and

View File

@ -1,16 +0,0 @@
#!/usr/bin/env bash
# Wrapper for the reminder cron job. Cron runs with almost no environment, so the
# settings (and the VAPID keys) have to be loaded explicitly.
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$PROJECT_DIR"
if [ -f .env ]; then
set -a
# shellcheck disable=SC1091
. ./.env
set +a
fi
exec "${UV:-uv}" run --no-sync python manage.py send_reminders "$@"