#!/bin/sh # backhaul-agent container entrypoint. Bootstraps the newest agent script, installs a # once-a-minute cron job (heartbeat + poll for work + self-update), runs once immediately, # then hands off to cron. All config comes from env passed to `docker run`. set -eu : "${BACKHAUL_URL:?set BACKHAUL_URL (e.g. https://backhaul.skui.io)}" : "${BACKHAUL_TOKEN:?set BACKHAUL_TOKEN (from the backhaul admin)}" APP=/app/backhaul-agent.py LOG=/var/log/backhaul-agent.log touch "$LOG" # Cron jobs run with a bare environment, so persist the vars the agent needs to a file # the cron command sources. Single-quoted to survive spaces/specials in values. { printf "export BACKHAUL_URL='%s'\n" "$BACKHAUL_URL" printf "export BACKHAUL_TOKEN='%s'\n" "$BACKHAUL_TOKEN" printf "export BACKHAUL_TARGETS='%s'\n" "${BACKHAUL_TARGETS:-}" printf "export BACKHAUL_AUTOUPDATE='%s'\n" "${BACKHAUL_AUTOUPDATE:-1}" } > /app/env chmod 600 /app/env # Bootstrap self-update: pull the current script from the app so a fresh container is already # up to date. Compile-check and sanity-check before replacing; keep the bundled copy on any # failure. Disable with BACKHAUL_AUTOUPDATE=0. if [ "${BACKHAUL_AUTOUPDATE:-1}" != "0" ]; then if curl -fsS -H "X-Agent-Token: $BACKHAUL_TOKEN" "$BACKHAUL_URL/api/agent-script" \ -o /tmp/agent.new 2>/dev/null \ && python3 -c "compile(open('/tmp/agent.new').read(),'a','exec')" 2>/dev/null \ && grep -q backhaul-agent /tmp/agent.new; then cp /tmp/agent.new "$APP" echo "bootstrap: fetched latest agent script" fi fi # Every-minute cron job (system crontab format needs the user field). echo "* * * * * root . /app/env; /usr/bin/python3 $APP >> $LOG 2>&1" > /etc/cron.d/backhaul chmod 0644 /etc/cron.d/backhaul # Run once now so the first check-in doesn't wait a full minute. ( . /app/env; /usr/bin/python3 "$APP" >> "$LOG" 2>&1 ) || true echo "backhaul-agent up — check-in every minute; logs at $LOG" cron # daemonize the scheduler exec tail -f "$LOG" # keep PID 1 alive and surface activity in `docker logs`