Uptime Kuma na własnym VPS - instalacja i konfiguracja

Arkadiusz Kulewicz Opublikowano: 18.07.2026 r.

Współczesne aplikacje i serwisy internetowe wymagają ciągłej uwagi. Nawet najkrótsza przerwa w ich działaniu może oznaczać utratę czytelników, klientów lub po prostu nadszarpnięte zaufanie. Chociaż na rynku istnieje wiele gotowych platform do monitorowania statusu usług, to jednak większość z nich to prawdziwe kobyły. Do wielu zastosowań będą one nadmiarowe i warto pomyśleć o prostszym rozwiązaniu.

Przyjrzymy się bliżej jednemu z najlepszych darmowych narzędzi z tego segmentu – Uptime Kuma. To lekka i funkcjonalna aplikacja, która monitoruje status usług i w razie potrzeby wyśle powiadomienie o awarii. Krok po kroku przejdziemy przez proces jej instalacji za pomocą Dockera, a także zmierzymy się z nieco bardziej zaawansowanym scenariuszem: uruchomieniem monitoringu na budżetowym serwerze VPS (Mikrus) z wykorzystaniem IPv6, Cloudflare jako reverse proxy oraz Nginx. Pokażę Ci również, jak poprawnie skonfigurować serwer, aby zachować autentyczne adresy IP użytkowników w logach.

Instalacja

Proces instalacji jest szczegółowo opisany na oficjalnej stronie projektu. Ja zdecydowałem się na wdrożenie z wykorzystaniem Docker Compose, co znacząco ułatwia późniejsze aktualizacje i zarządzanie kontenerem.

Instalację przeprowadziłem na serwerze VPS z systemem operacyjnym Ubuntu, wykorzystując Docker Engine. Jeśli nie masz jeszcze zainstalowanego środowiska Docker na swoim serwerze, możesz to zrobić, postępując zgodnie z dokumentacją Dockera.

Jeśli środowisko Docker jest już gotowe, czas utworzyć dedykowany katalog dla plików konfiguracyjnych i danych Uptime Kuma oraz do niego przejść:

mkdir -p uptime-kuma && cd uptime-kuma

W kolejnym kroku należy utworzyć plik docker-compose.yml:

nano docker-compose.yml

Skorzystałem z gotowego kodu z oficjalnej dokumentacji, który po drobnych modyfikacjach wygląda następująco:

services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    container_name: uptime-kuma
    restart: always
    ports:
      - "127.0.0.1:3001:3001"  
    volumes:
      - ./uptime-kuma-data:/app/data  
    environment:
      - TZ=Europe/Warsaw 
      - UMASK=0022 
    networks:
      - kuma_network  
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001"]
      interval: 30s
      retries: 3
      start_period: 10s
      timeout: 5s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

networks:
  kuma_network:
    driver: bridge

Po zapisaniu pliku (w edytorze nano: Ctrl + O, Enter, a następnie Ctrl + X) należy uruchomić kontener z aplikacją w tle:

docker compose up -d

Po chwili aplikacja powinna zainicjalizować swoje działanie i być dostępna pod adresem:

http://<adres-ip-twojego-serwera>:3001

Dodatkowe zabezpieczenie: Uptime Kuma jest mapowana na 127.0.0.1, dzięki czemu panel nie jest dostępny bezpośrednio z Internetu. Dla dodatkowej ochrony można również zablokować port 3001 w zaporze UFW:

sudo ufw deny in proto tcp to any port 3001

Uruchomienie Uptime Kuma na VPS Mikrus

W moim przypadku nie poszło tak łatwo, ponieważ jako docelowe środowisko dla Uptime Kuma wybrałem serwer Mikrus. Mikrusy wykorzystują adresację IPv6, a nie wszyscy dostawcy internetu w Polsce oferują pełną obsługę protokołu IPv6 dla użytkowników końcowych.

Istnieje kilka sposobów na rozwiązanie tego problemu i wystawienie usługi na świat. Jednym z prostszych jest podpięcie własnej domeny do serwera przy pomocy darmowej usługi Cloudflare, która zadziała jako proxy tłumaczące ruch IPv4 na IPv6. Dokładną instrukcję, jak to zrobić, znajdziesz bezpośrednio w dokumentacji Mikrusa.

Po skierowaniu domeny na serwer, w kolejnym kroku zainstalowałem serwer WWW Nginx, który posłuży jako reverse proxy:

sudo apt update && sudo apt install nginx-extras -y

Następnie utworzyłem dedykowany plik konfiguracyjny dla mojej subdomeny:

cd /etc/nginx/sites-available
sudo nano monitoring

Treść pliku konfiguracyjnego prezentuje się następująco:

server {
    listen 80;
    listen [::]:80;
    server_name monitoring.kulewicz.net;

    location / {
        proxy_pass         http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection "upgrade";
        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;

        proxy_set_header   Sec-WebSocket-Key $http_sec_websocket_key;
        proxy_set_header   Sec-WebSocket-Version $http_sec_websocket_version;
        proxy_set_header   Sec-WebSocket-Extensions $http_sec_websocket_extensions;

        proxy_buffering    off;
    }

}

Po zapisaniu pliku musiałem aktywować nową konfigurację. Aby to zrobić, należy utworzyć dowiązanie symboliczne (link symboliczny) do katalogu sites-enabled:

sudo ln -s /etc/nginx/sites-available/monitoring /etc/nginx/sites-enabled/

Teraz mogłem przetestować poprawność składni konfiguracji i przeładować proces Nginxa:

sudo nginx -t
sudo nginx -s reload

Po wpisaniu w przeglądarce adresu https://monitoring.kulewicz.net poprawnie wyświetlił się panel Uptime Kuma.

Dodajemy logowanie prawdziwych adresów IP

Ale to jeszcze nie koniec pracy! Ponieważ Cloudflare domyślnie proxyuje cały ruch, spodziewałem się, że analizując standardowe logi Nginxa, nie będę w stanie zweryfikować, z jakich realnych adresów IP generowane są odwiedziny. Szybka analiza pliku /var/log/nginx/access.log potwierdziła moje obawy – w logach widniały wyłącznie adresy IP należące do serwerów Cloudflare. A tak przecież być nie może. 🙂

2400:cb00:696:1000:5242:46dc:3e62:6071 - - [18/Jul/2026:08:21:04 +0000] "GET /setup-database-info HTTP/1.1" 304 0 "https://monitoring.kulewicz.net/setup-database" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15"

Całą operację „odzyskiwania prawdziwych IP” podzieliłem na trzy proste kroki.

1. Zmiana trybu szyfrowania w Cloudflare (Flexible -> Full (Strict))

Wspomniana wyżej dokumentacja Mikrusa wskazywała, aby w panelu Cloudflare wybrać tryb szyfrowania Flexible. Oznacza to, że ruch między przeglądarką użytkownika a Cloudflare jest w pełni szyfrowany (HTTPS), ale odcinek między Cloudflare a naszym Mikrusem leci już tradycyjnym, nieszyfrowanym protokołem HTTP na port 80.

Aby to zmienić, przeszedłem do zakładki SSL/TLS w panelu administracyjnym Cloudflare i przełączyłem tryb na Full (Strict). Od tego momentu Cloudflare bezwzględnie wymaga, aby nasz serwer nie tylko szyfrował ruch na bezpiecznym porcie 443, ale także legitymował się w pełni zaufanym, ważnym certyfikatem SSL.

2. Generowanie certyfikatu SSL za pomocą Certbota

Bezpośrednią konsekwencją wymuszenia trybu Strict była konieczność wdrożenia certyfikatu SSL na naszym serwerze Nginx. W tym celu skorzystałem z darmowego narzędzia Certbot dostarczanego przez Let’s Encrypt.

Instalacja oraz samo generowanie certyfikatu są banalnie proste i ograniczają się do dwóch poleceń:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d monitoring.kulewicz.net

Certbot automatycznie przejdzie proces weryfikacji własności domeny, wygeneruje niezbędne klucze kryptograficzne i – co najlepsze – sam odpowiednio zmodyfikuje pliki konfiguracyjne Nginxa w katalogu sites-available, otwierając bezpieczny port 443 oraz konfigurując przekierowania.

3. Konfiguracja modułu Real IP w Nginx

To jednak wciąż nie wszystko. Mimo wdrożenia SSL, Nginx w logach access.log nadal uparcie zapisywał adresy IP serwerów Cloudflare. Dlaczego? Ponieważ domyślnie interpretuje on bezpośrednie połączenie jako źródło ruchu. Aby rozwiązać ten problem, należało poinstruować Nginxa, by zaczął odczytywać specjalny nagłówek CF-Connecting-IP, który Cloudflare dokleja do każdego zapytania przesyłanego do serwera docelowego.

W tym celu poprosiłem Gemini o pomoc w przygotowaniu skryptu powłoki, który automatycznie pobierze aktualną listę zakresów IP Cloudflare i wygeneruje z nich globalną konfigurację dla serwera Nginx. Dlaczego nie wpisałem tych adresów na sztywno? Pula IP Cloudflare może się z czasem zmieniać, a taki skrypt mogę w prosty sposób podpiąć pod harmonogram zadań cron, zapewniając w pełni automatyczne aktualizacje.

sudo sh -c '
echo "# Cloudflare IPv4" > /etc/nginx/conf.d/cloudflare.conf
curl -s https://www.cloudflare.com/ips-v4 | sed "s/^/set_real_ip_from /;s/$/;/" >> /etc/nginx/conf.d/cloudflare.conf
echo "
# Cloudflare IPv6" >> /etc/nginx/conf.d/cloudflare.conf
curl -s https://www.cloudflare.com/ips-v6 | sed "s/^/set_real_ip_from /;s/$/;/" >> /etc/nginx/conf.d/cloudflare.conf
echo "
real_ip_header CF-Connecting-IP;" >> /etc/nginx/conf.d/cloudflare.conf
'

Na koniec wykonujemy szybki test nowej konfiguracji oraz przeładowanie Nginxa:

sudo nginx -t
sudo systemctl reload nginx

Nadeszła chwila prawdy – sprawdzam logi Nginxa za pomocą polecenia sudo tail -f /var/log/nginx/access.log i… pełen sukces! W logach zamiast serwerów proxy zaczęły pojawiać się rzeczywiste, publiczne adresy IP osób odwiedzających stronę.

Podstawowa konfiguracja Uptime Kuma

Konfigurację Cloudflare i Nginxa mamy za sobą – możemy przejść do uruchomienia monitoringu. Po wejściu na stronę pojawi się okno, w którym należy dokonać wyboru języka oraz bazy danych. Ja wybrałem Embedded MariaDB.

Okno wyboru bazy danych

Po wybraniu bazy danych należy podać nazwę użytkownika i hasło.

Konfiguracja użytkownika i hasła

Po wykonaniu powyższych czynności możemy zalogować się i wyświetli nam się dashboard.

Dashboard Uptime Kuma

Na koniec sprawdźmy jeszcze, czy monitoring działa. W tym celu klikamy “Dodaj monitor” i podajemy wymagane informacje. Na początkowe testy wystarczy:

  • Rodzaj monitora: HTTP(s)
  • Przyjazna nazwa: kulewicz.net
  • URL: https://kulewicz.net
  • Częstotliwość bicia serca: 60
  • Prób: 2
  • Zaznaczamy “Powiadomienie o wygaśnięciu certyfikatu”.

Po zapisaniu zmian w naszym dashboardzie pojawią się informacje o statusie strony oraz dacie ważności certyfikatu i domeny.

Dashboard Uptime Kuma z informacją o statusie strone

Podsumowanie

Wdrożenie własnego systemu monitoringu w oparciu o Uptime Kuma to doskonała alternatywa dla rozbudowanych i kosztownych platform komercyjnych. Dzięki wykorzystaniu Dockera proces instalacji samej aplikacji jest szybki i raczej mało skomplikowany.

W przypadku Mikrusa było trochę zabawy, ale im trudniej i więcej problemów, tym więcej człowiek się nauczy :)

A już w następnej części skupimy się możliwościach Uptime Kuma i skonfigurujemy automatyczne powiadomienia o awariach.