Mad World #Save_GAZA: Free Palestine  

Search

Cloudflare Always Online Alternative: Show a Saved Copy When Your Server Is Down

Cloudflare Always Online Alternative: Show a Saved Copy When Your Server Is Down

Short answer: Cloudflare Always Online helps only when Cloudflare cannot reach your server at all, and it can only show pages that were saved earlier by Cloudflare or the Internet Archive. For a copy that you control, save your site with one wget command, upload that folder to Cloudflare, and put a small Worker in front of your site. The Worker sends every visitor to your live server as usual. When the server is down, answers with a gateway error, or gives no answer for 8 seconds, the Worker shows the saved page instead. You do every Cloudflare step in your browser, on the free plan.

We did every step below on a new Cloudflare account with a test domain, nexaforge.si, on 12 November 2026. All the screenshots come from that account. Where you see nexaforge.si, use your own domain.

What you will build

  • site-snapshot: a Worker that only holds the saved copy of your site (its HTML pages, CSS, images and scripts). Nobody visits it directly.
  • snapshot-failover: a Worker in front of your domain. It passes every visit to your server. When your server fails, it takes the page from site-snapshot.

What you need

  • A domain that already uses Cloudflare, with its DNS records set to Proxied (orange cloud). If your domain is not on Cloudflare yet, first change your nameservers to Cloudflare.
  • A public website: pages that anyone can read without signing in, such as a blog, a company site or documentation.
  • A computer with Windows, macOS or Linux, and a browser such as Chrome, Edge or Firefox.
  • About 45 minutes. The free Cloudflare plan is enough.

Why not just turn on Always Online?

Always Online is a switch in your domain's Caching → Configuration page. When Cloudflare cannot connect to your server, it shows an old copy of the requested page: an expired copy from Cloudflare's cache, or else a copy from the Internet Archive's Wayback Machine, with a banner on top.

Cloudflare dashboard, Caching Configuration page: the Always Online setting and its switch
Always Online (1) and its switch (2), in Caching → Configuration. It is free, but it depends on copies saved by someone else.

It takes one click, but it has limits that matter on the day your server really goes down:

  • It works only when Cloudflare cannot connect to your server (Cloudflare errors 520 to 527). If your server is reachable but answers with an error, Always Online does nothing.
  • It shows only pages that were saved before. Cloudflare sends the Internet Archive your most popular pages of the last five hours, and the archive visits them at intervals that depend on your plan. A page that few people read may have no copy at all.
  • It does not help with a slow server. A server that hangs keeps every visitor waiting until Cloudflare gives up.
  • Turning it on shares your hostname and popular addresses with the Internet Archive.
SituationAlways OnlineThis guide
Which pages have a copyPopular pages saved earlier by Cloudflare or the Internet ArchiveEvery public page you saved
How new the copy isThe archive's last visitYour last upload
Cloudflare cannot reach your serverYesYes
Your server answers 502, 503 or 504NoYes
Your server gives no answer for 8 secondsNoYes, for pages that have a copy
Sign-in, forms, cartError pageShort "Back soon" page
PriceFreeFree plan, up to 100,000 Worker requests a day

How the failover Worker decides

Every visit goes through snapshot-failover first. It asks your server for the page, then:

  1. Your server answers normally, also with an error such as 404 or 500: the visitor gets that answer, unchanged.
  2. Your server cannot be reached, or answers 502, 503, 504 or one of Cloudflare's errors 520 to 530: the visitor gets the saved copy of the page.
  3. Your server has not answered after 8 seconds: if the page has a saved copy, the visitor gets it. If it has none, the Worker keeps waiting for your server.
  4. After a failure, the copy answers at once for the next 30 seconds, so the next visitors do not wait 8 seconds again.
  5. Sign-in, account, cart, checkout and admin pages, form submissions, and pages built from a search query never get a copy. While your server is down, they get a short "Back soon" page with status 503.

Each saved page is sent with the header X-Snapshot: 1, so you can always tell when the copy answered.

Diagram: a slow origin request either gets the saved public copy or keeps waiting for the live server when no copy exists
After 8 seconds without an answer, a page with a saved copy gets the copy. A page without one keeps waiting for your server.

Step 1: Save a copy of your site

wget is a free program that visits your site like a reader and saves every public page it finds, with the CSS, images and scripts that each page needs. It does not sign in, so it saves only what the public sees.

Install wget

Windows 10 or 11: open PowerShell (Start menu, type "PowerShell") and run the command below. Then close PowerShell and open it again.

Code
winget install JernejSimoncic.Wget

macOS: with Homebrew installed, open Terminal and run:

Code
brew install wget

Linux: wget is usually installed already. If it is not, on Debian or Ubuntu run:

Terminal
sudo apt install wget

Save the site

Replace https://www.example.com/ with the address that your home page really opens at, with or without www, exactly as your browser shows it. On Linux or macOS, in a terminal:

Terminal
mkdir snapshot
cd snapshot
wget --mirror --page-requisites --adjust-extension --no-host-directories --no-verbose https://www.example.com/

On Windows, in PowerShell, type wget.exe, not wget. In Windows PowerShell, wget is the name of a different command.

Terminal
mkdir snapshot
cd snapshot
wget.exe --mirror --page-requisites --adjust-extension --no-host-directories --no-verbose https://www.example.com/

If you use Docker on Linux or macOS, you do not need to install wget. This is the command we ran; it makes the snapshot folder in the current folder:

Terminal
docker run --rm -v "$PWD/snapshot:/snapshot" -w /snapshot alpine:3 sh -c "apk add --no-cache wget >/dev/null && wget --mirror --page-requisites --adjust-extension --no-host-directories --no-verbose https://www.example.com/"

What the options do:

  • --mirror: follow every link to another page of your site, then the links on those pages, until every page is saved.
  • --page-requisites: also save the CSS, images and scripts that each page shows.
  • --adjust-extension: save /about as about.html, so that Cloudflare knows it is a web page.
  • --no-host-directories: put the files straight into snapshot, not into a www.example.com folder inside it.
  • --no-verbose: print one line for each saved file.

Our test site has three pages. wget (GNU Wget 1.25.0) finished with this line:

YAML
Downloaded: 5 files, 2.8K in 0s (8.15 MB/s)

and the snapshot folder held these files. index.html is the home page.

Code
index.html
about.html
blog/first-post.html
assets/style.css
assets/logo.svg

A real site gives many more files and takes longer. When wget is done, count the files, still inside the snapshot folder. On Linux or macOS:

Code
find . -type f | wc -l

On Windows, in PowerShell:

Code
(Get-ChildItem -Recurse -File).Count

Up to 20,000 files, each smaller than 25 MiB: continue with Step 2. More than that: keep the copy in R2 instead, as shown in "Big site? Keep the copy in R2" below.

Step 2: Upload the copy to Cloudflare

Open dash.cloudflare.com and sign in. In the left menu, open Compute → Workers & Pages (1), then click Create application (2).

Cloudflare dashboard: Workers & Pages in the left menu and the Create application button
Workers & Pages (1), then Create application (2).

Choose Upload your static files.

Cloudflare create application page with the Upload your static files option
Upload your static files: the copy is only files, with no code.

In the upload box, click the word folder and choose your snapshot folder. You can also drag the folder onto the box. If your browser asks whether to upload all the files of the folder, confirm.

Cloudflare Upload and deploy box with the folder link to choose a folder from the computer
Click "folder" (1) and choose the snapshot folder.

Cloudflare lists the files that it will upload. As the Worker name, type site-snapshot (1), then click Deploy (2).

Cloudflare upload form: list of uploaded files, Worker name site-snapshot and the Deploy button
Name the Worker site-snapshot (1) and deploy it (2).

After a few seconds the Worker is live. Cloudflare gives it a test address that ends in workers.dev (1). Visit (2) opens it: you see your home page, served from the copy.

The site-snapshot Worker overview with its workers.dev address and the Visit button
The deployed copy: its workers.dev address (1) and Visit (2).

Turn off the workers.dev address

That test address shows a full second copy of your site. Search engines must not find it, and the failover Worker does not need it. Open the Domains tab of site-snapshot and click the switch next to Production (1) so that it turns grey. Leave the Preview switch off.

site-snapshot Domains tab with the Production workers.dev switch highlighted
Domains tab: switch the Production workers.dev address off (1).

Step 3: Create the failover Worker

Go back to Workers & Pages and click Create application again. This time choose Start with Hello World!.

Cloudflare create application page with Start with Hello World highlighted
Start with Hello World! (1): a small Worker that you replace in a minute.

Name it snapshot-failover (1) and click Deploy (2).

Deploy Hello World form with the Worker name snapshot-failover and the Deploy button
Worker name snapshot-failover (1), then Deploy (2).

On the Worker's page, click Edit code.

snapshot-failover Worker overview with the Edit code button highlighted
Edit code (1) opens the code editor in your browser.

The editor opens the file worker.js (1). Click inside the code, select all of it with Ctrl+A (Cmd+A on a Mac), and paste the code below over it. Then click Deploy (2). The preview on the right says "Not found": that is expected, because this Worker answers only on your own domain, never on its workers.dev address.

Cloudflare code editor with the snapshot failover code pasted in worker.js and the Deploy button
The code pasted in worker.js (1), then Deploy (2).

The complete code. Copy all of it:

Nginx
// Snapshot failover for Cloudflare: visitors get your live site, and a saved copy of it when your server is down.
// It needs one binding named SNAPSHOT: a Worker that holds your saved files, or an R2 bucket that holds them.
const SLOW_MS = 8000;      // Your server has not answered after 8 seconds: show the copy, if there is one.
const OUTAGE_MS = 30000;   // After a failure, go straight to the copy for 30 seconds.
const PRIVATE = /^\/(admin|login|logout|account|cart|checkout|api|wp-admin|wp-login\.php|wp-json)(\/|$)/i;
const TRACKING = /^(utm_.*|gclid|gbraid|wbraid|fbclid|msclkid|_ga|_gl|ref)$/i;
const DOCUMENT = /^(text\/html|application\/(.+\+)?xml|text\/xml)/i;
const R2_FOLDER = 'snapshot/'; // R2 only: the folder you uploaded, as the bucket shows it ('' if the files are at the top).

// Only public pages read by anyone have a copy: no form, no login, no private area.
function eligible(request, url) {
  return (request.method === 'GET' || request.method === 'HEAD')
    && !PRIVATE.test(url.pathname) && !request.headers.has('Authorization');
}

// The names wget gives the saved files: / is index.html, /about is about.html or about/index.html.
function keys(pathname) {
  let path;
  try { path = decodeURIComponent(pathname).replace(/^\/+/, ''); } catch { return []; }
  if (/[\x00-\x1f\x7f\\]|(^|\/)\.\.(\/|$)/.test(path)) return [];
  if (path === '' || path.endsWith('/')) return [path + 'index.html'];
  return /\.[a-z0-9]+$/i.test(path) ? [path] : [path + '.html', path + '/index.html'];
}

async function copyOf(request, env, url) {
  if (!eligible(request, url)) return null;
  try {
    let body = null, type = null;
    // A Worker answers fetch(); an R2 bucket has get(). (Asking a Worker binding for get would call a method it does not have.)
    if (typeof env.SNAPSHOT.fetch === 'function') {
      // A Worker with your saved files: it finds about.html for /about by itself, and sends /about.html on to /about.
      let saved = await env.SNAPSHOT.fetch(new Request(url.origin + url.pathname));
      const next = saved.status >= 300 && saved.status < 400 && saved.headers.get('Location');
      if (next && new URL(next, url.origin).origin === url.origin) {
        await saved.body?.cancel();
        saved = await env.SNAPSHOT.fetch(new Request(new URL(next, url.origin).href));
      }
      if (saved.ok) { body = saved.body; type = saved.headers.get('Content-Type'); }
      else await saved.body?.cancel();
    } else {
      // An R2 bucket.
      for (const key of keys(url.pathname)) {
        const object = await env.SNAPSHOT.get(R2_FOLDER + key);
        if (object) { body = object.body; type = object.httpMetadata?.contentType; break; }
      }
    }
    if (!body) return null;
    // A search page or any other page made from its query has no copy; tracking parameters are fine.
    if (!type || (DOCUMENT.test(type) && ![...url.searchParams.keys()].every((name) => TRACKING.test(name)))) {
      await body.cancel();
      return null;
    }
    if (request.method === 'HEAD') { await body.cancel(); body = null; }
    return new Response(body, { status: 200, headers: {
      'Content-Type': type, 'X-Snapshot': '1', 'X-Content-Type-Options': 'nosniff',
      'Cache-Control': DOCUMENT.test(type) ? 'no-store' : 'public, max-age=3600' } });
  } catch {
    return null;
  }
}

async function inOutage(url) {
  try {
    const mark = await caches.default.match(url.origin + '/__snapshot/outage');
    return Boolean(mark && Date.now() < Number(await mark.text()));
  } catch {
    return false;
  }
}

function markOutage(url, ctx) {
  ctx.waitUntil(caches.default.put(url.origin + '/__snapshot/outage', new Response(String(Date.now() + OUTAGE_MS),
    { headers: { 'Cache-Control': `max-age=${OUTAGE_MS / 1000}` } })).catch(() => {}));
}

function maintenance(request) {
  const page = '<!doctype html><meta charset=utf-8><meta name=viewport content="width=device-width">'
    + '<title>Back soon</title><h1>Back soon</h1><p>This page needs the live site. Please try again in a few minutes.</p>';
  return new Response(request.method === 'HEAD' ? null : page, { status: 503,
    headers: { 'Content-Type': 'text/html; charset=utf-8', 'Retry-After': '900', 'Cache-Control': 'no-store' } });
}

// No answer, or the errors Cloudflare shows when it cannot reach your server (502-504, 520-530).
const down = (response) => !response || (response.status >= 502 && response.status <= 504)
  || (response.status >= 520 && response.status <= 530);

export default {
  async fetch(request, env, ctx) {
    ctx.passThroughOnException();
    const url = new URL(request.url);
    if (url.hostname.endsWith('.workers.dev')) return new Response('Not found', { status: 404 });
    const outage = await inOutage(url);
    if (outage) {
      const copy = await copyOf(request, env, url);
      if (copy) return copy; // During an outage the copy answers at once; a page without one still asks your server.
    }

    const controller = new AbortController();
    const answer = fetch(request, { signal: controller.signal }).catch(() => null);
    let timer;
    let response = eligible(request, url)
      ? await Promise.race([answer, new Promise((resolve) => { timer = setTimeout(() => resolve('slow'), SLOW_MS); })])
      : await answer;
    clearTimeout(timer);
    if (response === 'slow') {
      const copy = outage ? null : await copyOf(request, env, url);
      if (copy || outage) { // A copy, or no copy while your server is known to be down: stop waiting.
        controller.abort();
        markOutage(url, ctx);
        return copy || maintenance(request);
      }
      response = await answer; // No copy of this page: keep waiting for your server's own answer.
    }
    if (!down(response)) return response; // 404, 500 and the like reach the visitor as they are.
    markOutage(url, ctx);
    if (response?.body) ctx.waitUntil(response.body.cancel().catch(() => {}));
    return await copyOf(request, env, url) || maintenance(request);
  },
};

You can leave the code as it is. Two values at the top are yours to change if you want:

  • SLOW_MS: how long a visitor waits for your server before the copy answers, in milliseconds. 8000 is 8 seconds.
  • PRIVATE: the paths that never get a copy. If your site has another private area, for example /members, add |members right after wp-json on that line.

Step 4: Connect the two Workers

The failover Worker reads the copy through a binding: a name in its code, SNAPSHOT, that points to site-snapshot.

Open snapshot-failover, then its Settings tab. Under Bindings (1), click Add binding (2).

snapshot-failover Settings tab with the Bindings section and the Add binding button
Settings → Bindings (1) → Add binding (2).

Choose Service binding (1) and click Add Binding (2).

List of binding types with Service binding selected and the Add Binding button
Service binding (1): a link from one Worker to another.

As the variable name, type SNAPSHOT (1), in capital letters, exactly like that. As the service, choose site-snapshot (2). Click Deploy (3).

Service binding form with the variable name SNAPSHOT, the service site-snapshot and the Deploy button
Variable name SNAPSHOT (1), service site-snapshot (2), Deploy (3).

Step 5: Test it safely on a test name

Before you touch your real site, test on a name with no server behind it: test on your domain, pointed to 192.0.2.1. That address is reserved for examples and nothing answers there, so it acts exactly like a server that is down.

Add the test DNS record

Open your domain in the dashboard, then DNS → Records, and click Add record.

Cloudflare DNS records page of nexaforge.si with the Add record button
DNS → Records → Add record (1). Your existing records stay as they are.

Type A. Name test (1). IPv4 address 192.0.2.1 (2). Proxy status Proxied (3): the orange cloud must be on. Click Save (4).

Add record form: type A, name test, IPv4 address 192.0.2.1, proxied, and the Save button
test points to 192.0.2.1, proxied through Cloudflare.

Put the Worker on the test name

Go back to Workers & Pages → snapshot-failover. Open the Domains tab (1) and click Add Route (2).

snapshot-failover Domains tab with the Add Route button
Domains (1) → Add Route (2).

As the Zone, choose your domain (1). As the Route, type the test name followed by /* (2), for us test.nexaforge.si/*. The * means every page under that name. Under Failure mode, choose Fail open (proceed) (3). Click Add Route (4).

Add Route form: zone nexaforge.si, route test.nexaforge.si/*, Fail open selected, Add Route button
Zone (1), route (2), Fail open (3), Add Route (4).

Fail open matters. If the Worker ever fails, or the free plan's daily limit is reached, visitors go straight to your server instead of seeing a Cloudflare error.

Open the test address

Open https://test. followed by your domain in your browser. The first time, the page takes about 8 seconds, because the Worker waits for the missing server. Then your saved home page appears. Click a few links: they open at once.

Browser at https://test.nexaforge.si/ showing the saved NexaForge home page while no server answers
No server answers at test.nexaforge.si, and the saved home page shows anyway.

To see proof that the copy answered, run this in a terminal, with your own test name. On Windows, type curl.exe instead of curl.

Terminal
curl -sI https://test.example.com/

Our result, with the other headers removed:

YAML
HTTP/2 200
content-type: text/html
cache-control: no-store
x-snapshot: 1
server: cloudflare

The first answer took 8.7 seconds. The next pages, from the same Cloudflare data center, took 0.1 to 0.3 seconds. A sign-in page got the "Back soon" page, status 503, after about 20 seconds: the time Cloudflare took to give up on the missing server. Sign-in pages always need the real server, so the Worker never answers them from the copy.

Step 6: Turn it on for your real site

When the test works, add the routes of your real site the same way (Domains → Add Route, with Fail open), one for each name your site uses:

  • example.com/*
  • www.example.com/*

Nothing changes for your visitors: they now pass through the Worker, and your server's answers reach them unchanged. Open a few pages and your sign-in page once to check.

Then remove the test: delete the test DNS record, and remove the test route in the Domains tab of snapshot-failover. The test name shows a full copy of your site at another address, and search engines must not find it.

Step 7: Keep the copy fresh

The copy is only as new as your last upload. A page published after it has no copy, so it shows "Back soon" during an outage. After you publish or change pages, run wget again in a new, empty snapshot folder (Step 1), then upload the new folder. Open site-snapshot and click New deployment (1).

site-snapshot Worker overview with the New deployment button highlighted
New deployment (1) on site-snapshot. "No URLs enabled" confirms that its workers.dev address is off.

Choose the new folder. Cloudflare lists the files (1). Click Deploy (2). The new copy replaces the old one; the binding and the routes stay as they are.

New deployment upload form listing the uploaded files and the Deploy button
The files of the new copy (1), then Deploy (2).

Once a week is enough for most blogs; once a day if you publish every day. If you want to automate it later, Cloudflare's command-line tool, Wrangler, can deploy a folder of static assets from a script.

Big site? Keep the copy in R2

On the free plan, the site-snapshot Worker holds up to 20,000 files, each up to 25 MiB (100,000 files on Workers Paid). Above that, keep the copy in an R2 bucket, Cloudflare's file storage. The same failover code works with R2; only the binding changes.

R2 has a free monthly allowance: 10 GB of storage, 1 million Class A operations (writes) and 10 million Class B operations (reads). You still need a payment method on file to turn R2 on.

In the left menu, open Storage & databases → R2 Object Storage. The first time, Cloudflare shows the R2 plan with Total Due Now (1). Click Add R2 subscription to my account (2).

R2 plan page with the free monthly operations, Total Due Now and the Add R2 subscription button
Total Due Now (1) is $0.00. Add R2 subscription to my account (2).

Check the payment method, tick both boxes (1, 2), and click Activate R2 (3). Cloudflare charges the card only for use above the free allowance.

R2 activation form with the payment method, two agreement check boxes and the Activate R2 button
Both boxes (1, 2), then Activate R2 (3). The card number is hidden in this screenshot.

Click Create bucket.

R2 Object Storage overview with the Create bucket button
Create bucket (1).

Name it site-snapshot (1), keep the location on Automatic, and click Create bucket at the bottom of the form.

Create a bucket form with the bucket name site-snapshot and the Automatic location
Bucket name site-snapshot (1). The name cannot be changed later.

In the bucket, click select from computer (1), or Upload when the bucket already holds files. Then click Folders (2) and choose your snapshot folder. When the upload ends, the bucket shows a snapshot/ folder.

R2 bucket upload area with select from computer and the Folders choice highlighted
select from computer (1), then Folders (2). Below, the snapshot/ folder from our upload.

Now point the binding to the bucket. Open snapshot-failover → Settings → Bindings. Delete the SNAPSHOT service binding (Cloudflare asks to confirm with Delete & Deploy), because one name can have only one binding. Then click Add binding → R2 bucket. Variable name SNAPSHOT (1), R2 bucket site-snapshot (2), then Deploy (3).

R2 bucket binding form with the variable name SNAPSHOT, the bucket site-snapshot and the Deploy button
Variable name SNAPSHOT (1), bucket site-snapshot (2), Deploy (3).

The dashboard keeps the name of the folder that you uploaded in front of every file: snapshot/index.html. That is why the code has R2_FOLDER = 'snapshot/'. If you upload a folder with another name, put that name there. If the files are at the top of the bucket, set it to ''.

The dashboard accepts files up to 300 MB each. For thousands of files, Cloudflare recommends rclone or another S3-compatible tool. We tested the R2 binding on the same test name: the copy answered with x-snapshot: 1, exactly as with site-snapshot.

Limits and costs

  • Free plan: 100,000 Worker requests a day. Each request that passes through snapshot-failover counts: pages, images, CSS and scripts. With Fail open, the requests above the limit go straight to your server. Your site keeps working, without the copy, until the count resets at midnight UTC. For a busy site, Workers Paid costs at least $5 a month and includes 10 million requests a month.
  • Reading the copy is free. Requests to the static files of site-snapshot are free and unlimited.
  • The copy cannot do what needs your server: sign-in, comments, forms, carts and search show "Back soon" until the server is back.
  • The first visitor waits. After a failure, the first visitor in each Cloudflare data center waits up to 8 seconds. Then the copy answers at once there for 30 seconds.
  • The copy is public. Never upload pages that only signed-in users may see. wget does not sign in, so it cannot save them by itself.

Troubleshooting

  • wget saves only index.html. Your robots.txt may tell programs like wget to stay out. It is your own site, so add -e robots=off to the wget command.
  • wget stops with "403 Forbidden". Your own Cloudflare security settings, for example Bot Fight Mode or a WAF rule, may block wget. Turn Bot Fight Mode off while wget runs, or add a WAF rule that skips your own IP address, then turn it back on.
  • The test address shows a Cloudflare error (522), not the copy. The route is missing or wrong. It must be your test name followed by /*, on the right zone. Also check that the DNS record is Proxied.
  • Every page shows "Back soon". The binding is missing or its name is not exactly SNAPSHOT. Check snapshot-failover → Settings → Bindings. With R2, also check R2_FOLDER against the folder name that the bucket shows.
  • The home page works, but another page shows "Back soon". That page is not in the copy. Check that wget saved it: /about must be about.html or about/index.html in the snapshot folder. wget follows links only; a page that no other page links to is not saved.
  • The site is slow and the copy never shows. That page has no copy, or it is a sign-in, cart or form page. The Worker then keeps waiting for your server, because it has nothing else to show.

Frequently asked questions

What do visitors see during an outage?

Your pages as they were at your last upload, at their normal addresses, with no banner. Sign-in pages and forms show a short "Back soon" page that asks them to try again in a few minutes.

Will Google see duplicate content?

Not from the copy on your own domain: it answers at your real addresses, with your own content. Only other addresses can show a second copy, which is why you turn off the workers.dev address of site-snapshot (Step 2) and remove the test name when you are done (Step 6).

Does this work with WordPress?

The code already treats wp-admin, wp-login.php and wp-json as private. The public pages of a WordPress site are ordinary HTML pages, which wget saves like any others. Comments and contact forms need the live server.

Do I need to know JavaScript?

No. You paste the code as it is. The only value you may have to change is R2_FOLDER, and only with the R2 option.

I only want a "we are down" notice. Is there a simpler way?

Yes, a maintenance page. See Cloudflare maintenance mode with a Synology script.

How do I know when my server is down?

The copy keeps your readers happy, but you still need to fix the server. A monitor such as Uptime Kuma on Docker checks your site every minute and warns you when it stops answering.

Sources

Yassine

Yassine

Yassine founded IGProd to educate the visitors with technological tutorials. These helpful guides are available for all sorts of professionals and novices, whether they work in technology or not!

Surf freely 💗

Leave a comment

Your email address will not be published. Required fields are marked *

Your experience on this site will be improved by allowing cookies Cookie Policy