From b7c769fc0e2f238e5f9782bbad3462fa72a712a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Thu, 21 Jan 2021 11:35:09 +0200 Subject: [PATCH] Add a section in Docs about running self-hosted instances Fixes: #467 --- CHANGELOG.md | 1 + hc/front/views.py | 30 +- hc/settings.py | 2 +- templates/docs/api.html | 65 +-- templates/docs/attaching_logs.html | 12 +- templates/docs/bash.html | 11 +- templates/docs/cloning_checks.html | 2 +- templates/docs/configuring_prometheus.html | 3 +- templates/docs/csharp.html | 2 +- templates/docs/go.html | 2 +- templates/docs/http_api.html | 35 +- templates/docs/javascript.html | 5 +- templates/docs/measuring_script_run_time.html | 3 +- templates/docs/monitoring_cron_jobs.html | 14 +- templates/docs/php.html | 6 +- templates/docs/powershell.html | 8 +- templates/docs/python.html | 8 +- templates/docs/reliability_tips.html | 6 +- templates/docs/ruby.html | 2 +- templates/docs/self_hosted.html | 86 ++++ templates/docs/self_hosted.md | 81 +++ templates/docs/self_hosted_configuration.html | 301 +++++++++++ templates/docs/self_hosted_configuration.md | 476 ++++++++++++++++++ templates/docs/signaling_failures.html | 8 +- templates/front/base_docs.html | 4 + 25 files changed, 1034 insertions(+), 139 deletions(-) create mode 100644 templates/docs/self_hosted.html create mode 100644 templates/docs/self_hosted.md create mode 100644 templates/docs/self_hosted_configuration.html create mode 100644 templates/docs/self_hosted_configuration.md diff --git a/CHANGELOG.md b/CHANGELOG.md index eeb57a6f..35098918 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - Improve the crontab snippet in the "Check Details" page (#465) - Add Signal integration (#428) - Change Zulip onboarding, ask for the zuliprc file (#202) +- Add a section in Docs about running self-hosted instances ## Bug Fixes - Fix unwanted HTML escaping in SMS and WhatsApp notifications diff --git a/hc/front/views.py b/hc/front/views.py index 1442e2e7..0b614b63 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -325,21 +325,23 @@ def serve_doc(request, doc="introduction"): if not os.path.exists(path): raise Http404("not found") - replaces = { - "{{ default_timeout }}": str(int(DEFAULT_TIMEOUT.total_seconds())), - "{{ default_grace }}": str(int(DEFAULT_GRACE.total_seconds())), - "SITE_NAME": settings.SITE_NAME, - "SITE_ROOT": settings.SITE_ROOT, - "SITE_HOSTNAME": site_hostname(), - "SITE_SCHEME": site_scheme(), - "PING_ENDPOINT": settings.PING_ENDPOINT, - "PING_URL": settings.PING_ENDPOINT + "your-uuid-here", - "IMG_URL": os.path.join(settings.STATIC_URL, "img/docs"), - } - content = open(path, "r", encoding="utf-8").read() - for placeholder, value in replaces.items(): - content = content.replace(placeholder, value) + + if not doc.startswith("self_hosted"): + replaces = { + "{{ default_timeout }}": str(int(DEFAULT_TIMEOUT.total_seconds())), + "{{ default_grace }}": str(int(DEFAULT_GRACE.total_seconds())), + "SITE_NAME": settings.SITE_NAME, + "SITE_ROOT": settings.SITE_ROOT, + "SITE_HOSTNAME": site_hostname(), + "SITE_SCHEME": site_scheme(), + "PING_ENDPOINT": settings.PING_ENDPOINT, + "PING_URL": settings.PING_ENDPOINT + "your-uuid-here", + "IMG_URL": os.path.join(settings.STATIC_URL, "img/docs"), + } + + for placeholder, value in replaces.items(): + content = content.replace(placeholder, value) ctx = { "page": "docs", diff --git a/hc/settings.py b/hc/settings.py index 0b3ee4d6..2d0da391 100644 --- a/hc/settings.py +++ b/hc/settings.py @@ -27,7 +27,7 @@ def envint(s, default): return int(v) -SECRET_KEY = os.getenv("SECRET_KEY", "---") +SECRET_KEY = os.getenv("SECRET_KEY", "") METRICS_KEY = os.getenv("METRICS_KEY") DEBUG = envbool("DEBUG", "True") ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "*").split(",") diff --git a/templates/docs/api.html b/templates/docs/api.html index b66baf4e..21cfc6c7 100644 --- a/templates/docs/api.html +++ b/templates/docs/api.html @@ -103,12 +103,11 @@ specified value.

The API key is either missing or invalid.

Example Request

-
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/
+
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/
 
-

Example Response

-
{
+
{
   "checks": [
     {
       "name": "Filesystem Backup",
@@ -149,14 +148,13 @@ specified value.

}
-

When using the read-only API key, SITE_NAME omits the following fields from responses: ping_url, update_url, pause_url, channels. It adds an extra unique_key field. The unique_key identifier is stable across API calls, and you can use it in the Get a single check and Get a list of check's status changes API calls.

Example:

-
{
+
{
   "checks": [
     {
       "name": "Filesystem Backup",
@@ -191,7 +189,6 @@ and Get a list of check's status changes API calls.

}
-

Get a Single Check

GET SITE_ROOT/api/v1/checks/<uuid>
GET SITE_ROOT/api/v1/checks/<unique_key>

@@ -210,12 +207,11 @@ using the read-only API key) as an identifier.

The specified check does not exist.

Example Request

-
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/<uuid>
+
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/checks/<uuid>
 
-

Example Response

-
{
+
{
   "name": "Database Backup",
   "tags": "production db",
   "desc": "Runs ~/db-backup.sh",
@@ -235,7 +231,6 @@ using the read-only API key) as an identifier.

}
-

Example Read-Only Response

When using the read-only API key, SITE_NAME omits the following fields from responses: ping_url, update_url, pause_url, channels. It adds an extra @@ -243,7 +238,7 @@ using the read-only API key) as an identifier.

Note: although API omits the ping_url, update_url, and pause_url in read-only API responses, the client can easily construct these URLs themselves if they know the check's unique UUID.

-
{
+
{
   "name": "Database Backup",
   "tags": "production db",
   "desc": "Runs ~/db-backup.sh",
@@ -260,7 +255,6 @@ check's unique UUID.

}
-

Create a Check

POST SITE_ROOT/api/v1/checks/

Creates a new check and returns its ping URL. @@ -395,20 +389,18 @@ field values. the limit is 20 checks per account.

Example Request

-
curl SITE_ROOT/api/v1/checks/ \
+
curl SITE_ROOT/api/v1/checks/ \
     --header "X-Api-Key: your-api-key" \
     --data '{"name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
 
-

Or, alternatively:

-
curl SITE_ROOT/api/v1/checks/ \
+
curl SITE_ROOT/api/v1/checks/ \
     --data '{"api_key": "your-api-key", "name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
 
-

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -427,7 +419,6 @@ the limit is 20 checks per account.
 }
 
-

Update an Existing Check

POST SITE_ROOT/api/v1/checks/<uuid>

Updates an existing check. All request parameters are optional. If you omit any @@ -540,20 +531,18 @@ field values.

The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
     --header "X-Api-Key: your-api-key" \
     --data '{"name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
 
-

Or, alternatively:

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
     --data '{"api_key": "your-api-key", "name": "Backups", "tags": "prod www", "timeout": 3600, "grace": 60}'
 
-

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -572,7 +561,6 @@ field values.
 }
 
-

Pause Monitoring of a Check

POST SITE_ROOT/api/v1/checks/<uuid>/pause

Disables monitoring for a check without removing it. The check goes into a "paused" @@ -590,16 +578,15 @@ state. You can resume monitoring of the check by pinging it.

The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/0c8983c9-9d73-446f-adb5-0641fdacc9d4/pause \
+
curl SITE_ROOT/api/v1/checks/0c8983c9-9d73-446f-adb5-0641fdacc9d4/pause \
     --request POST --header "X-Api-Key: your-api-key" --data ""
 
-

Note: the --data "" argument forces curl to send a Content-Length request header even though the request body is empty. For HTTP POST requests, the Content-Length header is sometimes required by some network proxies and web servers.

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -618,7 +605,6 @@ header is sometimes required by some network proxies and web servers.

}
-

Delete Check

DELETE SITE_ROOT/api/v1/checks/<uuid>

Permanently deletes the check from the user's account. Returns JSON representation of the @@ -636,13 +622,12 @@ check that was just deleted.

The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc \
     --request DELETE --header "X-Api-Key: your-api-key"
 
-

Example Response

-
{
+
{
   "channels": "",
   "desc": "",
   "grace": 60,
@@ -661,7 +646,6 @@ check that was just deleted.

}
-

Get a list of check's logged pings

GET SITE_ROOT/api/v1/checks/<uuid>/pings/

Returns a list of pings this check has received.

@@ -680,13 +664,12 @@ number of returned pings depends on the account's billing plan: 100 for free acc
The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pings/ \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/pings/ \
     --header "X-Api-Key: your-api-key"
 
-

Example Response

-
{
+
{
   "pings": [
     {
       "type": "success",
@@ -730,7 +713,6 @@ number of returned pings depends on the account's billing plan: 100 for free acc
 }
 
-

Get a list of check's status changes

GET SITE_ROOT/api/v1/checks/<uuid>/flips/
GET SITE_ROOT/api/v1/checks/<unique_key>/flips/

@@ -771,13 +753,12 @@ number of returned pings depends on the account's billing plan: 100 for free acc
The specified check does not exist.

Example Request

-
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/flips/ \
+
curl SITE_ROOT/api/v1/checks/f618072a-7bde-4eee-af63-71a77c5723bc/flips/ \
     --header "X-Api-Key: your-api-key"
 
-

Example Response

-
[
+
[
     {
       "timestamp": "2020-03-23T10:18:23+00:00",
       "up": 1
@@ -793,7 +774,6 @@ number of returned pings depends on the account's billing plan: 100 for free acc
 ]
 
-

Get a List of Existing Integrations

GET SITE_ROOT/api/v1/channels/

Returns a list of integrations belonging to the project.

@@ -805,12 +785,11 @@ number of returned pings depends on the account's billing plan: 100 for free acc
The API key is either missing or invalid.

Example Request

-
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/channels/
+
curl --header "X-Api-Key: your-api-key" SITE_ROOT/api/v1/channels/
 
-

Example Response

-
{
+
{
   "channels": [
     {
       "id": "4ec5a071-2d08-4baa-898a-eb4eb3cd6941",
diff --git a/templates/docs/attaching_logs.html b/templates/docs/attaching_logs.html
index 167d5f3a..1ed888ab 100644
--- a/templates/docs/attaching_logs.html
+++ b/templates/docs/attaching_logs.html
@@ -7,32 +7,29 @@ it later.

Logging Command Output

In this example, we run certbot renew, capture its output (both the stdout and stderr streams), and submit the captured output to SITE_NAME:

-
#!/bin/sh
+
#!/bin/sh
 
 m=$(/usr/bin/certbot renew 2>&1)
 curl -fsS -m 10 --retry 5 --data-raw "$m" PING_URL
 
-

In Combination with the /fail and /{exit-status} Endpoints

We can extend the previous example and signal either success or failure depending on the exit code:

-
#!/bin/sh
+
#!/bin/sh
 
 m=$(/usr/bin/certbot renew 2>&1)
 curl -fsS -m 10 --retry 5 --data-raw "$m" PING_URL/$?
 
-

Using Runitor

Runitor is a third party utility that runs the supplied command, captures its output and reports to SITE_NAME. It also measures the execution time and retries HTTP requests on transient errors. Best of all, the syntax is simple and clean:

-
runitor -uuid your-uuid-here -- /usr/bin/certbot renew
+
runitor -uuid your-uuid-here -- /usr/bin/certbot renew
 
-

Handling More Than 10KB of Logs

While SITE_NAME can store a small amount of logs in a pinch, it is not specifically designed for that. If you run into the issue of logs getting cut off, consider @@ -44,13 +41,12 @@ the totals instead.

  • If the important content is usually at the end, submit the last 10KB instead of the first. Here is an example that submits the last 10KB of dmesg output:
  • -
    #!/bin/sh
    +
    #!/bin/sh
     
     m=$(dmesg | tail --bytes=10000)
     curl -fsS -m 10 --retry 5 --data-raw "$m" PING_URL
     
    -
    • Finally, if it is critical to capture the entire log output, consider using a dedicated log aggregation service for capturing the logs.
    • diff --git a/templates/docs/bash.html b/templates/docs/bash.html index dc7ec9fc..65a0cedb 100644 --- a/templates/docs/bash.html +++ b/templates/docs/bash.html @@ -4,14 +4,13 @@ have to do is make an HTTP request at an appropriate place in the script. curl and wget are two common command-line HTTP clients you can use.

      -
      # Sends an HTTP GET request with curl:
      +
      # Sends an HTTP GET request with curl:
       curl -m 10 --retry 5 PING_URL
       
       # Silent version (no stdout/stderr output unless curl hits an error):
       curl -fsS -m 10 --retry 5 -o /dev/null PING_URL
       
      -

      Here's what each curl parameter does:

      -m <seconds>
      @@ -36,7 +35,7 @@ to actively signal a failure. The exit status should be a 0-255 integer. SITE_NAME will interpret exit status 0 as success and all non-zero values as failures.

      The following example runs /usr/bin/certbot renew, and uses the $? variable to look up its exit status:

      -
      #!/bin/sh
      +
      #!/bin/sh
       
       # Payload here:
       /usr/bin/certbot renew
      @@ -44,25 +43,23 @@ look up its exit status:

      curl -m 10 --retry 5 PING_URL/$?
      -

      Logging Command Output

      When pinging with HTTP POST, you can put extra diagnostic information in the request body. If the request body looks like a valid UTF-8 string, SITE_NAME will accept and store the first 10KB of the request body.

      In the below example, certbot's output is captured and submitted via HTTP POST:

      -
      #!/bin/sh
      +
      #!/bin/sh
       
       m=$(/usr/bin/certbot renew 2>&1)
       curl -fsS -m 10 --retry 5 --data-raw "$m" PING_URL
       
      -

      Auto-provisioning New Checks

      This example uses SITE_NAME Management API to create a check "on the fly" (if it does not already exist) and retrieve its ping URL. Using this technique, you can write services that automatically register with SITE_NAME the first time they run.

      -
      #!/bin/bash
      +
      #!/bin/bash
       
       API_KEY=your-api-key-here
       
      diff --git a/templates/docs/cloning_checks.html b/templates/docs/cloning_checks.html
      index bc08a7d8..5b06a674 100644
      --- a/templates/docs/cloning_checks.html
      +++ b/templates/docs/cloning_checks.html
      @@ -16,7 +16,7 @@ an existing deployment in a new region. The SITE_NAME web interface does
       not have a function to clone an entire project, but you can clone all checks in the
       project relatively easily using the Management API calls.
       Below is an example using Python and the requests library:

      -
      import requests
      +
      import requests
       
       API_URL = "SITE_ROOT/api/v1/checks/"
       SOURCE_PROJECT_READONLY_KEY = "..."
      diff --git a/templates/docs/configuring_prometheus.html b/templates/docs/configuring_prometheus.html
      index e7b8fff3..f8b5ef59 100644
      --- a/templates/docs/configuring_prometheus.html
      +++ b/templates/docs/configuring_prometheus.html
      @@ -7,7 +7,7 @@ the Prometheus endpoint:

      Project's API Keys

      Update the prometheus.yml

      You can copy the Prometheus endpoint URL and add it to the Prometheus configuration:

      -
        - job_name: "healthchecks"
      +
        - job_name: "healthchecks"
           scrape_interval: 60s
           scheme: SITE_SCHEME
           metrics_path: /projects/45sd78-eeee-dddd-8888-b25a9887ecfd/metrics/NXyGzks4s8xcF1J-wzoaioyoqXIANGD0
      @@ -15,6 +15,5 @@ the Prometheus endpoint:

      - targets: ["SITE_HOSTNAME"]
      -

      Notice how we split up the URL and paste in the scheme, domain, and path separately.

      Reload Prometheus, and your changes should be live, coming in under the hc_ prefix.

      \ No newline at end of file diff --git a/templates/docs/csharp.html b/templates/docs/csharp.html index 70751f36..850634b7 100644 --- a/templates/docs/csharp.html +++ b/templates/docs/csharp.html @@ -1,6 +1,6 @@

      C#

      Below is an example of making an HTTP request to SITE_NAME from C#.

      -
      using (var client = new System.Net.WebClient())
      +
      using (var client = new System.Net.WebClient())
       {
              client.DownloadString("PING_URL");
       }
      diff --git a/templates/docs/go.html b/templates/docs/go.html
      index b3a56284..1dda10b7 100644
      --- a/templates/docs/go.html
      +++ b/templates/docs/go.html
      @@ -1,6 +1,6 @@
       

      Go

      Below is an example of making an HTTP request to SITE_NAME from Go.

      -
      package main
      +
      package main
       
       import "fmt"
       import "net/http"
      diff --git a/templates/docs/http_api.html b/templates/docs/http_api.html
      index bac77da5..68bb5e4c 100644
      --- a/templates/docs/http_api.html
      +++ b/templates/docs/http_api.html
      @@ -15,20 +15,18 @@ If the request body looks like a UTF-8 string, SITE_NAME stores the request body
       

      Successful responses will have the "200 OK" HTTP response status code and a short "OK" string in the response body.

      Send a "success" Signal

      -
      HEAD|GET|POST PING_ENDPOINT{uuid}
      +
      HEAD|GET|POST PING_ENDPOINT{uuid}
       
      -

      Signals to SITE_NAME that the job has completed successfully (or, continuously running processes are still running and healthy). The uuid parameter is unique for each check.

      Example

      -
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278 HTTP/1.0
      +
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278 HTTP/1.0
       Host: hc-ping.com
       
      - -
      HTTP/1.1 200 OK
      +
      HTTP/1.1 200 OK
       Server: nginx
       Date: Wed, 29 Jan 2020 09:58:23 GMT
       Content-Type: text/plain; charset=utf-8
      @@ -39,21 +37,18 @@ is unique for each check.

      OK
      -

      Send a "fail" Signal

      -
      HEAD|GET|POST PING_ENDPOINT{uuid}/fail
      +
      HEAD|GET|POST PING_ENDPOINT{uuid}/fail
       
      -

      Signals to SITE_NAME that the job has failed. Actively signaling a failure minimizes the delay from your monitored service failing to you receiving an alert.

      Example

      -
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/fail HTTP/1.0
      +
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/fail HTTP/1.0
       Host: hc-ping.com
       
      - -
      HTTP/1.1 200 OK
      +
      HTTP/1.1 200 OK
       Server: nginx
       Date: Wed, 29 Jan 2020 09:58:23 GMT
       Content-Type: text/plain; charset=utf-8
      @@ -64,12 +59,10 @@ minimizes the delay from your monitored service failing to you receiving an aler
       OK
       
      -

      Send a "start" Signal

      -
      HEAD|GET|POST PING_ENDPOINT{uuid}/start
      +
      HEAD|GET|POST PING_ENDPOINT{uuid}/start
       
      -

      Sends a "job has started!" message to SITE_NAME. Sending a "start" signal is optional, but it enables a few extra features:

        @@ -77,12 +70,11 @@ optional, but it enables a few extra features:

      • SITE_NAME will detect if the job runs longer than its configured grace time

      Example

      -
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/start HTTP/1.0
      +
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/start HTTP/1.0
       Host: hc-ping.com
       
      - -
      HTTP/1.1 200 OK
      +
      HTTP/1.1 200 OK
       Server: nginx
       Date: Wed, 29 Jan 2020 09:58:23 GMT
       Content-Type: text/plain; charset=utf-8
      @@ -93,22 +85,19 @@ optional, but it enables a few extra features:

      OK
      -

      Report Script's Exit Status

      -
      HEAD|GET|POST PING_ENDPOINT{uuid}/{exit-status}
      +
      HEAD|GET|POST PING_ENDPOINT{uuid}/{exit-status}
       
      -

      Sends a success or failure signal depending on the exit status included in the URL. The exit status is a 0-255 integer. SITE_NAME interprets 0 as success and all other values as failure.

      Example

      -
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/1 HTTP/1.0
      +
      GET /5bf66975-d4c7-4bf5-bcc8-b8d8a82ea278/1 HTTP/1.0
       Host: hc-ping.com
       
      - -
      HTTP/1.1 200 OK
      +
      HTTP/1.1 200 OK
       Server: nginx
       Date: Wed, 29 Jan 2020 09:58:23 GMT
       Content-Type: text/plain; charset=utf-8
      diff --git a/templates/docs/javascript.html b/templates/docs/javascript.html
      index daf5d693..fffd7faf 100644
      --- a/templates/docs/javascript.html
      +++ b/templates/docs/javascript.html
      @@ -1,15 +1,14 @@
       

      Javascript

      Below is an example of making an HTTP request to SITE_NAME from Node.js.

      -
      var https = require('https');
      +
      var https = require('https');
       https.get('PING_URL').on('error', (err) => {
           console.log('Ping failed: ' + err)
       });
       
      -

      You can also send pings from a browser environment. SITE_NAME sets the Access-Control-Allow-Origin:* CORS header, so cross-domain AJAX requests work.

      -
      var xhr = new XMLHttpRequest();
      +
      var xhr = new XMLHttpRequest();
       xhr.open('GET', 'PING_URL', true);
       xhr.send(null);
       
      \ No newline at end of file diff --git a/templates/docs/measuring_script_run_time.html b/templates/docs/measuring_script_run_time.html index b8840f8a..f7c42e92 100644 --- a/templates/docs/measuring_script_run_time.html +++ b/templates/docs/measuring_script_run_time.html @@ -7,7 +7,7 @@

      Signaling a start kicks off a separate timer: the job now must signal a success within its configured "Grace Time," or it will get marked as "down."

      Below is a code example in Python:

      -
      import requests
      +
      import requests
       URL = "PING_URL"
       
       
      @@ -29,7 +29,6 @@ success within its configured "Grace Time," or it will get marked as "down."

      requests.get(URL)
      -

      Viewing Measured Run Times

      When SITE_NAME receives a "start" signal followed by a regular ping or a "fail" signal, and the two events are less than 24 hours apart, diff --git a/templates/docs/monitoring_cron_jobs.html b/templates/docs/monitoring_cron_jobs.html index 929f1b38..b5b57fd0 100644 --- a/templates/docs/monitoring_cron_jobs.html +++ b/templates/docs/monitoring_cron_jobs.html @@ -3,12 +3,11 @@ update your cron job command to send an HTTP request to SITE_NAME after completing the job.

      Let's look at an example:

      -
      $ crontab -l
      +
      $ crontab -l
       # m h dom mon dow command
         8 6 * * * /home/user/backup.sh
       
      -

      The above job runs /home/user/backup.sh every day at 6:08. The backup script is presumably a headless, background process. Even if it works correctly currently, it can start silently failing in the future without @@ -40,12 +39,11 @@ increasingly important as you add more checks to your account.

      Finally, edit your cron job definition and append a curl or wget call after the command:

      -
      $ crontab -e
      +
      $ crontab -e
       # m h dom mon dow command
         8 6 * * * /home/user/backup.sh && curl -fsS --retry 5 -o /dev/null PING_URL
       
      -

      Now, each time your cron job runs, it will send an HTTP request to the ping URL. Since SITE_NAME knows your cron job's schedule, it can calculate the dates and times when the job should run. As soon as your cron job doesn't @@ -84,7 +82,7 @@ the likely cause is a timezone mismatch: your machine may be using a timezone different from what you have configured on SITE_NAME.

      On modern GNU/Linux systems, you can look up the time zone using the timedatectl status command and looking for "Time zone" in its output:

      -
      $ timedatectl status
      +
      $ timedatectl status
       
                      Local time: C  2020-01-23 12:35:50 EET
                  Universal time: C  2020-01-23 10:35:50 UTC
      @@ -95,15 +93,13 @@ different from what you have configured on SITE_NAME.

      RTC in local TZ: no
      -

      Viewing Cron Logs Using journalctl

      On a systemd-based system, you can use the journalctl utility to see system logs, including logs from the cron daemon.

      To see live logs:

      -
      journalctl -f
      +
      journalctl -f
       
      -

      To see the logs from e.g. the last hour, and only from the cron daemon:

      -
      journalctl --since "1 hour ago" -t CRON
      +
      journalctl --since "1 hour ago" -t CRON
       
      \ No newline at end of file diff --git a/templates/docs/php.html b/templates/docs/php.html index 2eb87dcc..66a42464 100644 --- a/templates/docs/php.html +++ b/templates/docs/php.html @@ -1,13 +1,12 @@

      PHP

      Below is an example of making an HTTP request to SITE_NAME from PHP.

      -
      file_get_contents('PING_URL');
      +
      file_get_contents('PING_URL');
       
      -

      If you would like to setup timeout and retry options, as discussed in the reliability tips section, there is a curl package available that lets you do that easily:

      -
      use Curl\Curl;
      +
      use Curl\Curl;
       
       $curl = new Curl();
       $curl->setRetry(20);
      @@ -15,5 +14,4 @@
       $curl->get('PING_URL');
       
      -

      Note: this code does not throw any exceptions.

      \ No newline at end of file diff --git a/templates/docs/powershell.html b/templates/docs/powershell.html index 439436c0..09b20f28 100644 --- a/templates/docs/powershell.html +++ b/templates/docs/powershell.html @@ -5,19 +5,17 @@

      Here is a simple PowerShell script that pings SITE_NAME. When scheduled to run with Task Scheduler, it will essentially just send regular "I'm alive" messages. Of course, you can extend it to do more things.

      -
      # inside a PowerShell script:
      +
      # inside a PowerShell script:
       Invoke-RestMethod PING_URL
       
      -

      Save the above to e.g., C:\Scripts\healthchecks.ps1. Then use the following command in a Scheduled Task to run the script:

      -
      powershell.exe -ExecutionPolicy bypass -File C:\Scripts\healthchecks.ps1
      +
      powershell.exe -ExecutionPolicy bypass -File C:\Scripts\healthchecks.ps1
       
      -

      In simple cases, you can also pass the script to PowerShell directly, using the "-command" argument:

      -
      # Without an underlying script, passing the command to PowerShell directly:
      +
      # Without an underlying script, passing the command to PowerShell directly:
       powershell.exe -command &{Invoke-RestMethod PING_URL}
       
      \ No newline at end of file diff --git a/templates/docs/python.html b/templates/docs/python.html index cd8a5cf6..9eb22050 100644 --- a/templates/docs/python.html +++ b/templates/docs/python.html @@ -1,7 +1,7 @@

      Python

      If you are already using the requests library, it is convenient to also use it here:

      -
      import requests
      +
      import requests
       
       try:
           requests.get("PING_URL", timeout=10)
      @@ -10,10 +10,9 @@ library, it is convenient to also use it here:

      print("Ping failed: %s" % e)
      -

      Otherwise, you can use the urllib.request module from Python 3 standard library:

      -
      import socket
      +
      import socket
       import urllib.request
       
       try:
      @@ -23,9 +22,8 @@ module from Python 3 standard library:

      print("Ping failed: %s" % e)
      -

      You can include additional diagnostic information in the in the request body (for POST requests):

      -
      # Passing diagnostic information in the POST body:
      +
      # Passing diagnostic information in the POST body:
       import requests
       requests.post("PING_URL", data="temperature=-7")
       
      \ No newline at end of file diff --git a/templates/docs/reliability_tips.html b/templates/docs/reliability_tips.html index f27b5b9b..2ff5335f 100644 --- a/templates/docs/reliability_tips.html +++ b/templates/docs/reliability_tips.html @@ -12,21 +12,19 @@ request could block the whole process. An explicit per-request time limit mitiga this problem.

      Specifying the timeout depends on the tool you use. curl, for example, has the --max-time (shorthand: -m) parameter:

      -
      # Send an HTTP request, 10 second timeout:
      +
      # Send an HTTP request, 10 second timeout:
       curl -m 10 PING_URL
       
      -

      Use Retries

      To minimize the amount of false alerts you get from SITE_NAME, instruct your HTTP client to retry failed requests several times.

      Specifying the retry policy depends on the tool you use. curl, for example, has the --retry parameter:

      -
      # Retry up to 5 times, uses an increasing delay between each retry (1s, 2s, 4s, 8s, ...)
      +
      # Retry up to 5 times, uses an increasing delay between each retry (1s, 2s, 4s, 8s, ...)
       curl --retry 5 PING_URL
       
      -

      Handle Exceptions

      Make sure you know how your HTTP client handles failed requests. For example, if you use an HTTP library that raises exceptions, decide if you want to diff --git a/templates/docs/ruby.html b/templates/docs/ruby.html index 765420aa..2f999b03 100644 --- a/templates/docs/ruby.html +++ b/templates/docs/ruby.html @@ -1,6 +1,6 @@

      Ruby

      Below is an example of making an HTTP request to SITE_NAME from Ruby.

      -
      require 'net/http'
      +
      require 'net/http'
       require 'uri'
       
       Net::HTTP.get(URI.parse('PING_URL'))
      diff --git a/templates/docs/self_hosted.html b/templates/docs/self_hosted.html
      new file mode 100644
      index 00000000..db7e5d18
      --- /dev/null
      +++ b/templates/docs/self_hosted.html
      @@ -0,0 +1,86 @@
      +

      Self-Hosted Healthchecks

      +

      Healthchecks is open-source, and is licensed under the BSD 3-clause license.

      +

      Rather than using the hosted service at +https://healthchecks.io, you have the option to host an +instance yourself.

      +

      The building blocks are:

      +
        +
      • Python 3.6+
      • +
      • Django 3
      • +
      • PostgreSQL or MySQL
      • +
      +

      Setting Up for Development

      +

      You can set up a development environment in a Python +virtual environment +on your local system to develop a new feature, write a new integration +or test a bugfix.

      +

      The following instructions assume you are using a Debian-based OS.

      +
        +
      • +

        Install dependencies:

        +
        $ sudo apt-get update
        +$ sudo apt-get install -y gcc python3-dev python3-venv
        +
        + +
      • +
      • +

        Prepare directory for project code and virtualenv. Feel free to use a + different location:

        +
        $ mkdir -p ~/webapps
        +$ cd ~/webapps
        +
        + +
      • +
      • +

        Prepare virtual environment + (with virtualenv you get pip, we'll use it soon to install requirements):

        +
        $ python3 -m venv hc-venv
        +$ source hc-venv/bin/activate
        +
        + +
      • +
      • +

        Check out project code:

        +
        $ git clone https://github.com/healthchecks/healthchecks.git
        +
        + +
      • +
      • +

        Install requirements (Django, ...) into virtualenv:

        +
        $ pip install wheel
        +$ pip install -r healthchecks/requirements.txt
        +
        + +
      • +
      • +

        Create database tables and a superuser account:

        +
        $ cd ~/webapps/healthchecks
        +$ ./manage.py migrate
        +$ ./manage.py createsuperuser
        +
        + +
      • +
      +

      With the default configuration, Healthchecks stores data in a SQLite file + hc.sqlite in the checkout directory (~/webapps/healthchecks).

      +
        +
      • +

        Run tests:

        +
        $ ./manage.py test
        +
        + +
      • +
      • +

        Run development server:

        +
        $ ./manage.py runserver
        +
        + +
      • +
      +

      At this point, the site should now be running at http://localhost:8000.

      +

      To access Django administration site, log in as a superuser, then +visit http://localhost:8000/admin/.

      +

      FIXME note about no email configuration, no sendalerts, and the devserver

      +

      Next Steps

      +

      Get the source code.

      +

      See Configuration for a list of configuration options.

      \ No newline at end of file diff --git a/templates/docs/self_hosted.md b/templates/docs/self_hosted.md new file mode 100644 index 00000000..889520da --- /dev/null +++ b/templates/docs/self_hosted.md @@ -0,0 +1,81 @@ +# Self-Hosted Healthchecks + +Healthchecks is open-source, and is licensed under the BSD 3-clause license. + +Rather than using the hosted service at +[https://healthchecks.io](https://healthchecks.io), you have the option to host an +instance yourself. + +The building blocks are: + +* Python 3.6+ +* Django 3 +* PostgreSQL or MySQL + +## Setting Up for Development + + +You can set up a development environment in a Python +[virtual environment](https://docs.python.org/3/tutorial/venv.html) +on your local system to develop a new feature, write a new integration +or test a bugfix. + +The following instructions assume you are using a Debian-based OS. + +* Install dependencies: + + $ sudo apt-get update + $ sudo apt-get install -y gcc python3-dev python3-venv + +* Prepare directory for project code and virtualenv. Feel free to use a + different location: + + $ mkdir -p ~/webapps + $ cd ~/webapps + +* Prepare virtual environment + (with virtualenv you get pip, we'll use it soon to install requirements): + + $ python3 -m venv hc-venv + $ source hc-venv/bin/activate + +* Check out project code: + + $ git clone https://github.com/healthchecks/healthchecks.git + +* Install requirements (Django, ...) into virtualenv: + + $ pip install wheel + $ pip install -r healthchecks/requirements.txt + + +* Create database tables and a superuser account: + + $ cd ~/webapps/healthchecks + $ ./manage.py migrate + $ ./manage.py createsuperuser + + With the default configuration, Healthchecks stores data in a SQLite file + `hc.sqlite` in the checkout directory (`~/webapps/healthchecks`). + +* Run tests: + + $ ./manage.py test + +* Run development server: + + $ ./manage.py runserver + +At this point, the site should now be running at `http://localhost:8000`. + +To access Django administration site, log in as a superuser, then +visit `http://localhost:8000/admin/`. + +FIXME note about no email configuration, no sendalerts, and the devserver + +## Next Steps + +Get the [source code](https://github.com/healthchecks/healthchecks). + +See [Configuration](../self_hosted_configuration/) for a list of configuration options. + diff --git a/templates/docs/self_hosted_configuration.html b/templates/docs/self_hosted_configuration.html new file mode 100644 index 00000000..513c92ef --- /dev/null +++ b/templates/docs/self_hosted_configuration.html @@ -0,0 +1,301 @@ +

      Server Configuration

      +

      Healthchecks prepares its configuration in hc/settings.py. It reads configuration +from environment variables. Below is a list of variables it reads and uses:

      +

      ALLOWED_HOSTS

      +

      Default: *

      +

      A list of strings representing the host/domain names that this site can serve. +You can specify multiple domain names by separating them with commas:

      +
      ALLOWED_HOSTS=my-hc.example.org,alternative-name.example.org
      +
      + +

      Aside from the comma-separated syntax, this is a standard Django setting. +Read more about it in the +Django documentation.

      +

      APPRISE_ENABLED

      +

      Default: False

      +

      A boolean that turns on/off the Apprise +integration.

      +

      Before enabling the Apprise integration, make sure the apprise package is installed:

      +
      pip install apprise
      +
      + +

      DEBUG

      +

      Default: True

      +

      A boolean that turns on/off debug mode.

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DEFAULT_FROM_EMAIL

      +

      Default: healthchecks@example.org

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DB

      +

      Default: sqlite

      +

      The database enginge to use. Possible values: sqlite, postgres, mysql.

      +

      DB_CONN_MAX_AGE

      +

      Default: 0

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DB_HOST

      +

      Default: "" (empty string)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DB_NAME

      +

      Default: hc (PostgreSQL, MySQL) or {project-path}/hc.sqlite (SQLite)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DB_PASSWORD

      +

      Default: "" (empty string)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DB_PORT

      +

      Default: "" (empty string)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DB_SSLMODE

      +

      Default: prefer

      +

      PostgreSQL-specific, details

      +

      DB_TARGET_SESSION_ATTRS

      +

      Default: read-write

      +

      PostgreSQL-specific, details

      +

      DB_USER

      +

      Default: postgres (PostgreSQL) or root (MySQL)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      DISCORD_CLIENT_ID

      +

      Default: None

      +

      The Discord Client ID, required by the Discord integration.

      +

      To set up the Discord integration:

      +
        +
      • Register a new application at + https://discordapp.com/developers/applications/me
      • +
      • Add a Redirect URI to your Discord application. The URI format is + SITE_ROOT/integrations/add_discord/. For example, if your SITE_ROOT + is https://my-hc.example.org then the Redirect URI would be + https://my-hc.example.org/integrations/add_discord/
      • +
      • Look up your Discord app's Client ID and Client Secret. Put them + in the DISCORD_CLIENT_ID and DISCORD_CLIENT_SECRET environment + variables.
      • +
      +

      DISCORD_CLIENT_SECRET

      +

      Default: None

      +

      The Discord Client Secret, required by the Slack integration. Look it up at +https://discordapp.com/developers/applications/me.

      +

      EMAIL_HOST

      +

      Default: "" (empty string)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      EMAIL_HOST_PASSWORD

      +

      Default: "" (empty string)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      EMAIL_HOST_USER

      +

      Default: "" (empty string)

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      EMAIL_PORT

      +

      Default: 587

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      EMAIL_USE_TLS

      +

      Default: True

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      EMAIL_USE_VERIFICATION

      +

      Default: True

      +

      A boolean that turns on/off a verification step when adding an email integration.

      +

      If enabled, whenever an user adds an email integration, Healthchecks emails a +verification link to the new address. The new integration becomes active only +after user clicks the verification link.

      +

      If you are setting up a private healthchecks instance where +you trust your users, you can opt to disable the verification step. In that case, +set EMAIL_USE_VERIFICATION to False.

      +

      LINENOTIFY_CLIENT_ID

      +

      Default: None

      +

      LINENOTIFY_CLIENT_SECRET

      +

      Default: None

      +

      MASTER_BADGE_LABEL

      +

      Default: same as SITE_NAME

      +

      MATRIX_ACCESS_TOKEN

      +

      Default: None

      +

      The Matrix bot user's access token, required by the Matrix +integration.

      +

      To set up the Matrix integration:

      +
        +
      • Register a bot user (for posting notifications) in your preferred Matrix homeserver.
      • +
      • Use the Login API call + to retrieve bot user's access token. You can run it as shown in the documentation, + using curl in command shell.
      • +
      • Set the MATRIX_ environment variables. Example:
      • +
      +
      MATRIX_ACCESS_TOKEN=[a long string of characters returned by the login call]
      +MATRIX_HOMESERVER=https://matrix.org
      +MATRIX_USER_ID=@mychecks:matrix.org
      +
      + +

      MATRIX_HOMESERVER

      +

      Default: None

      +

      The Matrix bot's homeserver address, required by the Matrix integration.

      +

      MATRIX_USER_ID

      +

      Default: None

      +

      The Matrix bot's user identifier, required by the Matrix integration.

      +

      PD_VENDOR_KEY

      +

      Default: None

      +

      PagerDuty vendor key, +required by the PagerDuty integration.

      +

      PING_BODY_LIMIT

      +

      Default: 10000

      +

      The upper size limit in bytes for logged ping request bodies. +The default value is 10000 (10 kilobytes). You can adjust the limit or you can remove +the it altogether by setting this value to None.

      +

      PING_EMAIL_DOMAIN

      +

      Default: localhost

      +

      PING_ENDPOINT

      +

      Default: http://localhost:8000/ping/

      +

      PUSHBULLET_CLIENT_ID

      +

      Default: None

      +

      PUSHBULLET_CLIENT_SECRET

      +

      Default: None

      +

      PUSHOVER_API_TOKEN

      +

      Default: None

      +

      The Pushover API token, required by the Pushover integration.

      +

      To enable the Pushover integration:

      +
        +
      • Register a new Pushover application at + https://pushover.net/apps/build.
      • +
      • Within the Pushover application configuration, enable subscriptions. + Make sure the subscription type is set to "URL". Also make sure the redirect + URL is configured to point back to the root of the Healthchecks instance + (e.g., https://my-hc.example.org/).
      • +
      • Put the Pushover application's API Token and the Subscription URL in + PUSHOVER_API_TOKEN and PUSHOVER_SUBSCRIPTION_URL environment + variables. The Pushover subscription URL should look similar to + https://pushover.net/subscribe/yourAppName-randomAlphaNumericData.
      • +
      +

      PUSHOVER_EMERGENCY_EXPIRATION

      +

      Default: 86400 (24 hours)

      +

      Specifies how many seconds an emergency Pushoover notification +will continue to be retried for.

      +

      More information in Pushover API documentation.

      +

      PUSHOVER_EMERGENCY_RETRY_DELAY

      +

      Default: 300 (5 minutes)

      +

      Specifies how often (in seconds) the Pushover servers will send the same notification +to the user.

      +

      More information in Pushover API documentation.

      +

      PUSHOVER_SUBSCRIPTION_URL

      +

      Default: None

      +

      The Pushover Subscription URL, required by the Pushover integration.

      +

      REGISTRATION_OPEN

      +

      Default: True

      +

      A boolean that controls whether site visitors can create new accounts. +Set it to False if you are setting up a private Healthchecks instance, but +it needs to be publicly accessible (so, for example, your cloud services +can send pings to it).

      +

      If you close new user registration, you can still selectively invite users +to your team account.

      +

      REMOTE_USER_HEADER

      +

      Default: None

      +

      Specifies the request header to use for external authentication.

      +

      Healthchecks supports external authentication by means of HTTP headers set by +reverse proxies or the WSGI server. This allows you to integrate it into your +existing authentication system (e.g., LDAP or OAuth) via an authenticating proxy. When this option is enabled, Healtchecks will trust the header's value implicitly, so it is very important to ensure that attackers cannot set the value themselves (and thus impersonate any user). How to do this varies by your chosen proxy, but generally involves configuring it to strip out headers that normalize to the same name as the chosen identity header.

      +

      To enable this feature, set the REMOTE_USER_HEADER value to a header you wish to authenticate with. HTTP headers will be prefixed with HTTP_ and have any dashes converted to underscores. Headers without that prefix can be set by the WSGI server itself only, which is more secure.

      +

      When REMOTE_USER_HEADER is set, Healthchecks will: + - assume the header contains user's email address + - look up and automatically log in the user with a matching email address + - automatically create an user account if it does not exist + - disable the default authentication methods (login link to email, password)

      +

      RP_ID

      +

      Default: None

      +

      The Relying Party identifier, +required by the WebAuthn second-factor authentication feature.

      +

      Healthchecks optionally supports two-factor authentication using the WebAuthn +standard. To enable WebAuthn support, set the RP_ID setting to a non-null value. +Set its value to your site's domain without scheme and without port. For example, +if your site runs on https://my-hc.example.org, set RP_ID to my-hc.example.org.

      +

      Note that WebAuthn requires HTTPS, even if running on localhost. To test WebAuthn +locally with a self-signed certificate, you can use the runsslserver command +from the django-sslserver package.

      +

      SECRET_KEY

      +

      Default: "" (empty string)

      +

      A secret key used for cryptographic signing.

      +

      This is a standard Django setting, read more in +Django documentation.

      +

      SHELL_ENABLED

      +

      Default: False

      +

      A boolean that turns on/off the "Shell Commands" integration.

      +

      The "Shell Commands" integration runs user-defined local shell commands when checks +go up or down. This integration is disabled by default, and can be enabled by setting +the SHELL_ENABLED environment variable to True.

      +

      Note: be careful when using "Shell Commands" integration, and only enable it when +you fully trust the users of your Healthchecks instance. The commands will be executed +by the manage.py sendalerts process, and will run with its system permissions.

      +

      SIGNAL_CLI_ENABLED

      +

      Default: False

      +

      A boolean that turns on/off the Signal integration.

      +

      Healthchecks uses signal-cli to send Signal +notifications. Healthcecks interacts with signal-cli over DBus.

      +

      To enable the Signal integration:

      +
        +
      • Set up and configure signal-cli to listen on DBus system bus + (instructions). + Make sure you can send test messages from command line, using the dbus-send + example given in the signal-cli instructions.
      • +
      • Set the SIGNAL_CLI_ENABLED environment variable to True.
      • +
      +

      SITE_ROOT

      +

      Default: http://localhost:8000

      +

      SITE_NAME

      +

      Default: Mychecks

      +

      SLACK_CLIENT_ID

      +

      Default: None

      +

      The Slack Client ID, required by the Slack integration.

      +

      Go to https://api.slack.com/apps/ +to create a Slack app, and look up its Client ID and Client Secret.

      +

      When setting up the Slack app, make sure to:

      +
        +
      • Add the incoming-webhook + scope to the Bot Token Scopes.
      • +
      • Add a Redirect URL in the format SITE_ROOT/integrations/add_slack_btn/. + For example, if your SITE_ROOT is https://my-hc.example.org then the + Redirect URL would be https://my-hc.example.org/integrations/add_slack_btn/.
      • +
      +

      SLACK_CLIENT_SECRET

      +

      Default: None

      +

      The Slack Client Secret, required by the Slack integration. +Look it up at https://api.slack.com/apps/.

      +

      TELEGRAM_BOT_NAME

      +

      Default: ExampleBot

      +

      The Telegram bot name, required by the Telegram integration.

      +

      To set up the Telegram integration:

      +
        +
      • Create a Telegram bot by talking to the +BotFather. Set the bot's name, +description, user picture, and add a "/start" command.
      • +
      • After creating the bot you will have the bot's name and token. Put them +in TELEGRAM_BOT_NAME and TELEGRAM_TOKEN environment variables.
      • +
      • Run the settelegramwebhook management command. This command tells Telegram +where to forward channel messages by invoking Telegram's +setWebhook API call:
      • +
      +
      $ ./manage.py settelegramwebhook
      +Done, Telegram's webhook set to: https://my-monitoring-project.com/integrations/telegram/bot/
      +
      + +

      For this to work, your SITE_ROOT must be publicy accessible and use the "https://" +scheme.

      +

      TELEGRAM_TOKEN

      +

      Default: None

      +

      The Telegram bot user's authentication token, required by the Telegram integration.

      +

      TRELLO_APP_KEY

      +

      Default: None

      +

      TWILIO_ACCOUNT

      +

      Default: None

      +

      TWILIO_AUTH

      +

      Default: None

      +

      TWILIO_FROM

      +

      Default: None

      +

      TWILIO_USE_WHATSAPP

      +

      Default: False

      +

      USE_PAYMENTS

      +

      Default: False

      +

      A boolean that turns on/off billing features.

      \ No newline at end of file diff --git a/templates/docs/self_hosted_configuration.md b/templates/docs/self_hosted_configuration.md new file mode 100644 index 00000000..73282a6f --- /dev/null +++ b/templates/docs/self_hosted_configuration.md @@ -0,0 +1,476 @@ +# Server Configuration + +Healthchecks prepares its configuration in `hc/settings.py`. It reads configuration +from environment variables. Below is a list of variables it reads and uses: + +## `ALLOWED_HOSTS` + +Default: `*` + +A list of strings representing the host/domain names that this site can serve. +You can specify multiple domain names by separating them with commas: + +```ini +ALLOWED_HOSTS=my-hc.example.org,alternative-name.example.org +``` + +Aside from the comma-separated syntax, this is a standard Django setting. +Read more about it in the +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#allowed-hosts). + +## `APPRISE_ENABLED` + +Default: `False` + +A boolean that turns on/off the [Apprise](https://github.com/caronc/apprise) +integration. + +Before enabling the Apprise integration, make sure the `apprise` package is installed: + +```bash +pip install apprise +``` + +## `DEBUG` + +Default: `True` + +A boolean that turns on/off debug mode. + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#debug). + +## `DEFAULT_FROM_EMAIL` + +Default: `healthchecks@example.org` + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#default-from-email). + +## `DB` + +Default: `sqlite` + +The database enginge to use. Possible values: `sqlite`, `postgres`, `mysql`. + +## `DB_CONN_MAX_AGE` + +Default: `0` + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#conn-max-age). + +## `DB_HOST` + +Default: `""` (empty string) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#host). + +## `DB_NAME` + +Default: `hc` (PostgreSQL, MySQL) or `{project-path}/hc.sqlite` (SQLite) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#name). + +## `DB_PASSWORD` + +Default: `""` (empty string) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#password). + +## `DB_PORT` + +Default: `""` (empty string) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#port). + +## `DB_SSLMODE` + +Default: `prefer` + +PostgreSQL-specific, [details](https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-CONNECT-SSLMODE) + +## `DB_TARGET_SESSION_ATTRS` + +Default: `read-write` + +PostgreSQL-specific, [details](https://www.postgresql.org/docs/10/libpq-connect.html#LIBPQ-CONNECT-TARGET-SESSION-ATTRS) + +## `DB_USER` + +Default: `postgres` (PostgreSQL) or `root` (MySQL) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#user). + +## `DISCORD_CLIENT_ID` + +Default: `None` + +The Discord Client ID, required by the Discord integration. + +To set up the Discord integration: + +* Register a new application at + [https://discordapp.com/developers/applications/me](https://discordapp.com/developers/applications/me) +* Add a Redirect URI to your Discord application. The URI format is + `SITE_ROOT/integrations/add_discord/`. For example, if `your SITE_ROOT` + is `https://my-hc.example.org` then the Redirect URI would be + `https://my-hc.example.org/integrations/add_discord/` +* Look up your Discord app's _Client ID_ and _Client Secret_. Put them + in the `DISCORD_CLIENT_ID` and `DISCORD_CLIENT_SECRET` environment + variables. + +## `DISCORD_CLIENT_SECRET` + +Default: `None` + +The Discord Client Secret, required by the Slack integration. Look it up at +[https://discordapp.com/developers/applications/me](https://discordapp.com/developers/applications/me). + +## `EMAIL_HOST` + +Default: `""` (empty string) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#email-host). + +## `EMAIL_HOST_PASSWORD` + +Default: `""` (empty string) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#email-host-password). + +## `EMAIL_HOST_USER` + +Default: `""` (empty string) + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#email-host-user). + +## `EMAIL_PORT` + +Default: `587` + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#email-port). + +## `EMAIL_USE_TLS` + +Default: `True` + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#email-use-tls). + +## `EMAIL_USE_VERIFICATION` + +Default: `True` + +A boolean that turns on/off a verification step when adding an email integration. + +If enabled, whenever an user adds an email integration, Healthchecks emails a +verification link to the new address. The new integration becomes active only +after user clicks the verification link. + +If you are setting up a private healthchecks instance where +you trust your users, you can opt to disable the verification step. In that case, +set `EMAIL_USE_VERIFICATION` to `False`. + +## `LINENOTIFY_CLIENT_ID` + +Default: `None` + +## `LINENOTIFY_CLIENT_SECRET` + +Default: `None` + +## `MASTER_BADGE_LABEL` + +Default: same as `SITE_NAME` + +## `MATRIX_ACCESS_TOKEN` + +Default: `None` + +The [Matrix](https://matrix.org/) bot user's access token, required by the Matrix +integration. + +To set up the Matrix integration: + +* Register a bot user (for posting notifications) in your preferred Matrix homeserver. +* Use the [Login API call](https://www.matrix.org/docs/guides/client-server-api#login) + to retrieve bot user's access token. You can run it as shown in the documentation, + using curl in command shell. +* Set the `MATRIX_` environment variables. Example: + +```ini +MATRIX_ACCESS_TOKEN=[a long string of characters returned by the login call] +MATRIX_HOMESERVER=https://matrix.org +MATRIX_USER_ID=@mychecks:matrix.org +``` + +## `MATRIX_HOMESERVER` + +Default: `None` + +The Matrix bot's homeserver address, required by the Matrix integration. + +## `MATRIX_USER_ID` + +Default: `None` + +The Matrix bot's user identifier, required by the Matrix integration. + +## `PD_VENDOR_KEY` + +Default: `None` + +[PagerDuty](https://www.pagerduty.com/) vendor key, +required by the PagerDuty integration. + +## `PING_BODY_LIMIT` + +Default: `10000` + +The upper size limit in bytes for logged ping request bodies. +The default value is 10000 (10 kilobytes). You can adjust the limit or you can remove +the it altogether by setting this value to `None`. + +## `PING_EMAIL_DOMAIN` + +Default: `localhost` + +## `PING_ENDPOINT` + +Default: `http://localhost:8000/ping/` + +## `PUSHBULLET_CLIENT_ID` + +Default: `None` + +## `PUSHBULLET_CLIENT_SECRET` + +Default: `None` + +## `PUSHOVER_API_TOKEN` + +Default: `None` + +The [Pushover](https://pushover.net/) API token, required by the Pushover integration. + +To enable the Pushover integration: + +* Register a new Pushover application at + [https://pushover.net/apps/build](https://pushover.net/apps/build). +* Within the Pushover application configuration, enable subscriptions. + Make sure the subscription type is set to "URL". Also make sure the redirect + URL is configured to point back to the root of the Healthchecks instance + (e.g., `https://my-hc.example.org/`). +* Put the Pushover application's _API Token_ and the _Subscription URL_ in + `PUSHOVER_API_TOKEN` and `PUSHOVER_SUBSCRIPTION_URL` environment + variables. The Pushover subscription URL should look similar to + `https://pushover.net/subscribe/yourAppName-randomAlphaNumericData`. + +## `PUSHOVER_EMERGENCY_EXPIRATION` + +Default: `86400` (24 hours) + +Specifies how many seconds an emergency Pushoover notification +will continue to be retried for. + +More information in [Pushover API documentation](https://pushover.net/api#priority). + +## `PUSHOVER_EMERGENCY_RETRY_DELAY` + +Default: `300` (5 minutes) + +Specifies how often (in seconds) the Pushover servers will send the same notification +to the user. + +More information in [Pushover API documentation](https://pushover.net/api#priority). + +## `PUSHOVER_SUBSCRIPTION_URL` + +Default: `None` + +The Pushover Subscription URL, required by the Pushover integration. + +## `REGISTRATION_OPEN` + +Default: `True` + +A boolean that controls whether site visitors can create new accounts. +Set it to `False` if you are setting up a private Healthchecks instance, but +it needs to be publicly accessible (so, for example, your cloud services +can send pings to it). + +If you close new user registration, you can still selectively invite users +to your team account. + +## `REMOTE_USER_HEADER` + +Default: `None` + +Specifies the request header to use for external authentication. + +Healthchecks supports external authentication by means of HTTP headers set by +reverse proxies or the WSGI server. This allows you to integrate it into your +existing authentication system (e.g., LDAP or OAuth) via an authenticating proxy. When this option is enabled, **Healtchecks will trust the header's value implicitly**, so it is **very important** to ensure that attackers cannot set the value themselves (and thus impersonate any user). How to do this varies by your chosen proxy, but generally involves configuring it to strip out headers that normalize to the same name as the chosen identity header. + +To enable this feature, set the `REMOTE_USER_HEADER` value to a header you wish to authenticate with. HTTP headers will be prefixed with `HTTP_` and have any dashes converted to underscores. Headers without that prefix can be set by the WSGI server itself only, which is more secure. + +When `REMOTE_USER_HEADER` is set, Healthchecks will: + - assume the header contains user's email address + - look up and automatically log in the user with a matching email address + - automatically create an user account if it does not exist + - disable the default authentication methods (login link to email, password) + +## `RP_ID` + +Default: `None` + +The [Relying Party identifier](https://www.w3.org/TR/webauthn-2/#relying-party-identifier), +required by the WebAuthn second-factor authentication feature. + +Healthchecks optionally supports two-factor authentication using the WebAuthn +standard. To enable WebAuthn support, set the `RP_ID` setting to a non-null value. +Set its value to your site's domain without scheme and without port. For example, +if your site runs on `https://my-hc.example.org`, set `RP_ID` to `my-hc.example.org`. + +Note that WebAuthn requires HTTPS, even if running on localhost. To test WebAuthn +locally with a self-signed certificate, you can use the `runsslserver` command +from the `django-sslserver` package. + +## `SECRET_KEY` + +Default: `""` (empty string) + +A secret key used for cryptographic signing. + +This is a standard Django setting, read more in +[Django documentation](https://docs.djangoproject.com/en/3.1/ref/settings/#secret-key). + +## `SHELL_ENABLED` + +Default: `False` + +A boolean that turns on/off the "Shell Commands" integration. + +The "Shell Commands" integration runs user-defined local shell commands when checks +go up or down. This integration is disabled by default, and can be enabled by setting +the `SHELL_ENABLED` environment variable to `True`. + +Note: be careful when using "Shell Commands" integration, and only enable it when +you fully trust the users of your Healthchecks instance. The commands will be executed +by the `manage.py sendalerts` process, and will run with its system permissions. + +## `SIGNAL_CLI_ENABLED` + +Default: `False` + +A boolean that turns on/off the [Signal](https://signal.org/) integration. + +Healthchecks uses [signal-cli](https://github.com/AsamK/signal-cli) to send Signal +notifications. Healthcecks interacts with signal-cli over DBus. + +To enable the Signal integration: + +* Set up and configure signal-cli to listen on DBus system bus + ([instructions](https://github.com/AsamK/signal-cli/wiki/DBus-service)). + Make sure you can send test messages from command line, using the `dbus-send` + example given in the signal-cli instructions. +* Set the `SIGNAL_CLI_ENABLED` environment variable to `True`. + +## `SITE_ROOT` + +Default: `http://localhost:8000` + +## `SITE_NAME` + +Default: `Mychecks` + +## `SLACK_CLIENT_ID` + +Default: `None` + +The Slack Client ID, required by the Slack integration. + +Go to [https://api.slack.com/apps/](https://api.slack.com/apps/) +to create a _Slack app_, and look up its _Client ID_ and _Client Secret_. + +When setting up the Slack app, make sure to: + +* Add the [incoming-webhook](https://api.slack.com/scopes/incoming-webhook) + scope to the Bot Token Scopes. +* Add a _Redirect URL_ in the format `SITE_ROOT/integrations/add_slack_btn/`. + For example, if your `SITE_ROOT` is `https://my-hc.example.org` then the + Redirect URL would be `https://my-hc.example.org/integrations/add_slack_btn/`. + +## `SLACK_CLIENT_SECRET` + +Default: `None` + +The Slack Client Secret, required by the Slack integration. +Look it up at [https://api.slack.com/apps/](https://api.slack.com/apps/). + +## `TELEGRAM_BOT_NAME` + +Default: `ExampleBot` + +The [Telegram](https://telegram.org/) bot name, required by the Telegram integration. + +To set up the Telegram integration: + +* Create a Telegram bot by talking to the +[BotFather](https://core.telegram.org/bots#6-botfather). Set the bot's name, +description, user picture, and add a "/start" command. +* After creating the bot you will have the bot's name and token. Put them +in `TELEGRAM_BOT_NAME` and `TELEGRAM_TOKEN` environment variables. +* Run the `settelegramwebhook` management command. This command tells Telegram +where to forward channel messages by invoking Telegram's +[setWebhook](https://core.telegram.org/bots/api#setwebhook) API call: + +```bash +$ ./manage.py settelegramwebhook +Done, Telegram's webhook set to: https://my-monitoring-project.com/integrations/telegram/bot/ +``` + +For this to work, your `SITE_ROOT` must be publicy accessible and use the "https://" +scheme. + +## `TELEGRAM_TOKEN` + +Default: `None` + +The Telegram bot user's authentication token, required by the Telegram integration. + +## `TRELLO_APP_KEY` + +Default: `None` + +## `TWILIO_ACCOUNT` + +Default: `None` + +## `TWILIO_AUTH` + +Default: `None` + +## `TWILIO_FROM` + +Default: `None` + +## `TWILIO_USE_WHATSAPP` + +Default: `False` + +## `USE_PAYMENTS` + +Default: `False` + +A boolean that turns on/off billing features. \ No newline at end of file diff --git a/templates/docs/signaling_failures.html b/templates/docs/signaling_failures.html index 5913fb63..fa3c8103 100644 --- a/templates/docs/signaling_failures.html +++ b/templates/docs/signaling_failures.html @@ -4,30 +4,28 @@ ping URL: append either /fail or /{exit-status} to you The exit status should be a 0-255 integer. SITE_NAME will interpret exit status 0 as success and all non-zero values as failures.

      Examples:

      -
      # Reports failure by appending the /fail suffix:
      +
      # Reports failure by appending the /fail suffix:
       curl --retry 3 PING_URL/fail
       
       # Reports failure by appending a non-zero exit status:
       curl --retry 3 PING_URL/1
       
      -

      By actively signaling failures to SITE_NAME, you can minimize the delay from your monitored service encountering a problem to you getting notified about it.

      Shell Scripts

      The below shell script appends $? (a special variable which contains the exit status of the last executed command) to the ping URL:

      -
      #!/bin/sh
      +
      #!/bin/sh
       
       /usr/bin/certbot renew
       curl --retry 3 PING_URL/$?
       
      -

      Python

      Below is a skeleton code example in Python which signals a failure when the work function returns an unexpected value or throws an exception:

      -
      import requests
      +
      import requests
       URL = "PING_URL"
       
       def do_work():
      diff --git a/templates/front/base_docs.html b/templates/front/base_docs.html
      index f5a1e18f..bc25d35e 100644
      --- a/templates/front/base_docs.html
      +++ b/templates/front/base_docs.html
      @@ -42,6 +42,10 @@
               
               {% include "front/docs_nav_item.html" with slug="resources" title="Third-party resources" %}
       
      +        
      +        {% include "front/docs_nav_item.html" with slug="self_hosted" title="Overview" %}
      +        {% include "front/docs_nav_item.html" with slug="self_hosted_configuration" title="Configuration" %}
      +
               
               
    • Cron syntax cheatsheet