Na Ubuntu 24.04
chci rozběhnout open-source aplikaci Healthchecks.
Cituju z dokumentace:
Healthchecks.io is a service for monitoring cron jobs and similar periodic processes:
- Healthchecks.io listens for HTTP requests ("pings") from your cron jobs and scheduled tasks.
- It keeps silent as long as pings arrive on time.
- It raises an alert as soon as a ping does not arrive on time.
Healthchecks.io works as a dead man's switch for processes that need to run continuously or on a regular, known schedule. Some examples of jobs that would benefit from Healthchecks.io monitoring:
- filesystem backups, database backups
- task queues
- database replication monitoring scripts
Healthchecks.io is not the right tool for:
- monitoring website uptime by probing it with HTTP requests
- collecting application performance metrics
Vycházím z:
git clone https://github.com/healthchecks/healthchecks.git healthchecks && cd healthchecks
git checkout v3.9 # viz https://github.com/healthchecks/healthchecks/releases
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
uv pip install gunicorn
# uv pip list
cat << EOF > .env
# https://healthchecks.io/docs/self_hosted_configuration/
[email protected]
ALLOWED_HOSTS=health.example.com,localhost
DEBUG=False
[email protected]
EMAIL_HOST='live.smtp.mailtrap.io'
EMAIL_HOST_USER='api'
EMAIL_HOST_PASSWORD='insert the email password here'
EMAIL_PORT=587
# Note that EMAIL_USE_TLS (587) / EMAIL_USE_SSL (465) are mutually exclusive, so only set one of those settings to True.
EMAIL_USE_TLS=True
EMAIL_USE_SSL=False
EMAIL_USE_VERIFICATION=False
REGISTRATION_OPEN=False
SECRET_KEY='$(tr -dc 'a-zA-Z0-9!@#$%^&*()-_=+' < /dev/urandom | head -c 64)'
[email protected]
SHELL_ENABLED=False
SITE_NAME='Mychecks'
SITE_ROOT='https://health.example.com'
EOF
chmod 0600 .env
./manage.py migrate
./manage.py createsuperuser
# ./manage.py test
# ./manage.py runserver
Stalo se mi, že ./manage.py …
hlásí settings.EMAIL_HOST is not set, cannot send email
, přestože je proměnná EMAIL_HOST
v .env
nastavená.
Znamená to, že si ./manage.py
nevyzvedává nastavení z .env
. To je pitomé, ale řešitelné pomocí set -a; source .env; set +a;
.
Pro danou terminálovou relaci (~session) pak ./manage.py …
funguje podle očekávání.
Tyhle kroky provádím jako root.
Vytvoření a spuštění systemd služby.
cd /etc/systemd/system/
cat << EOF > healthchecks.service
[Unit]
Description=Healthchecks App
After=network.target
[Service]
Type=simple
User=web
Group=web
WorkingDirectory=/home/web/p/healthchecks/
# Bez následujícího řádku se proměnné prostředí nastavené v .env nepoužijí!
EnvironmentFile=/home/web/p/healthchecks/.env
ExecStart=/home/web/p/healthchecks/.venv/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 --timeout 120 hc.wsgi:application
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable healthchecks.service
systemctl start healthchecks.service
# systemctl status healthchecks.service
# journalctl -u healthchecks.service -f
# systemctl restart healthchecks.service
Pro odesílání upozornění z aplikace je potřeba ještě systemd služba healthchecks-sendalerts.service
:
[Unit]
Description=Healthchecks Sendalerts
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=web
Group=web
WorkingDirectory=/home/web/p/healthchecks/
EnvironmentFile=/home/web/p/healthchecks/.env
ExecStart=/home/web/p/healthchecks/.venv/bin/python -u /home/web/p/healthchecks/manage.py sendalerts
Restart=always
# během 120 sekund může dojít k maximálně 5 pokusům o restart
RestartSec=20
StartLimitInterval=120
StartLimitBurst=5
[Install]
WantedBy=multi-user.target
Následně tedy:
systemctl daemon-reload
systemctl enable healthchecks-sendalerts.service
systemctl start healthchecks-sendalerts.service
Volitelně je možné vytvořit ještě dvě další systemd služby pro:
./manage.py sendreports # sends out monthly reports, weekly reports, and the daily or hourly reminders
./manage.py smtpd --port 2525 # https://github.com/healthchecks/healthchecks/#receiving-emails
Instalace a konfigurace nginx, vystavení TLS certifikátu.
apt install nginx
systemctl status nginx
ufw allow 'Nginx HTTP'
ufw allow 'Nginx HTTPS'
ufw status
cd /etc/nginx/sites-available/
cat << 'EOF' > health.example.com
# Redirect HTTP to HTTPS
server {
listen 80;
server_name health.example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS server
server {
listen 443;
server_name health.example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
EOF
ln -s /etc/nginx/sites-available/health.example.com /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
# apt install certbot python3-certbot-nginx
certbot --nginx -d health.example.com
# certbot renew --dry-run
# systemctl status certbot.timer
Každá aktualizace pak probíhá takhle:
# Stáhne informace o "tags" a pak přepne na nejnovější tag.
# git fetch --all --tags
# git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
# git status
set -a; source .env; set +a;
./manage.py compress --force
./manage.py collectstatic
./manage.py migrate
# Následně "systemctl restart healthchecks.service healthchecks-sendalerts.service" jako root.
Kdybych chtěl místo výchozí SQLite
použít databázi Postgres
, hodí se tyto návody pro její zprovoznění:
Vlastně je to docela jednoduché:
apt install -y postgresql-common
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
apt-cache depends postgresql
apt install postgresql
sudo -u postgres psql
CREATE USER healthchecks WITH PASSWORD 'tajne_heslo';
CREATE DATABASE healthchecks OWNER healthchecks;
GRANT ALL PRIVILEGES ON DATABASE healthchecks TO healthchecks;
\q
Databázi chci přístupnou jen z localhostu, ne zvenku. Že to tak je, můžu zkontrolovat takhle:
netstat -tulpn | grep postgres
psql "postgresql://healthchecks:tajne_heslo@localhost:5432/healthchecks" -c "show listen_addresses;"
Vzhledem k tomu, že databáze není přístupná zvenku, není - myslím - potřeba:
ALTER USER postgres with encrypted password 'strong_password';
Pak je ještě nutné do .env
přidat:
DB="postgres"
DB_HOST="localhost"
DB_PORT="5432"
DB_NAME="healthchecks"
DB_USER="healthchecks"
DB_PASSWORD="tajne_heslo"
Po provedení výše uvedeného mi prohlížeč hlásil ERR_TOO_MANY_REDIRECTS.
S debugováním mi pomohlo:
curl -I http://127.0.0.1:8000
curl -IL http://127.0.0.1:8000
Příčina byla v nastavení SSL/TLS encryption
na Cloudflare. Bylo potřeba přepnout encryption mode
z Flexible
na Full (strict)
.
Víc tu:
Redirect loops will occur if your origin server automatically redirects all HTTP requests to HTTPS.
A tu:
The reason for “too many redirects” is if you have an http->https redirect on your origin server. The client connects over https, but Cloudflare connects to your origin on http, which returns a redirect to https, which connects over http to be redirected to https and so on forever until the browser gives up.
Není to specifické pro Healthchecks, došlo by k tomu u libovolné služby s výše uvedenou nginx konfigurací a nastavením Cloudflare.
Uptime Kuma.
Nabízí více typů monitorů:
Monitoring uptime for HTTP(s) / TCP / HTTP(s) Keyword / HTTP(s) Json Query / Ping / DNS Record / Push / Steam Game Server / Docker Containers.
Z výše uvedených monitorů nabízí Healthchecks
vlastně jen Push
.
Na druhou stranu má Uptime Kuma
výrazně horší dokumentaci. Aplikace je napsaná v JavaScriptu, takže pro provoz bez Dockeru je nutné mít na serveru Node.js
a npm
. Já dávám přednost kombinaci Python
a uv
, i proto raději použiju Healthchecks
.
Uptime Kuma také neumí - stejně jako Healthchecks - hledat řetězec na „SPA webu“:
The website is most likely an SPA, meaning content is loaded by JavaScript after initial page load. Currently you cannot check the content of such a website.
Aplikace běží, můžeme se přihlásit s údaji vytvořenými pomocí ./manage.py createsuperuser
na https://health.example.com.
Může se hodit: