#!/usr/bin/env bash # entrypoint.sh — news-digest worker startup. # # Strategy: # 1. If /output is empty, run digest.py once at start so the page # isn't blank while waiting for the next cron tick. # 2. Start busybox crond in foreground so the container stays up. # # All env vars are inherited from compose, including TZ which busybox # crond honors when computing fire times. set -e mkdir -p /output # Sync static frontend assets from /app/templates → /output. The web # container serves /output as static; the assets are baked into the # image but the bind-mounted /output otherwise wouldn't pick up # CSS/JS updates on rebuild without a manual copy. for asset in style.css app.js favicon.svg; do if [ -f "/app/templates/$asset" ]; then cp -f "/app/templates/$asset" "/output/$asset" fi done if [ ! -f /output/index.html ]; then echo "[entrypoint] no /output/index.html yet — running first digest" /usr/local/bin/run-digest.sh || \ echo "[entrypoint] first run failed; cron will retry on schedule" fi # Render the crontab from env so each per-user instance can fire on # its own schedule. Defaults match the original singleton (0800 / 2000 # local). Two separate vars (AM / PM) instead of one combined string # so users can tweak one fire without re-deriving the other. CRON_AM="${DIGEST_CRON_AM:-0 8 * * *}" CRON_PM="${DIGEST_CRON_PM:-0 20 * * *}" mkdir -p /etc/crontabs { echo "# news-digest cron — generated at container start from env." echo "$CRON_AM /usr/local/bin/run-digest.sh" echo "$CRON_PM /usr/local/bin/run-digest.sh" } > /etc/crontabs/root echo "[entrypoint] crontab:" sed 's/^/ /' /etc/crontabs/root # Foreground crond. -L /dev/stdout sends cron stdout/stderr to docker logs. echo "[entrypoint] starting crond" exec crond -f -L /dev/stdout -l 8