<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Uptime-Kuma – Serverküche</title><link>https://serverkueche.de/en/tags/uptime-kuma/</link><description>Uptime-Kuma – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>en-US</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Sun, 19 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/en/tags/uptime-kuma/index.xml" rel="self" type="application/rss+xml"/><item><title>Installing Uptime Kuma: server monitoring behind Traefik</title><link>https://serverkueche.de/en/tutorials/uptime-kuma-monitoring/</link><pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/en/tutorials/uptime-kuma-monitoring/</guid><description>Set up Uptime Kuma behind Traefik and monitor your services: monitors, notifications and a status page – the first real app of the series.</description><content:encoded><![CDATA[<p>Traefik is up – now we hang the first real app behind it. <strong>Uptime Kuma</strong> is ideal for
that: tiny, immediately useful and without a database. It monitors your services and raises
the alarm when one fails – from now on <em>you</em> notice first that something is stuck, not your
users. Along the way you learn the pattern every further app repeats.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>By the end, <strong>Uptime Kuma 2.4</strong> runs at <code>https://status.YOUR_DOMAIN</code>, secured via Traefik
with automatic HTTPS. You&rsquo;ve set up the first monitor (which checks every minute whether a
service responds), connected a notification and optionally a public status page. For the
first time we bind a service that <strong>doesn&rsquo;t listen on port 80</strong> – an important detail for all
the following apps.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A running <a href="/en/tutorials/traefik-reverse-proxy/">Traefik reverse proxy</a> including the
<code>proxy</code> network and a working Let&rsquo;s Encrypt resolver <code>le</code></li>
<li>A DNS record <code>status.YOUR_DOMAIN</code> that
<a href="/en/tutorials/connect-domain-to-server/">points to the server</a></li>
</ul>
<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-the-composeyaml">Step 1: The compose.yaml</h3>
<p>Own folder, own file:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p ~/uptime-kuma <span class="o">&amp;&amp;</span> <span class="nb">cd</span> ~/uptime-kuma</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">uptime-kuma</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">louislam/uptime-kuma:2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">kuma-data:/app/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">proxy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.enable=true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.kuma.rule=Host(`status.YOUR_DOMAIN`)&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.kuma.entrypoints=websecure&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.kuma.tls.certresolver=le&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.services.kuma.loadbalancer.server.port=3001&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">kuma-data</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">proxy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">external</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></div>
</div>
<p>You know this from the Traefik tutorial – except for <strong>one new, decisive line</strong>:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.services.kuma.loadbalancer.server.port=3001&#34;</span></span></span></code></pre></div>
</div>
<p>Uptime Kuma listens internally on <strong>port 3001</strong>, not on 80. This line tells Traefik which
port to forward the requests to. Without it, Traefik guesses wrong and you get a <code>Bad Gateway</code>. Remember the label – every app that doesn&rsquo;t run on port 80 needs it.</p>
<p>The rest is the familiar pattern: <strong>no <code>ports:</code></strong> (only reachable via Traefik), <code>proxy</code>
network, named volume for the data.</p>
<h3 id="step-2-start-and-first-login">Step 2: Start and first login</h3>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose up -d
</span></span><span class="line"><span class="cl">docker compose logs -f uptime-kuma</span></span></code></pre></div>
</div>
<p>When Kuma is ready, the log ends with this line – from here the service accepts requests
(<code>Ctrl+C</code> only ends the following):</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">[SERVER] INFO: Welcome to Uptime Kuma
</span></span><span class="line"><span class="cl">[SERVER] INFO: Uptime Kuma Version: 2.4.0
</span></span><span class="line"><span class="cl">[SETUP-DATABASE] INFO: Listening on:
</span></span><span class="line"><span class="cl">[SETUP-DATABASE] INFO: -  http://localhost:3001</span></span></code></pre></div>
</div>
<p>On the first start, Kuma creates its database in the volume – that takes a few seconds. Then
open <code>https://status.YOUR_DOMAIN</code> in the browser. Uptime Kuma 2.x first asks for the
<strong>database</strong> – for a setup like ours, <strong>SQLite</strong> is the right, simplest choice (select it,
click <strong>Next</strong>). Right after that you create the <strong>admin account</strong> (username + strong
password).</p>
<p><figure class="my-6"><img src="/en/tutorials/uptime-kuma-monitoring/kuma-setup_hu_1d0c56e67101b8af.webp" srcset="/en/tutorials/uptime-kuma-monitoring/kuma-setup_hu_8fae09095cd4616e.webp 480w, /en/tutorials/uptime-kuma-monitoring/kuma-setup_hu_1d0c56e67101b8af.webp 768w, /en/tutorials/uptime-kuma-monitoring/kuma-setup_hu_6992115843b8c5c4.webp 1200w, /en/tutorials/uptime-kuma-monitoring/kuma-setup_hu_7dac57d86ca48603.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/uptime-kuma-monitoring/kuma-setup_hu_2fd60a2da8963f4b.webp"
    alt="Uptime Kuma&rsquo;s initial setup: choose the language and create the admin account" title="Initial setup: choose the language and create the admin account"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Initial setup: choose the language and create the admin account</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Create the admin account immediately
  </p>
  <div class="prose-kitchen text-sm">As long as no admin account exists, <strong>anyone</strong> who opens the page can create one. Do this
right after the first start – not &ldquo;later&rdquo;.</div>
</div>
<h3 id="step-3-create-the-first-monitor">Step 3: Create the first monitor</h3>
<p>A <strong>monitor</strong> is a recurring check. Click <strong>Add New Monitor</strong> and create one for Traefik
itself:</p>
<ul>
<li><strong>Monitor type:</strong> <code>HTTP(s)</code></li>
<li><strong>Friendly name:</strong> <code>Traefik Dashboard</code></li>
<li><strong>URL:</strong> <code>https://traefik.YOUR_DOMAIN</code></li>
<li><strong>Heartbeat interval:</strong> <code>60</code> seconds</li>
<li><strong>Authentication:</strong> the Traefik dashboard is protected by basic auth (step 7 of the
<a href="/en/tutorials/traefik-reverse-proxy/">Traefik tutorial</a>) – so choose <strong>HTTP Basic Auth</strong> as
the authentication method below and enter the user and password. Without credentials, Kuma
only gets <code>401</code> and reports the monitor as <strong>Down</strong>.</li>
</ul>
<p>Save – after a few seconds the monitor is <strong>Up</strong> (green) and shows the response time.</p>
<p><figure class="my-6"><img src="/en/tutorials/uptime-kuma-monitoring/kuma-dashboard_hu_ecad2a835a6b6005.webp" srcset="/en/tutorials/uptime-kuma-monitoring/kuma-dashboard_hu_b9fd222e62394661.webp 480w, /en/tutorials/uptime-kuma-monitoring/kuma-dashboard_hu_ecad2a835a6b6005.webp 768w, /en/tutorials/uptime-kuma-monitoring/kuma-dashboard_hu_84686854fd419462.webp 1200w, /en/tutorials/uptime-kuma-monitoring/kuma-dashboard_hu_25a9861864b2b7ef.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/uptime-kuma-monitoring/kuma-dashboard_hu_efc1a897fd354ecc.webp"
    alt="The Uptime Kuma dashboard with two running monitors – both green with 100% availability and &ldquo;200 – OK&rdquo;" title="The dashboard with two running monitors"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The dashboard with two running monitors</figcaption></figure></p>
<p>Besides the simple <code>HTTP(s)</code> check, it pays to choose the matching <strong>monitor type</strong>:</p>
<ul>
<li><strong>HTTP(s) – Keyword:</strong> additionally checks whether a certain word appears in the response
text. This detects &ldquo;the server responds, but shows an error page&rdquo;.</li>
<li><strong>TCP port:</strong> for services without a web interface (e.g. a database, an SSH port). Only
checks whether the port is open.</li>
<li><strong>Ping:</strong> the simplest reachability test via ICMP.</li>
<li><strong>Docker container:</strong> checks the container status directly via the Docker socket – handy
for internal services without their own domain.</li>
<li><strong>Push:</strong> here <em>the monitored service</em> calls Kuma regularly. Ideal for cron jobs and
backups: if the script doesn&rsquo;t report in time, Kuma raises the alarm (&ldquo;dead man&rsquo;s switch&rdquo;).</li>
</ul>
<p>Create the matching monitor for every important service.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Tip
  </p>
  <div class="prose-kitchen text-sm">Check <strong>public services via their real domain</strong> (<code>https://…</code>), not via <code>localhost</code>. This way
you simultaneously test that Traefik and the certificate work from outside – not just that
the container is running.</div>
</div>
<p>For the <code>HTTP(s)</code> monitor, the option <strong>&ldquo;certificate expiry notification&rdquo;</strong> is also worth it:
Kuma then warns in good time before a TLS certificate expires. For services behind Traefik,
Let&rsquo;s Encrypt renews automatically – but this very automation occasionally fails silently (a
DNS record is changed, port 80 accidentally closed). The monitor is your safety net and
reports in while there are still days to fix it, instead of visitors suddenly facing a
certificate warning.</p>
<h3 id="step-4-set-up-notifications-email-and-telegram">Step 4: Set up notifications (email and Telegram)</h3>
<p>A monitor without an alarm is just a pretty chart. Under <strong>Settings → Notifications → Setup
Notification</strong> you create a channel. Uptime Kuma supports over 90 – we set up the two most
common completely: <strong>email</strong> for the classic message and <strong>Telegram</strong> for push straight to
the phone.</p>
<h4 id="email-smtp">Email (SMTP)</h4>
<p>Choose &ldquo;Email (SMTP)&rdquo; as the <strong>notification service</strong> and enter your mail provider&rsquo;s data:</p>
<ul>
<li><strong>Hostname / port:</strong> e.g. <code>smtp.YOUR_PROVIDER.com</code> and <code>587</code></li>
<li><strong>Security:</strong> <code>STARTTLS</code> (port 587) or <code>TLS/SSL</code> (port 465)</li>
<li><strong>Username / password:</strong> your SMTP credentials</li>
<li><strong>From / to address:</strong> which address the warning comes from and which it&rsquo;s sent to</li>
</ul>
<p><figure class="my-6"><img src="/en/tutorials/uptime-kuma-monitoring/kuma-email_hu_7f1e9c91a901332a.webp" srcset="/en/tutorials/uptime-kuma-monitoring/kuma-email_hu_e7e333a89de51892.webp 480w, /en/tutorials/uptime-kuma-monitoring/kuma-email_hu_7f1e9c91a901332a.webp 768w, /en/tutorials/uptime-kuma-monitoring/kuma-email_hu_a1d62b8025eec0b7.webp 1200w, /en/tutorials/uptime-kuma-monitoring/kuma-email_hu_6c1a492676432907.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/uptime-kuma-monitoring/kuma-email_hu_dc87d46846cc61b7.webp"
    alt="The email notification (SMTP) in Uptime Kuma: hostname, port, security and from address" title="Setting up the email notification (SMTP)"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Setting up the email notification (SMTP)</figcaption></figure></p>
<p>Click <strong>Test</strong> – within a few seconds a test message lands in the mailbox. Only when it
really arrives are the credentials and port correct. Don&rsquo;t forget to save.</p>
<h4 id="telegram">Telegram</h4>
<p>Telegram is ideal for instant push alerts to the phone – without your own mail server. You
need two pieces of information:</p>
<ol>
<li><strong>Bot token:</strong> message <a href="https://t.me/BotFather">@BotFather</a> in Telegram, send <code>/newbot</code>,
assign a name – BotFather replies with the <strong>token</strong>.</li>
<li><strong>Chat ID:</strong> send your new bot any message, then open
<code>https://api.telegram.org/bot&lt;YOUR_TOKEN&gt;/getUpdates</code> in the browser and read the
<code>chat.id</code> from the response.</li>
</ol>
<p>Enter the token and chat ID into the Telegram notification (Uptime Kuma links both helpers
directly in the dialog) and click <strong>Test</strong> – the message should appear in the chat
immediately.</p>
<p><figure class="my-6"><img src="/en/tutorials/uptime-kuma-monitoring/kuma-telegram_hu_1feb4facbe88ee6e.webp" srcset="/en/tutorials/uptime-kuma-monitoring/kuma-telegram_hu_c4bb1dc005fd5de9.webp 480w, /en/tutorials/uptime-kuma-monitoring/kuma-telegram_hu_1feb4facbe88ee6e.webp 768w, /en/tutorials/uptime-kuma-monitoring/kuma-telegram_hu_f338e7e25e86656.webp 1200w, /en/tutorials/uptime-kuma-monitoring/kuma-telegram_hu_fa7e43c2efbd8e16.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/uptime-kuma-monitoring/kuma-telegram_hu_2c05a870636172bd.webp"
    alt="The Telegram notification in Uptime Kuma: bot token and chat ID, with a direct link to the BotFather" title="Telegram notification: bot token and chat ID"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Telegram notification: bot token and chat ID</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Otherwise the alarm stays silent
  </p>
  <div class="prose-kitchen text-sm">A configured notification does <strong>not</strong> take effect automatically. Enable it in each monitor
(checkbox in the monitor form) or, in the notification dialog, turn on &ldquo;Enabled by default&rdquo;
and &ldquo;Apply on all existing monitors&rdquo;.</div>
</div>
<p>If you want push messages entirely under your own control (without a Telegram server),
<strong>ntfy</strong> comes later – self-hosted, with its own recipe in the series.</p>
<h3 id="step-5-a-public-status-page-optional">Step 5: A public status page (optional)</h3>
<p>Kuma can publish a <strong>status page</strong> where visitors see whether your services are running.
Here&rsquo;s how:</p>
<ol>
<li><strong>Status Pages → New Status Page</strong>, then assign a <strong>name</strong> (e.g. &ldquo;Serverküche Status&rdquo;) and
a <strong>slug</strong> (the URL, e.g. <code>serverkueche</code>) and click <strong>Next</strong>.</li>
<li>In the editor, <strong>Add Group</strong> (e.g. &ldquo;Services&rdquo;), and below it, add the desired <strong>monitors</strong>
via the selection field.</li>
<li><strong>Save</strong> at the top right – done. The page is then publicly reachable at
<code>https://status.YOUR_DOMAIN/status/serverkueche</code>.</li>
</ol>
<p>Only include what really everyone may see – better leave internal services out.</p>
<p><figure class="my-6"><img src="/en/tutorials/uptime-kuma-monitoring/kuma-statusseite_hu_c4b45400765e134.webp" srcset="/en/tutorials/uptime-kuma-monitoring/kuma-statusseite_hu_34f9e0e0768594d.webp 480w, /en/tutorials/uptime-kuma-monitoring/kuma-statusseite_hu_c4b45400765e134.webp 768w, /en/tutorials/uptime-kuma-monitoring/kuma-statusseite_hu_b036ea3223a2da7.webp 1200w, /en/tutorials/uptime-kuma-monitoring/kuma-statusseite_hu_3c0dc17506dd64f2.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/uptime-kuma-monitoring/kuma-statusseite_hu_652cbd6c4d4b33a1.webp"
    alt="The public status page &ldquo;Serverküche Status&rdquo;: &ldquo;All Systems Operational&rdquo; and both services with 100% availability" title="The finished public status page"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The finished public status page</figcaption></figure></p>
<h3 id="step-6-avoid-false-alarms--fine-tune-the-alarm-behavior">Step 6: Avoid false alarms – fine-tune the alarm behavior</h3>
<p>A monitor that raises the alarm at every brief network hiccup is quickly ignored – and then
you miss the real outage. In the monitor form you set the behavior appropriately:</p>
<ul>
<li><strong>Retries:</strong> the service only counts as &ldquo;Down&rdquo; after <em>n</em> failed checks. <code>2</code>–<code>3</code> filters out
individual dropouts without obscuring real outages for long.</li>
<li><strong>Heartbeat interval on failure:</strong> Kuma may check more often in the error case (e.g. every
20 seconds) to detect recovery quickly.</li>
<li><strong>Resend notification:</strong> Kuma can remind you every <em>x</em> minutes as long as a service is down
– useful so an outage at night doesn&rsquo;t get lost in a single mail.</li>
</ul>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Plan maintenance windows
  </p>
  <div class="prose-kitchen text-sm">If you plan an update with downtime, create a <strong>maintenance window</strong> under <strong>Maintenance</strong>.
Kuma then pauses the alarms for the affected monitors – so you (and the status page) don&rsquo;t
get false alarms while you&rsquo;re at work.</div>
</div>
<h3 id="step-7-monitor-cron-jobs-with-a-push-monitor">Step 7: Monitor cron jobs with a push monitor</h3>
<p>Classic monitors check from outside whether a service <em>responds</em>. For things that <strong>run
silently in the background</strong> – a nightly backup, a sync script, a cron job – the <strong>push
monitor</strong> flips the principle: not Kuma asks, but <em>your script reports in</em>. If the report
fails to come, Kuma raises the alarm – the classic &ldquo;dead man&rsquo;s switch&rdquo;.</p>
<p>Create a monitor of type <strong>Push</strong>. Kuma then shows you a unique <strong>push URL</strong>:</p>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">https://status.YOUR_DOMAIN/api/push/YOUR_TOKEN?status=up&amp;msg=OK&amp;ping=</span></span></code></pre></div>
</div>
<p>You call this URL at the end of your script – for example after a successfully completed
backup:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># ... your backup command ...</span>
</span></span><span class="line"><span class="cl">curl -fsS <span class="s2">&#34;https://status.YOUR_DOMAIN/api/push/YOUR_TOKEN?status=up&amp;msg=Backup+OK&#34;</span> &gt; /dev/null</span></span></code></pre></div>
</div>
<p>Set the <strong>check interval</strong> in Kuma a bit more generously than your cron cadence (if the
backup runs hourly, give Kuma e.g. 90 minutes of tolerance). If no <code>curl</code> comes in that time,
the monitor goes to <strong>Down</strong> and you&rsquo;re notified – so you learn about a backup that did <em>not</em>
run, not only when you urgently need it.</p>
<h3 id="step-8-secure-the-admin-login-with-2fa">Step 8: Secure the admin login with 2FA</h3>
<p>Your Kuma login protects access to all monitors, the stored notification credentials and the
status-page configuration – and it&rsquo;s publicly on the net. So enable <strong>two-factor
authentication</strong>: under <strong>Settings → Security → Two-Factor Authentication</strong>. Kuma shows a QR
code you scan with an authenticator app (e.g. Aegis or 2FAS); to activate, you enter the
generated code once.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Secure the recovery
  </p>
  <div class="prose-kitchen text-sm">Keep the TOTP secret or a second authenticator in a safe place (password manager). If you lose
your phone <strong>and</strong> have no copy, you can otherwise only get back in via the database in the
<code>kuma-data</code> volume.</div>
</div>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong><code>Bad Gateway</code> (502) when opening <code>status.YOUR_DOMAIN</code>.</strong> Almost always the port label
<code>traefik.http.services.kuma.loadbalancer.server.port=3001</code> is missing or has a wrong port.
Traefik then reaches the container but knocks on the wrong port. Check the label and run
<code>docker compose up -d</code> again.</p>
<p><strong><code>404 page not found</code> instead of Kuma.</strong> As with every app behind Traefik:
<code>traefik.enable=true</code> set? Container on the <code>proxy</code> network? Is the domain in the <code>Host(...)</code>
rule correct and does the DNS record <code>status.YOUR_DOMAIN</code> point to the server? The Traefik
dashboard shows under &ldquo;HTTP Routers&rdquo; whether <code>kuma</code> is registered.</p>
<p><strong>The interface loads, but the live update stutters / breaks off.</strong> Kuma uses WebSockets.
Traefik forwards those correctly by default – if the problem still occurs, it&rsquo;s usually an
upstream CDN/proxy (e.g. Cloudflare in &ldquo;proxy&rdquo; mode) that blocks WebSockets. For direct
operation behind Traefik, no extra configuration is needed.</p>
<p><strong>After a re-setup all monitors are gone.</strong> The <code>kuma-data</code> volume was deleted (e.g. by
<code>docker compose down -v</code>). All configuration and history lives solely in this volume – that&rsquo;s
why it&rsquo;s at the top of the next section.</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Back up:</strong> the complete heart of Kuma is the <code>kuma-data</code> volume (a SQLite database). Back
it up regularly – if it&rsquo;s gone, all monitors and the history are gone. We build the off-site
backup for it in the <a href="/en/tutorials/restic-backups/">Restic tutorial</a>.</li>
<li><strong>Updates:</strong> the tag <code>:2</code> stays on the 2.x series and brings bug fixes with
<code>docker compose pull &amp;&amp; docker compose up -d</code>. Before a jump to a new major version (e.g.
later <code>:3</code>), read the release notes and back up the volume first.</li>
<li><strong>Coming from 1.x?</strong> The switch to <code>:2</code> <strong>migrates the SQLite database automatically on the
first start</strong> – that can take a moment, and going back to <code>:1</code> is not intended afterwards.
So back up the <code>kuma-data</code> volume <strong>beforehand</strong>, then you&rsquo;re on the safe side. New
installations (like above) aren&rsquo;t affected.</li>
<li><strong>Honest limitation:</strong> a monitor that runs <strong>on the same server</strong> as the monitored services
can&rsquo;t warn you when the whole server fails – then Kuma is offline too. For that case, add an
<strong>external</strong> watcher. Two cheap ways: a <strong>second Uptime Kuma</strong> on a small server (or at
home) that only monitors this instance via HTTP – or a <strong>free external ping service</strong> that
pings your public status page. This way you also get a notice when the whole host is gone –
the only case a local monitor inherently can&rsquo;t cover.</li>
</ul>
<p>With that you&rsquo;ve internalized the app pattern and monitor everything you hang behind Traefik
from now on. What every further app requires are
<a href="/en/tutorials/restic-backups/">encrypted off-site backups with Restic</a> – so your data
survives a server crash.</p>
]]></content:encoded></item></channel></rss>