How can I run scheduled URL availability checks with GitHub Actions? #209320
Replies: 4 comments
|
For this, a plain GitHub-hosted ubuntu runner is plenty. Use the schedule trigger with a cron expression and run curl with --fail and --max-time 20, so timeouts fail cleanly instead of hanging. Write a short summary to the job summary with $GITHUB_STEP_SUMMARY and upload only a small JSON artifact rather than full logs, which keeps storage low. Keep any tokens in secrets and mask them with ::add-mask:: so they never appear in logs. If you already run ARC, a short-lived ephemeral runner per check is the right pattern; keeping one warm for a check this light just wastes resources. |
|
Hi @edwardjames12, for a check this light, I'd use a plain GitHub-hosted name: URL check
on:
schedule:
- cron: "*/15 * * * *"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: url-check
cancel-in-progress: false
jobs:
check:
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- name: Check URL
env:
URL: https://fdown.media
run: |
curl_exit=0
out=$(curl -sS -L -o /dev/null \
--connect-timeout 10 \
--max-time 20 \
-w '%{http_code} %{time_total}' \
"$URL") || curl_exit=$?
if [ "$curl_exit" -ne 0 ]; then
code=0
secs=0
else
code=${out%% *}
secs=${out##* }
fi
echo "{\"url\":\"$URL\",\"status\":$code,\"seconds\":$secs,\"curl_exit\":$curl_exit,\"checked_at\":\"$(date -u +%FT%TZ)\"}" > result.json
echo "| $URL | $code | ${secs}s | curl exit $curl_exit |" >> "$GITHUB_STEP_SUMMARY"
[ "$curl_exit" -eq 0 ] && [[ "$code" =~ ^2 ]] || exit 1
- name: Save result
if: always()
uses: actions/upload-artifact@v4
with:
name: url-check-result
path: result.json
retention-days: 7
How this maps to your questions:
One other distinction is important: a |
|
For a lightweight scheduled URL-monitoring workflow, the main design question is whether you actually need ARC. For many simple checks, a GitHub-hosted runner is sufficient; ARC becomes more useful when you need Kubernetes-based, autoscaled, ephemeral self-hosted runners. Recommended setup For your use case, I'd start with a GitHub-hosted runner: name: URL Monitor on: jobs: For a small monitoring job, keeping a self-hosted runner permanently available generally isn't necessary. With ARC, an ephemeral runner per job is usually the better isolation model when you do need self-hosted infrastructure. If you use ARC A reasonable architecture is: Scheduled workflow This gives each monitoring execution a clean environment and avoids maintaining an idle runner between checks. Practical recommendations Timeouts Use several layers rather than allowing curl to run indefinitely: curl --connect-timeout 5 --max-time 20 ... and also set a job-level timeout: timeout-minutes: 2 Results For a simple monitor, you probably don't need to retain full logs as artifacts every time. A workflow summary containing: timestamp is usually enough. Keep artifacts for cases where you actually need historical/debugging information. Credentials Don't put tokens directly into: run: echo "$TOKEN" Use GitHub Actions secrets: env: and avoid printing the environment or complete request headers. Important: if the endpoint itself is public, you don't need credentials just to perform an availability check. One additional consideration If the purpose is simply continuous website monitoring, GitHub Actions isn't necessarily the most natural monitoring infrastructure. Scheduled workflows can be delayed, particularly during periods of Actions load, so they shouldn't be treated as a precise uptime-monitoring clock. For example, */10 * * * * means request the job approximately every ten minutes, not necessarily perform the HTTP request exactly every ten minutes. For lightweight periodic checks, GitHub Actions is perfectly reasonable for development/testing. For strict uptime monitoring and alerting, a dedicated monitoring service or continuously running monitoring system is generally more appropriate. So, for your stated workload: GitHub-hosted ubuntu-latest → simplest choice. |
|
I actually went through this exact setup last month, and the reference comment is spot on. For a lightweight URL check, spinning up a full ARC runner is overkill and will definitely feel wasteful in your billing. A simple Here is the workflow snippet I use that covers most of your best practices: on:
schedule:
- cron: '*/15 * * * *'
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Check URL
run: |
start_time=$(date +%s%3N)
http_code=$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 --fail https://fdown.media)
end_time=$(date +%s%3N)
duration=$((end_time - start_time))
echo "HTTP Code: $http_code"
echo "Duration: ${duration}ms"
# Write to summary
echo "### 🟢 $http_code in ${duration}ms" >> $GITHUB_STEP_SUMMARYA few tips from my experience:
Since this is just a heartbeat check, I wouldn't touch ARC unless your other workflows force you to. Keep it simple, and you'll have a reliable monitor running for pennies. |
Uh oh!
There was an error while loading. Please reload this page.
🏷️ Discussion Type
Question
💬 Feature/Topic Area
ARC (Actions Runner Controller)
Discussion Details
Hi everyone,
I'm working on a small web-service monitoring workflow and I'm trying to understand the best way to run periodic URL availability checks with GitHub Actions.
The basic workflow I have in mind is:
One of the services I'm testing is fdown.media, so I'm using it as an example endpoint rather than as an Actions-related product.
I'm particularly interested in the runner side of this. If using Actions Runner Controller, would you recommend creating a short-lived runner for each monitoring job, or keeping a runner available for recurring checks?
I'm also interested in best practices for:
For a lightweight scheduled monitoring task like this, what runner setup would you recommend?
All reactions