bolt Valebyte VPS від $4/міс — NVMe, запуск за 60 секунд.

Отримати VPS arrow_forward
eco Початковий Туторіал

Installing Gatus on a VPS: Website Monitoring, SSL Alerts, and Telegram Notifications

calendar_month Oct 03, 2026 schedule 18 хв. читання visibility 24 переглядів
Установка Gatus на VPS: мониторинг сайтов, SSL-алерты и уведомления в Telegram
info

Потрібен сервер для цього гайду? Ми пропонуємо виділені сервери та VPS у 50+ країнах з миттєвим налаштуванням.

Потрібен сервер для цього гайду?

Розгорніть VPS або виділений сервер за хвилини.

Installing Gatus on a VPS: website monitoring, SSL alerts, and Telegram notifications

TL;DR

Gatus is a lightweight self-hosted monitoring service that regularly checks the availability of websites, APIs, TCP ports, and SSL certificate expiration dates. In this guide, you will deploy Gatus via Docker Compose on a VPS, place it behind a Caddy HTTPS proxy, and configure Telegram notifications for service failures and recoveries.

  • For basic monitoring of 20–100 endpoints, 1 vCPU, 1 GB RAM, and 10 GB SSD are sufficient.
  • Gatus will run in Docker Compose with SQLite storage and automatic restart.
  • Endpoint configuration is stored in YAML, while the Telegram token is kept in a separate .env file.
  • Caddy will automatically issue and renew a Let’s Encrypt TLS certificate for the Gatus dashboard.
  • HTTP checks, API checks, SSL alerts, a healthcheck, and backups will be configured.
  • The end includes troubleshooting for common issues: Telegram, TLS, Docker, firewall, and an unavailable dashboard.

What we are configuring and why

Gatus is an open-source availability monitoring tool written in Go. It is suitable for a VPS owner who wants to see the status of their own websites, REST APIs, VPN dashboards, game servers, Git services, mail, or external dependencies without sharing an infrastructure inventory with third-party SaaS monitoring services.

The service performs checks on a schedule. For example, it can send an HTTP request to https://example.com/health, verify that the server returned code 200, check a JSON response field, measure latency, and warn you if an SSL certificate expires in 21 days. For TCP services, Gatus can check whether a port is open, and for ICMP, whether a host is reachable via ping.

As a result, you will have a web status dashboard at an address such as https://status.example.com, a history of checks, response times, availability percentage, and Telegram notifications. Notifications are sent not for a single random timeout, but after a specified number of consecutive failures. Once a service recovers, Gatus will also send a separate message.

What exactly will be deployed

  • Ubuntu Server 24.04 LTS or 26.04 LTS on a VPS.
  • Docker Engine 27+ or a newer stable version.
  • Docker Compose Plugin v2.
  • A Gatus container from the official twinproduction/gatus image.
  • A Caddy 2.9+ container for reverse proxying and automatic HTTPS.
  • A Gatus SQLite database in a Docker volume.
  • Endpoint configuration in YAML and secrets in the .env file.
  • Configuration and SQLite database backups via restic.

What checks Gatus supports

Check type Example use case Success condition
HTTP/HTTPS Website homepage or API endpoint Response code 200, required header, or text in the body
JSON API /health, payment webhook, SaaS backend JSONPath value matches the expected value
TCP SSH, PostgreSQL, Redis, Minecraft, SMTP Port accepts a connection
ICMP Checking availability of a remote host Host responds to ping
SSL/TLS Website with a Let’s Encrypt or commercial certificate Certificate is valid and does not expire before the threshold

Self-hosted Gatus or cloud monitoring

Cloud monitoring services are convenient if you need multiple geographically distributed monitoring locations, SLA reports for clients, and minimal administration. Their downside is a monthly fee, a limited number of checks on low-cost plans, and sharing data about your domains, endpoints, and incidents with an external provider.

Self-hosted Gatus on a VPS is better suited for personal infrastructure, a small SaaS, a development team, or a set of internal services. It does not require a separate database at the start, consumes few resources, and keeps history under your control. It is important to understand the limitation: if Gatus is hosted in the same data center as the monitored website, it will not detect a complete network outage at that location. For critical services, it is useful to maintain a second instance in another location.

What VPS configuration is needed for this task

Gatus does not require a powerful server. The load depends on the number of endpoints, check interval, number of TCP connections, and history retention period. For most personal and small commercial projects, the limiting factor will not be CPU, but sensible SQLite database storage and a stable network.

Scenario CPU RAM Disk Network
Up to 30 endpoints, 1–5 minute interval 1 vCPU 1 GB 10 GB SSD 100 Mbps
30–200 endpoints, API checks and history 1–2 vCPU 2 GB 20–30 GB NVMe 100–300 Mbps
200–1000 endpoints, multiple groups 2–4 vCPU 4 GB 50 GB NVMe 1 Gbps

A practical starting option is 1 vCPU, 2 GB RAM, 20 GB NVMe, and a public IPv4 address. This capacity is sufficient for Gatus, Caddy, Docker, fail2ban, configuration backups, and several dozen checks every minute. As one neutral option, you can choose a VPS with the specified characteristics, but prioritize location proximity, network quality, and the availability of regular snapshots.

When you need a dedicated server instead of a VPS

A dedicated server is almost never necessary for Gatus alone. Dedicated hardware makes sense if monitoring is only part of a large observability platform: Prometheus, Grafana, Loki, Uptime Kuma, a CI system, and hundreds of containers run alongside it. It is also useful when isolation is required, log volumes are high, or there are thousands of checks at short intervals.

If you simply monitor 10–200 domains and services, a VPS is simpler, cheaper, and scales faster. As load grows, moving Gatus to a larger VPS usually comes down to restoring configuration files and the SQLite volume from a backup.

How to choose a location

Location affects check latency and which network problems you will see. If your website users are in Europe, it makes sense to place monitoring in a European data center. If the infrastructure is located in one country and you need to see it “from the outside,” choose an independent facility and network.

Do not install Gatus on the same host it monitors: if the server fails, monitoring disappears as well. The minimum sensible setup is a separate VPS. For important projects, use two independent instances in different countries or with different providers and send notifications to different Telegram chats.

Server preparation

The following assumes a clean Ubuntu 24.04 LTS or Ubuntu 26.04 LTS server with a public IPv4 address, the domain status.example.com, and an A DNS record pointing to the VPS IP. Before issuing the certificate, make sure DNS has already propagated: Caddy must be externally accessible on ports 80 and 443.

Update the system

Connect to the server as the user provided during provisioning or as root. First, install security updates and basic utilities.

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl ca-certificates gnupg ufw fail2ban nano jq unzip
sudo reboot

The commands update packages, install the required utilities, firewall, and brute-force protection, then reboot the server.

Create a separate administrator account

Do not work permanently as root. Create a user, add it to the sudo group, and add an SSH public key in advance. In this example, the username is deploy.

sudo adduser deploy
sudo usermod -aG sudo deploy
sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
sudo nano /home/deploy/.ssh/authorized_keys
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown deploy:deploy /home/deploy/.ssh/authorized_keys

Insert one line containing your public key into the authorized_keys file, for example, the contents of ~/.ssh/id_ed25519.pub on your local computer. Before closing the current SSH session, be sure to test login in a new terminal.

ssh deploy@SERVER_IP

This command verifies that key-based login works for the new user.

Disable password-based SSH login

After verifying the key, disable password authentication and root login. This significantly reduces the likelihood of server compromise through automated brute-force attacks.

sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
sudo sshd -t && sudo systemctl restart ssh

The command checks the SSH configuration syntax and restarts SSH only if there are no errors.

Configure UFW and fail2ban

The Gatus dashboard must be available over HTTPS, while HTTP is required by Caddy for initial domain validation and redirection to HTTPS. Keep SSH open only after confirming that you can reconnect.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

The commands enable the firewall and leave only SSH, HTTP, and HTTPS open. There is no need to expose Gatus port 8080 externally: it will be accessible only to the Caddy container on the internal Docker network.

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

This enables fail2ban at system boot and displays the SSH protection status. If you restrict server access to fixed IPs, additionally create UFW rules that allow SSH only from your network.

Software Installation — Step by Step

For deployment, we use Docker Engine and the Compose Plugin from the official Docker repository. As of 2026, it is recommended to use the current stable Docker Engine 27+ branch or a newer available version, rather than the old docker.io package from the standard Ubuntu repository.

Add the Official Docker Repository

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

This block creates a directory for APT keys and adds the signing key for the official Docker repository.

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update

The command adds the repository matching the Ubuntu version and server architecture, then updates the package index.

Install Docker Engine and Compose

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker deploy

This block installs Docker, enables it to start automatically, and allows the deploy user to run Docker without sudo. After completing it, exit the SSH session and reconnect to refresh group membership.

exit
ssh deploy@SERVER_IP
docker version
docker compose version

Verify that Docker Engine and the Compose Plugin are available. If the docker ps command returns a socket access error, reconnect once more or run newgrp docker.

Create the Project Structure

All Gatus files will be stored in /opt/gatus. This directory is convenient for backups, migration, and verification through a configuration management system without secrets.

sudo mkdir -p /opt/gatus/{config,caddy,data,backups}
sudo chown -R deploy:deploy /opt/gatus
cd /opt/gatus
umask 077
touch .env
chmod 600 .env

The commands create working directories, assign ownership to the deploy user, and create a protected file for Telegram secrets.

Create a Telegram Bot and Find the Chat ID

Open the official @BotFather bot in Telegram, run the /newbot command, and set a name and username. BotFather will return a token in the format 123456789:AA.... Do not publish it in Git, tickets, screenshots, or configuration accessible to other users.

Create a private chat with the bot and send it any message, such as /start. For a group chat, add the bot to the group and send a message in that group. Retrieve the chat identifier on the server by substituting the token:

curl -s "https://api.telegram.org/botВАШ_ТОКЕН/getUpdates" | jq

In the JSON, find the message.chat.id field. For Telegram groups, the chat ID often starts with a minus sign, for example -1001234567890. Save the token and identifier in /opt/gatus/.env.

cd /opt/gatus
nano .env
TELEGRAM_TOKEN=123456789:REPLACE_WITH_REAL_TOKEN
TELEGRAM_CHAT_ID=-1001234567890
GATUS_DOMAIN=status.example.com
[email protected]

This file contains secrets and environment parameters. It must not be readable by other users and must not be committed to a public repository.

Gatus, Telegram, and HTTPS Configuration

In this setup, Gatus listens on port 8080 only within the Docker network. Caddy accepts external requests on ports 80 and 443, automatically obtains a TLS certificate, and forwards traffic to Gatus. This prevents the service port from being exposed and eliminates manual Let’s Encrypt maintenance.

Create the Gatus Configuration Template

Gatus uses YAML. We store the config.yaml.template template, and Compose substitutes Telegram variables through envsubst at startup. This prevents the token from ending up in a persistent YAML file that could be committed accidentally.

cd /opt/gatus
nano config/config.yaml.template
storage:
  type: sqlite
  path: /data/gatus.db
  caching: true

ui:
  title: "Infrastructure Status"
  description: "Availability and SSL monitoring"
  default-sort-by: group

metrics: true

alerting:
  telegram:
    token: "${TELEGRAM_TOKEN}"
    id: "${TELEGRAM_CHAT_ID}"

endpoints:
  - name: Main website
    group: Public sites
    url: "https://example.com/"
    interval: 1m
    timeout: 10s
    conditions:
      - "[STATUS] == 200"
      - "[RESPONSE_TIME] < 3000"
    alerts:
      - type: telegram
        failure-threshold: 3
        success-threshold: 2
        send-on-resolved: true
        description: "The main website is unavailable or too slow."

  - name: API healthcheck
    group: Public sites
    url: "https://api.example.com/health"
    interval: 1m
    timeout: 10s
    headers:
      Accept: "application/json"
    conditions:
      - "[STATUS] == 200"
      - "[BODY].status == UP"
      - "[RESPONSE_TIME] < 2000"
    alerts:
      - type: telegram
        failure-threshold: 2
        success-threshold: 2
        send-on-resolved: true
        description: "API healthcheck did not return status UP."

  - name: SSH server
    group: Infrastructure
    url: "tcp://203.0.113.10:22"
    interval: 2m
    timeout: 5s
    conditions:
      - "[CONNECTED] == true"
    alerts:
      - type: telegram
        failure-threshold: 3
        success-threshold: 1
        send-on-resolved: true
        description: "SSH port is unreachable."

  - name: External HTTPS certificate
    group: SSL certificates
    url: "https://example.com/"
    interval: 12h
    conditions:
      - "[STATUS] == 200"
      - "[CERTIFICATE_EXPIRATION] > 336h"
    alerts:
      - type: telegram
        failure-threshold: 1
        success-threshold: 1
        send-on-resolved: true
        description: "SSL certificate expires in less than 14 days."

Replace example.com, api.example.com, and the SSH IP address with actual values. The [CERTIFICATE_EXPIRATION] > 336h condition means that more than 14 days must remain before the certificate expires. For critical certificates, you can set 720 hours, or 30 days.

Do not include tokens, passwords, or private query parameters in URLs. If the API requires authorization, use a separate technical token with minimal permissions and pass it through environment variables or a protected template. For sensitive internal endpoints, it is better to restrict access to the Gatus dashboard through Caddy Basic Auth, a VPN, or a firewall.

Create the Caddy Configuration

cd /opt/gatus
nano caddy/Caddyfile
{
    email {$ACME_EMAIL}
}

{$GATUS_DOMAIN} {
    encode zstd gzip

    reverse_proxy gatus:8080

    header {
        -Server
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}

Caddy will request a certificate automatically. For this, the domain's A record must point to the VPS, and ports 80 and 443 must be accessible externally. If the domain uses CDN proxying, ensure that the TLS mode does not interfere with ACME validation.

Create the Docker Compose File

cd /opt/gatus
nano compose.yaml
services:
  gatus:
    image: twinproduction/gatus:latest
    container_name: gatus
    restart: unless-stopped
    env_file:
      - .env
    entrypoint:
      - /bin/sh
      - -ec
      - |
        envsubst < /config/config.yaml.template > /tmp/config.yaml
        exec /gatus --config-file=/tmp/config.yaml
    volumes:
      - ./config:/config:ro
      - ./data:/data
    networks:
      - monitoring
    healthcheck:
      test: ["CMD", "/gatus", "--config-file=/tmp/config.yaml", "--version"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s

  caddy:
    image: caddy:2-alpine
    container_name: caddy-gatus
    restart: unless-stopped
    env_file:
      - .env
    depends_on:
      gatus:
        condition: service_started
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - monitoring

networks:
  monitoring:
    name: monitoring

volumes:
  caddy_data:
  caddy_config:

Using the latest tag is convenient for the initial launch, but for predictable production updates it is better to pin a tested Gatus version, such as twinproduction/gatus:v5.x.y, after checking the current release. Similarly, you can pin a minor Caddy version. After updating a version, always check configuration format changes in the release notes.

Validate YAML and Start the Containers

cd /opt/gatus
docker compose config
docker compose pull
docker compose up -d
docker compose ps

The first command combines the Compose file and variables while validating syntax. Docker then downloads the images, starts the stack in the background, and displays container status. Both containers must have the Up status.

docker compose logs --tail=100 gatus
docker compose logs --tail=100 caddy

The Gatus logs must not contain YAML errors, and the Caddy logs will show a successful certificate issuance message. If the certificate is not issued, first check DNS, UFW ports, and whether another web server is using port 80 or 443.

Verify the Dashboard and Endpoint

curl -I http://127.0.0.1
curl -I https://status.example.com
curl -s https://status.example.com | head

The first request may return an error because Caddy expects the correct Host header. The main check is the second request: expect status 200 or a redirect from HTTP to HTTPS. Open the domain in a browser and ensure that the interface displays groups, endpoints, check history, and current status.

Test the Telegram Notification

The safest test is to temporarily specify a deliberately unavailable URL in a separate endpoint. After two or three intervals, Gatus should send a Telegram message. Then restore the correct address: after the configured success-threshold, a recovery notification will arrive.

docker compose restart gatus
docker compose logs -f gatus

The first command applies configuration template changes, while the second displays logs in real time. After completing the test, remove the temporary endpoint to avoid receiving false alerts.

Important: Gatus checks services from your VPS IP address. If the monitored resource blocks requests from data centers, uses geographic restrictions, or Cloudflare WAF, add the monitoring IP to the allowlist or configure a separate permitted /health endpoint.

Backups and Maintenance

Gatus can be redeployed quickly, but without a backup you will lose check settings, incident history, the SQLite database, and Caddy certificate data. The minimum strategy is to back up the /opt/gatus directory to external storage daily and periodically test restoration on a test server.

What to back up

  • /opt/gatus/config/ — endpoint templates and monitoring logic.
  • /opt/gatus/.env — Telegram token, chat ID, domain, and ACME email.
  • /opt/gatus/data/gatus.db — SQLite history of checks and events.
  • Docker volume caddy_data — certificates, keys, and Caddy state.
  • The /opt/gatus/compose.yaml file and Caddyfile.

Do not keep the only backup copy on the same VPS. Suitable options include S3-compatible storage, a separate server via SFTP, or a second VPS over SSH. If the backup contains .env and a certificate private key, the repository must be encrypted.

Install restic

sudo apt install -y restic
sudo mkdir -p /root/.config/restic
sudo chmod 700 /root/.config/restic

Restic creates encrypted, deduplicated backups. The example below uses S3-compatible storage. Access credentials must be provided by your object storage service.

sudo nano /root/.config/restic/gatus.env
export RESTIC_REPOSITORY="s3:https://s3.example.net/gatus-backups"
export RESTIC_PASSWORD="REPLACE_WITH_LONG_RANDOM_PASSWORD"
export AWS_ACCESS_KEY_ID="REPLACE_WITH_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="REPLACE_WITH_SECRET_KEY"
sudo chmod 600 /root/.config/restic/gatus.env
sudo bash -c 'source /root/.config/restic/gatus.env && restic init'

The commands protect the variables file and initialize an empty encrypted repository. Store the RESTIC_PASSWORD separately: restoration is impossible without it.

Create a backup script

sudo nano /usr/local/sbin/backup-gatus.sh
#!/usr/bin/env bash
set -euo pipefail

source /root/.config/restic/gatus.env

cd /opt/gatus
docker compose stop gatus
trap 'docker compose start gatus' EXIT

restic backup \
  /opt/gatus/config \
  /opt/gatus/caddy \
  /opt/gatus/compose.yaml \
  /opt/gatus/.env \
  /opt/gatus/data \
  --tag gatus

docker run --rm \
  -v caddy_data:/source:ro \
  -v /opt/gatus/backups:/backup \
  alpine sh -c 'tar czf /backup/caddy_data.tar.gz -C /source .'

restic backup /opt/gatus/backups/caddy_data.tar.gz --tag caddy

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

The script briefly stops Gatus to obtain a consistent SQLite copy, then starts it again even if an error occurs thanks to trap. Caddy continues running, so the web panel may display the last page, but new checks will stop for a few seconds.

sudo chmod 700 /usr/local/sbin/backup-gatus.sh
sudo /usr/local/sbin/backup-gatus.sh
sudo bash -c 'source /root/.config/restic/gatus.env && restic snapshots'

First, run the backup manually and make sure a new snapshot appears in the output. Only then add automated execution.

sudo crontab -e
15 3   * /usr/local/sbin/backup-gatus.sh >> /var/log/backup-gatus.log 2>&1

The job runs a backup every day at 03:15 server time. Test restoration once a month: download a snapshot to a separate temporary directory, verify that gatus.db is present and that the YAML is valid.

Updates and status monitoring

For a small installation, it is best to perform updates during a maintenance window: alerts may briefly not arrive during this time, and version changes are easier to roll back. Before updating, create a backup, read the changelog, and check whether the Gatus configuration format has changed.

cd /opt/gatus
sudo /usr/local/sbin/backup-gatus.sh
docker compose pull
docker compose up -d
docker image prune -f
docker compose ps

Gatus is not designed for rolling updates as a clustered service with automatic failover. If monitoring is critical, deploy a second instance on another VPS with a separate Telegram channel or different message prefixes. This is more reliable than trying to update a single instance without a brief interruption.

Check df -h, docker system df, container status, and the size of /opt/gatus/data/gatus.db weekly. With a high check frequency, the database will grow. Reduce the history retention period using the capabilities of the current Gatus version, or periodically export metrics to Prometheus and remove old data according to the documented procedure for the version you use.

Troubleshooting and FAQ

Why does Gatus not open over HTTPS while Caddy reports a certificate acquisition error?

First, check DNS: the dig +short status.example.com command must return the VPS public IP. Then make sure UFW allows ports 80 and 443, and Docker publishes them through docker compose ps. Check whether the ports are occupied by another Nginx or Apache instance: sudo ss -ltnp | grep -E ':80|:443'. If a CDN is used, temporarily disable proxying or configure the correct TLS mode for the ACME challenge.

Why are Telegram notifications not arriving?

Check that the bot has received at least one message from the user or has been added to a group. Then run the getUpdates request and make sure that TELEGRAM_CHAT_ID matches message.chat.id. Group IDs are often negative. Check the .env file for extra quotes, spaces, and an incorrect token, then restart Gatus with docker compose restart gatus and review the container logs.

Why does the Gatus container keep restarting?

The most common cause is a YAML error or an unsupported configuration field after an image update. Run docker compose logs --tail=200 gatus: the error line usually contains the YAML line number. Check indentation, use spaces instead of tabs, and ensure special characters in URLs are enclosed in quotes. If the problem appeared after an update, temporarily restore the previously working image tag and compare the configuration with that version's documentation.

Why does an endpoint show an error even though the site opens in a browser?

The browser and VPS may use different DNS, IPv4/IPv6 routes, geolocation, and headers. Check the request directly from the container: docker exec -it gatus wget -S -O /dev/null https://example.com. Possible causes include WAF blocking of data centers, a required Host header, a redirect to another domain, authentication requirements, or a timeout that is too short. Configure an allowlist for monitoring IPs, increase the timeout to 15–20 seconds, and check a dedicated /health endpoint.

Why does the SSL alert arrive too late or not arrive at all?

Check the endpoint interval: with a value of 12h, Gatus detects a certificate change only twice per day. For important domains, use an interval of 1–6 hours. Check the [CERTIFICATE_EXPIRATION] condition: 336 hours equals 14 days, and 720 hours equals 30 days. Also make sure the endpoint actually uses HTTPS rather than HTTP. After changing the condition, restart the container and check the endpoint status in the panel.

What is the minimum suitable VPS configuration?

For 10–30 websites and API endpoints checked every 1–5 minutes, 1 vCPU, 1 GB RAM, 10 GB SSD, and a 100 Mbps connection are sufficient. It is more practical to choose 2 GB RAM and 20 GB NVMe: this leaves capacity for Docker, Caddy, updates, and SQLite history. A public IPv4 address, the ability to open ports 80/443, and a stable network are essential. If hundreds of endpoints are planned, start with 2 vCPU, 4 GB RAM, and 30–50 GB NVMe.

What should you choose for this task: VPS or dedicated server?

A VPS is almost always sufficient for Gatus. It is cheaper, faster to deploy, and easy to scale as the number of checks grows. A dedicated server is needed if Gatus is part of a large monitoring system with Prometheus, Grafana, logs, and thousands of frequent checks, or if the security policy requires physically dedicated hardware. To improve reliability, it is better to spend the budget not on a dedicated server but on a second small VPS in a different network and location.

Can the Gatus panel be closed to public access?

Yes. The simplest option is to leave access public only through a VPN, such as WireGuard, and close ports 80/443 in UFW for everyone except the VPN subnet. If the panel must be accessible to several employees, add Basic Auth to the Caddyfile with a hashed password. Do not block ACME checks if Caddy continues issuing a public certificate. Alternatively, use a DNS challenge or a separate internal domain with corporate TLS.

Conclusions and Next Steps

Gatus is now running on a separate VPS with an HTTPS panel, website and API checks, SSL certificate monitoring, and Telegram notifications. Configuration is separated from secrets, data is stored in SQLite, and backups are sent to external encrypted storage.

  1. Add endpoints for all public websites, APIs, DNS dependencies, SSH, and critical TCP services.
  2. Create separate groups for production, staging, and external providers to make Telegram alerts easier to classify.
  3. For critical systems, deploy a second Gatus instance in another location and compare incidents from independent networks.

Чи був цей гайд корисним?

Ваш відгук допомагає нам покращувати гайди.

Share this post:

Надішліть гайд тому, кому він може стати в пригоді.

Telegram VKVK WhatsApp Facebook LinkedIn XX

Gatus installation on VPS: website monitoring, SSL alerts, and Telegram notifications
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.