Working examples
Each recipe is a small, readable starting point. Copy one into loops.yaml,
review its paths and credentials, run it once on demand, then add a schedule when you
trust the result.
18 / 18 shown
Snapshot a SQLite DB and push it to an R2 bucket. Offsite backup in two lines.
sqlite3 app.db ".backup /tmp/app-$(date +%F).db" && \ wrangler r2 object put backups/app-$(date +%F).db --file /tmp/app-$(date +%F).db
needs: sqlite3 · wrangler
Rsync-style upload of a working directory to R2 so a wiped VPS costs you nothing.
tar czf /tmp/site.tgz ./site && \ wrangler r2 object put backups/site-$(date +%FT%H).tgz --file /tmp/site.tgz
needs: tar · wrangler
Compressed pg_dump straight into object storage. Keep the last 7 by date in the key.
pg_dump "$DATABASE_URL" | gzip | \ wrangler r2 object put db/pg-$(date +%F).sql.gz --pipe
needs: pg_dump · gzip · wrangler
Alert before a certificate expires. Catches the outage everyone forgets about.
END=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null \ | openssl x509 -noout -enddate | cut -d= -f2); \ echo "cert for $DOMAIN expires $END"
needs: openssl · curl
Hit a URL, fail loud on non-200. The whole monitoring stack you need on day one.
curl -fsS -o /dev/null -w "%{http_code}" https://example.com/health \
|| echo "DOWN at $(date)" needs: curl
Warn when the VPS disk crosses 85%. Cheap insurance against a full-disk 500.
df -P / | awk 'NR==2 && $5+0 > 85 {print "disk " $5 " on " $6}' needs: df · awk
Bust the cache on deploy or schedule. One API call, no dashboard clicking.
curl -fsS -X POST \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}' needs: curl
Point a Cloudflare DNS record at your current IP. Self-hosted from a dynamic address.
IP=$(curl -fsS https://api.ipify.org); \
curl -fsS -X PATCH \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
--data "$(jq -n --arg ip "$IP" '{type:"A",content:$ip}')" needs: curl · jq
Pull latest, deploy a Worker. A one-box CD pipeline with no CI service.
git -C ./app pull --ff-only && \ cd ./app && wrangler deploy
needs: git · wrangler
Pipe the day’s log through a model and get a plain-English summary. Your agent in cron.
TAIL=$(tail -c 6000 app.log | jq -Rs .); \
curl -fsS "https://api.cloudflare.com/client/v4/accounts/$ACCT/ai/run/@cf/meta/llama-3.1-8b-instruct" \
-H "Authorization: Bearer $CF_API_TOKEN" \
--data "{\"prompt\":\"Summarize today's errors: \"$TAIL}" needs: curl · jq
Fetch a feed, post new items to a chat webhook. Stay current without opening a tab.
curl -fsS https://example.com/feed.json \ | jq -r '.items[0:5][] | "• \(.title) — \(.url)"' \ | curl -fsS "$CHAT_WEBHOOK" --data-binary @-
needs: curl · jq
Hash a page, ping you when it changes. Price drops, stock, job posts — anything.
NEW=$(curl -fsS https://example.com/item | sha1sum | cut -c1-12); \ OLD=$(cat .item-hash 2>/dev/null); \ [ "$NEW" != "$OLD" ] && echo "changed" && echo "$NEW" > .item-hash
needs: curl · sha1sum
Poll a GitHub repo’s latest release; notify on a new tag. No webhooks to host.
TAG=$(curl -fsS https://api.github.com/repos/$REPO/releases/latest | jq -r .tag_name); \ [ "$TAG" != "$(cat .last-tag 2>/dev/null)" ] && \ echo "new release $TAG" && echo "$TAG" > .last-tag
needs: curl · jq
Keep the last 5k lines of a log file. The unglamorous chore that prevents a 3am page.
tail -n 5000 app.log > app.log.tmp && mv app.log.tmp app.log
needs: tail · mv
Delete files older than 7 days from a scratch dir. Boring, essential, two seconds.
find /tmp/scratch -type f -mtime +7 -delete
needs: find
Pull a CSV and import it into a D1 table. A nightly ETL in one command.
curl -fsS https://example.com/export.csv -o /tmp/in.csv && \ wrangler d1 execute mydb --command \ ".import /tmp/in.csv records"
needs: curl · wrangler
Save a daily copy of an API response. Cheap history you can diff later.
curl -fsS https://api.example.com/stats \ | jq . > snapshots/stats-$(date +%F).json
needs: curl · jq
Resize every new image in a folder. ffmpeg/ImageMagick + cron beats a SaaS.
for f in inbox/*.jpg; do \ [ -f "thumbs/$(basename "$f")" ] || convert "$f" -resize 400x "thumbs/$(basename "$f")"; \ done
needs: ImageMagick