<?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>News on Blog G.C.</title>
    <link>https://blog.cichy1173.eu/news/</link>
    <description>Recent content in News on Blog G.C.</description>
    <generator>Hugo -- 0.152.2</generator>
    <language>pl-PL</language>
    <lastBuildDate>Sat, 04 Apr 2026 00:22:08 +0200</lastBuildDate>
    <atom:link href="https://blog.cichy1173.eu/news/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Zabbix dla homelabów &#34;Arvalis&#34; po pół roku - czy było warto?</title>
      <link>https://blog.cichy1173.eu/news/arvalis-zabbix-cd/</link>
      <pubDate>Sat, 04 Apr 2026 00:22:08 +0200</pubDate>
      <guid>https://blog.cichy1173.eu/news/arvalis-zabbix-cd/</guid>
      <description>&lt;p&gt;Od &lt;a href=&#34;https://blog.cichy1173.eu/news/arvalis-zabbix&#34;&gt;ostatniego wpisu&lt;/a&gt; na temat projektu &amp;ldquo;Arvalis&amp;rdquo; trochę minęło, w zasadzie około pół roku i od tamtej pory sporo się zmieniło. Jako że jest to projekt czysto związany z selfhostingiem i cięciem kosztów tak bardzo jak to możliwe, to uznałem, że powinienem Wam co nieco opowiedzieć.&lt;/p&gt;
&lt;h2 id=&#34;czym-jest-projekt-arvalis&#34;&gt;Czym jest projekt &amp;ldquo;Arvalis&amp;rdquo;?&lt;/h2&gt;
&lt;p&gt;Pod nazwą &amp;ldquo;Arvalis&amp;rdquo; kryje się w rzeczywistości hosting własnej instancji oprogramowania Zabbix w celu monitorowania domowych homelabów. Mówię o liczbie mnogiej, ponieważ w projekt zaangażowanych jest kilka osób, a instancja Zabbix jest współdzielona. Projekt też wykorzystuje wiele praktyk i czynności kojarzonych raczej z infrastrukturami produkcyjnymi, a nie domowymi, jednakże zostały one wybrane, aby ułatwić deployment i utrzymanie. O projekcie więcej dowiecie się &lt;a href=&#34;https://blog.cichy1173.eu/news/arvalis-zabbix&#34;&gt;z tego wpisu&lt;/a&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Od <a href="/news/arvalis-zabbix">ostatniego wpisu</a> na temat projektu &ldquo;Arvalis&rdquo; trochę minęło, w zasadzie około pół roku i od tamtej pory sporo się zmieniło. Jako że jest to projekt czysto związany z selfhostingiem i cięciem kosztów tak bardzo jak to możliwe, to uznałem, że powinienem Wam co nieco opowiedzieć.</p>
<h2 id="czym-jest-projekt-arvalis">Czym jest projekt &ldquo;Arvalis&rdquo;?</h2>
<p>Pod nazwą &ldquo;Arvalis&rdquo; kryje się w rzeczywistości hosting własnej instancji oprogramowania Zabbix w celu monitorowania domowych homelabów. Mówię o liczbie mnogiej, ponieważ w projekt zaangażowanych jest kilka osób, a instancja Zabbix jest współdzielona. Projekt też wykorzystuje wiele praktyk i czynności kojarzonych raczej z infrastrukturami produkcyjnymi, a nie domowymi, jednakże zostały one wybrane, aby ułatwić deployment i utrzymanie. O projekcie więcej dowiecie się <a href="/news/arvalis-zabbix">z tego wpisu</a>.</p>
<h2 id="co-się-zmieniło">Co się zmieniło?</h2>
<p>Od października zaszło kilka zmian, choć nie staraliśmy się poświęcać zbyt sporo czasu.</p>
<h3 id="jest-nas-więcej">Jest nas więcej!</h3>
<p>Już publikując poprzedni wpis informowałem, że liczba osób uczestniczących w projekcie wzrosła do 5. W tym momencie jest nas aż sześciu, co sprawiło, że koszt miesięczny za styczeń 2026 wyszedł około 6 złotych za osobę. Jak za enterprise-level monitoring jest to naprawdę świetna cena.</p>
<p>Niestety, Hetzner poinformował, że jest zmuszony podnieść ceny i dotyka to również nas. W celu zminimalizowania kosztów postanowiliśmy więc w końcu przejść na nowy typ instancji CX23. Pierwotnie infrastruktura została zbudowana na bazie CX22, czyli najtańszego wariantu instancji EC2 od Hetzner. Jednak nieco później udostępniono nowe typy, gdzie CX22 zastępuje właśnie nieco tańszy CX23, a CX22 szybciutko został oznaczony jako <code>deprecated</code>. I tak, faktycznie nowy CX23 jest tańszy od CX22, jednakże, tak jak wspomniałem, Hetzner ogólnie podniósł ceny swoich usług i nawet ten nowy typ instancji stał się droższy. Nadal jednak są to koszty rozsądne, tym bardziej, że dzielone na parę osób.</p>
<h3 id="problem-zmiennego-ip">Problem zmiennego IP</h3>
<p>Największym problemem był onboardowanie osób ze zmiennym adresem IP. Jako że podstawą kontroli dostępów jest mechanizm whitelistowania adresów IP, to publiczny, wyjściowy adres danego użytkownika musi być znany (dotyczy to również podwójnego NAT-u, w naszej konfiguracji korzystamy z Zabbix Proxy w trybie Active, a więc otwieranie się na ruch wchodzący po stronie userów jest zbędne). Niestety, u niektórych z nas był to spory problem, bo czasami adres mógł się zmieniać nawet co kilka dni.</p>
<p><img alt="Schemat działania Zabbix Proxy" loading="lazy" src="/img/zabbix/zabbix-proxy-active-passive.jpg#center" title="Schemat działania Zabbix Proxy"></p>
<p>Udało się to jednak rozwiązać wykorzystując fakt, że już infrastruktura była opisana w kodzie. Dodaliśmy więc selfhostowany worker Forgejo i utworzyliśmy workflow, gdzie odpowiedni event informuje o zmianie adresu IP i uruchamia automatyzację, która aplikuje nową definicję infrastruktury. Aby to działało sprawniej musieliśmy też przerobić moduły związane z firewallem&hellip; i to dwa razy. Najlepszym rozwiązaniem było utworzenie oddzielnej security grupy (oj, firewalli&hellip;) dla każdego usera, ale okazało się, że Hetzner narzuca niezmienny limit, gdzie jedna instancja może mieć maksymalnie 5 security grup. Przearanżowaliśmy więc SG ponownie i uzyskaliśmy potrzebny efekt.</p>
<h3 id="rozwój-iac">Rozwój IaC</h3>
<p>Poszliśmy dalej z architekturą rozwiązania. Przerobiliśmy jak zarządzamy użytkownikami po stronie serwerów, a definicję kontenerów wrzuciliśmy do oddzielnego stacka. Udało się też opisać infrastrukturę Cloudflare w kodzie, co jest kolejnym, ważnym krokiem. Gdzieś po drodze zmodyfikowaliśmy konfigurację Zabbixa, aby wyciągnąć wyższą wydajność, a także staramy się regularnie robić aktualizacje minor. Poza wyżej opisanym workflow dla zmiennego IP, dodaliśmy też inne automatyzacje, stricte związane z OpenTofu.</p>
<h2 id="podsumowanie">Podsumowanie</h2>
<p>Arvalis, mimo wszystko, to projekt hobbystyczny, a więc rozwój jest powolny, bo bazuje tylko i wyłącznie na wolnym czasie użytkowników. A jednak udało się wprowadzić trochę zmian i ciągle trwają prace nad usprawnieniami. Mamy backlog wypełniony kolejnymi działaniami, większymi i mniejszymi. No i oczywiście czekamy na Zabbix 8.0, który wniesie sporo nowości.</p>
<p>Zabbix jako narzędzie do monitoringu homelaba podoba mi się coraz bardziej i bardzo lubię z niego korzystać, a jego konstrukcja oparta o Server i Proxy niesamowicie dobrze sprawdza się w tym użyciu. Niewielkim kosztem mamy dostęp do monitoringu klasy enterprise, a jeśli tylko sobie ktoś z nas wymarzy jakiś monitoring czy sposób działania, to zapewne będzie mógł to zrobić. <strong>Fajnie by było, jakby Zabbix dostał choć trochę lepszy interfejs GUI i najlepiej oficjalnego providera Terraform&hellip;</strong></p>
]]></content:encoded>
    </item>
    <item>
      <title>Zabbix monitoruje mi ważność apteczek</title>
      <link>https://blog.cichy1173.eu/news/arvalis-apteczka/</link>
      <pubDate>Sun, 30 Nov 2025 12:29:21 +0100</pubDate>
      <guid>https://blog.cichy1173.eu/news/arvalis-apteczka/</guid>
      <description>&lt;p&gt;Nie tak dawno temu opisałem mój proces dochodzenia do oprogramowania Zabbix, który to zdeployowałem w chmurze Hetzner. Ma to być narzędzie, które posłuży wiele lat. Dlatego też wiedziałem, że można tam zacząć monitorować rzeczy w szerszej perspektywie czasowej. I tak jakoś szybkim krokiem możemy przejść do&amp;hellip; apteczek samochodowych. Pewnie wielu z Was takowe posiada, ale czy regularnie sprawdza ważność ich wyposażenia? Okazuje się, że nawet w nowej apteczce niektóre elementy potrafią przeterminować się za 1,5 czy 2 lata. Zakup nowych apteczek skłonił mnie więc do poszukiwania rozwiązania, aby w jakiś sposób monitorować i zostać poinformowanym o tym, że któryś z elementów będzie &lt;em&gt;expired&lt;/em&gt;.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nie tak dawno temu opisałem mój proces dochodzenia do oprogramowania Zabbix, który to zdeployowałem w chmurze Hetzner. Ma to być narzędzie, które posłuży wiele lat. Dlatego też wiedziałem, że można tam zacząć monitorować rzeczy w szerszej perspektywie czasowej. I tak jakoś szybkim krokiem możemy przejść do&hellip; apteczek samochodowych. Pewnie wielu z Was takowe posiada, ale czy regularnie sprawdza ważność ich wyposażenia? Okazuje się, że nawet w nowej apteczce niektóre elementy potrafią przeterminować się za 1,5 czy 2 lata. Zakup nowych apteczek skłonił mnie więc do poszukiwania rozwiązania, aby w jakiś sposób monitorować i zostać poinformowanym o tym, że któryś z elementów będzie <em>expired</em>.</p>
<p>Zaraz na samym początku korzystania z Zabbixa w chmurze Hetzner przygotowaliśmy skrypt, którym można było łatwo definiować strony internetowe, które następnie były monitorowane poprzez Web Scenarios. Skrypt szybko dodawał monitoring i zakładał odpowiednie triggery i inne elementy bez potrzeby ręcznego klikania. Troszkę taki wyszedł z tego pseudo Terraform, ale w Pythonie. Skrypt nie jest kompletny, nie jest idealny, ale zrobił to co trzeba, czyli po prostu dodał ten monitoring, który skutecznie zastąpił Uptime Kuma.</p>
<p>Sposób tworzenia tego monitoringu i alarmu bardzo mi się spodobał. Finalnym elementem dla użytkownika było w zasadzie wpisanie adresu strony i <em>ważności</em> monitorowania w JSON-ie, a następnie odpalenie skryptu. Pomyślałem, że coś takiego można byłoby dodać do innych rzeczy, a dobrym testem byłoby przerobienie skryptu na monitoring ważności apteczek samochodowych.</p>
<h2 id="dodawanie-pozycji-do-apteczki">Dodawanie pozycji do apteczki</h2>
<p>Utworzenie nowego skryptu jednak nie było tak proste. Fakt, można utworzyć pozycje i ustawić daty ważności w Zabbix, ale nie ustawimy odmierzania czasu. Tak, Zabbix sam z siebie czasu nie odmierza, a więc nie możemy ustawić, że np. odliczamy do 31 grudnia 2025, a Zabbix sam z siebie będzie odejmował z puli kolejne godziny. Niestety, tutaj potrzebny jest jakiś zewnętrzny bodziec, który ten czas odliczy i prześle wartości do serwera.</p>
<p>Ale od początku. Pierwszy skrypt dodaje nowe rzeczy do apteczki i ustawia dla nich datę ważności. Każda pozycja w apteczce to osobny <em>item</em> w Zabbix. Skrypt automatycznie tworzy też <em>triggery</em> – w moim przypadku są trzy alarmy dla każdego przedmiotu: pierwszy 30 dni przed końcem ważności, drugi na 14 dni, a trzeci na 7 dni przed przeterminowaniem.</p>
<p><img alt="Widok pozycji apteczki w Zabbix" loading="lazy" src="/img/zabbix-apteczki/zabbix-apteczka-pozycje.png#center" title="Lista pozycji z apteczki monitorowana przez Zabbix"></p>
<p><img alt="Triggery dla pozycji apteczki" loading="lazy" src="/img/zabbix-apteczki/zabbix-apteczka-triggery.png#center" title="Automatycznie generowane triggery dla terminów ważności"></p>
<p>Dzięki temu mam czas na spokojne zakupienie nowych produktów i wymianę tych, które wkrótce stracą ważność.</p>
<h2 id="odświeżanie-danych">Odświeżanie danych</h2>
<p>Tutaj pojawia się wcześniej wspomniana kwestia techniczna. Zabbix sam w sobie nie odmierza czasu dla pozycji. Jeśli mam item z datą ważności na &ldquo;2025-12-31&rdquo;, to Zabbix nie będzie sam sprawdzał, ile dni zostało. Potrzebny jest &ldquo;zewnętrzny bodziec&rdquo;, który zaktualizuje wartość i zmusi Zabbix do ponownego sprawdzenia triggerów.</p>
<p>Dlatego powstał drugi skrypt, który uruchamiam jako <em>cronjob</em> co 12 godzin w Forgejo Actions. Skrypt odpytuje Zabbix API, pobiera wszystkie pozycje związane z apteczkami i aktualizuje ich wartości.</p>
<p><img alt="Konfiguracja Forgejo Actions" loading="lazy" src="/img/zabbix-apteczki/zabbix-forgejo-actions.png#center" title="Cronjob uruchamiany co 12h w Forgejo Actions"></p>
<h2 id="praca-w-praktyce">Praca w praktyce</h2>
<p>Kiedy zbliża się termin ważności jakiegoś produktu, dostaję powiadomienie na Telegram, tak samo jak w przypadku alertów z infrastruktury IT. Wszystko scentralizowane w jednym miejscu, więc nie muszę pamiętać, która apteczka była ostatnio sprawdzana ani co w niej się znajduje.</p>
<h2 id="ograniczenia">Ograniczenia</h2>
<p>Największy problem to brak automatycznego usuwania pozycji. Jeśli jakiś przedmiot znika z apteczki, to muszę ręcznie usunąć go z Zabbixa. Przydałoby się, żeby skrypt porównywał aktualny stan inventory w kodzie z tym, co jest w Zabbix i sam usuwał nieaktualne pozycje. Te wszelkie problemy rozwiązałby Terraform, ale niestety, provider do Zabbixa jest przestarzały i już nie działa. Innym sposobem byłoby skorzystanie z Ansible, ale niestety, nie badałem czy <em>jeszcze</em> Ansible działa.</p>
<h2 id="co-dalej">Co dalej</h2>
<p>Myślę, aby ponownie wykorzystać ten zestaw narzędzi do podobnych rzeczy. Monitoring terminu ważności to przecież uniwersalny problem - leki w domowej apteczce, produkty spożywcze w spiżarni, przeglądy techniczne samochodu, ważność dokumentów czy subskrypcje oprogramowania. Wszystko to mogłoby być monitorowane tym samym mechanizmem.</p>
<p>Przydałoby się jednak usuwanie danych pozycji, kiedy te znikną z inventory w kodzie. Wymaga to refaktoringu i lepszego zaprojektowania struktury danych, ale z czasem do tego wrócę.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Zabbix do monitoringu domowych serwerów jest świetny!</title>
      <link>https://blog.cichy1173.eu/news/arvalis-zabbix/</link>
      <pubDate>Sat, 29 Nov 2025 12:00:00 +0200</pubDate>
      <guid>https://blog.cichy1173.eu/news/arvalis-zabbix/</guid>
      <description>&lt;p&gt;Nie robiłem badań, nie mam żadnych wyników ankiet, ale &lt;em&gt;wydajemisię&lt;/em&gt;, że monitoring i obserwowalność nie stoją na zbyt wysokiej pozycji priorytetowych zadań wielu entuzjastów selfhostingu. I nie ma w tym nic dziwnego, bo selfhosting (czy tam &amp;ldquo;homelabbing&amp;rdquo;) to dla wielu głównie zabawa w szukaniu coraz to ciekawszych aplikacji, które mogą zastąpić komercyjne odpowiedniki czy poprawić codzienne życie. Monitoring, sposoby deploymentów, zarządzanie konfiguracją może więc wydawać się tym &amp;ldquo;the boring work&amp;rdquo;. Ale według mnie wcale tak nie musi być i monitoring oraz obserwowalność stały się dla mnie głównymi &amp;ldquo;zabawkami&amp;rdquo; selfhostingu na niekrótki czas.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Nie robiłem badań, nie mam żadnych wyników ankiet, ale <em>wydajemisię</em>, że monitoring i obserwowalność nie stoją na zbyt wysokiej pozycji priorytetowych zadań wielu entuzjastów selfhostingu. I nie ma w tym nic dziwnego, bo selfhosting (czy tam &ldquo;homelabbing&rdquo;) to dla wielu głównie zabawa w szukaniu coraz to ciekawszych aplikacji, które mogą zastąpić komercyjne odpowiedniki czy poprawić codzienne życie. Monitoring, sposoby deploymentów, zarządzanie konfiguracją może więc wydawać się tym &ldquo;the boring work&rdquo;. Ale według mnie wcale tak nie musi być i monitoring oraz obserwowalność stały się dla mnie głównymi &ldquo;zabawkami&rdquo; selfhostingu na niekrótki czas.</p>
<blockquote>
<p>Na początku dodam, że choć niezbyt lubię to słowo, tak w tym wpisie będę stosował słowo &ldquo;homelab&rdquo; w celu nazwania domowego serwera opartego o sprzęt konsumpcyjny.</p>
</blockquote>
<h2 id="początki-monitorowania-mojego-homelaba">Początki monitorowania mojego homelaba</h2>
<p>Kiedy to zacząłem bawić się w selfhosting, to nie przykładałem żadnej uwagi monitorowaniu. Nic dziwnego, początki to właśnie faza na szukanie coraz to ciekawszych aplikacji, wszak otworzył się przede mną kompletnie nowy katalog oprogramowania, którego nigdy wcześniej nie eksplorowałem. Początki monitoringu więc sięgają dopiero instalacji Home Assistanta, na którego skusiłem się po około 6 miesiącach zabawy. W Home Assistant monitorowałem zużycie energii przez serwer, a także dodałem (co jest w Home Assistant bardzo proste) zbieranie takich metryk jak użycie CPU, RAM, zajętość dysków itd. Nie miałem żadnych alertów, więc zdany byłem tylko i wyłącznie na to, że jak zauważyłem, że coś działa <em>nie tak</em>, to wchodziłem i sprawdzałem metryki.</p>
<h3 id="uptime-kuma">Uptime Kuma</h3>
<p>Pierwszym takim oprogramowaniem, które faktycznie pełniło rolę źródła informowania o problemach była aplikacja Uptime Kuma, która jest w zasadzie silnikiem dla healtchecków, tudzież sprawdza czy strona pod danym adresem &ldquo;żyje&rdquo;/odpowiada kodem 200. Jeśli nie, to wysyłany jest alert, w moim przypadku na Telegrama. Po drodze uznałem, że posiadanie tego programu na tym samym serwerze, który monitoruję jest bez sensu, więc przeniosłem go na zewnątrz, na &ldquo;VPS-a&rdquo; od dostawcy Mikrus. Później dodałem kolejną instancję Uptime Kuma, która monitorowała ten serwer VPS i tym samym obydwie <em>Kumy</em> sprawdzały siebie. Z takiego rozwiązania korzystałem do niedawna.</p>
<p>W tak zwanym międzyczasie zacząłem swoją pracę zawodową na pozycji SysOps. Dla osoby zajmującej to stanowisko monitoring i support to główne &ldquo;dania&rdquo; i zajawki. Szybko poznałem kilka rozwiązań do monitorowania, w tym właśnie Zabbix czy Amazon CloudWatch. To mnie też skłoniło do uznania, że monitoring moich usług jest po prostu słaby, nieistniejący, choć - muszę przyznać - Uptime Kuma to dobry początek. Dlatego też po jakimś czasie znalazłem bardzo świeże na tamten moment rozwiązanie o nazwie Beszel.</p>
<h3 id="beszel">Beszel</h3>
<p><a href="https://beszel.dev/">Beszel pozostaje oprogramowaniem</a>, które do dzisiaj jestem w stanie polecić. Jest ono stale ulepszane i dodawane są kolejne ważne funkcje dlatego warto je mieć na uwadze. <strong>A co robi Beszel?</strong> Zapewnia funkcje monitorowania podstawowych pozycji (<em>pozycje</em> to oficjalne tłumaczenie słowa <em>items</em> w Zabbix) takich jak użycie CPU, RAM, zajętość dysków, ale też monitoring użycia zasobów przez kontenery Docker. Jako administrator można ustawić progi alertowania. No właśnie, alertowania, bo można też wysyłać alarmy z użyciem wybranego sposobu, ja zdecydowałem się na bota Telegram.</p>
<p>Beszel nieco przypomina Zabbixa, bowiem mamy tutaj oprogramowanie serwer+frontend (jako monolit), które deployujemy <em>gdzieś</em> i mamy także agentów, które instalujemy na sprzętach, które mają być monitorowane. Instalacja agenta może odbyć się zarówno z użyciem Dockera, jak i natywnej instalacji (skryptem). Z Beszela korzystałem całkiem długo i w zasadzie potrafi on być wystarczający dla wielu entuzjastów selfhostingu, a nawet myślę, że sprawdziłby się w mniejszych firmach. Zarówno agent, jak i oprogramowanie serwer+frontend jest niezwykle lekkie i szybkie - ja to drugie utrzymywałem z powodzeniem na Mikrus Frog. <strong>Dlatego do dzisiaj Beszela potrafię polecać.</strong></p>
<p>Ale zaczęło mi brakować większej liczby funkcji. Zwłaszcza monitorowania innych sprzętów, chociażby routera, ale też jakichś aplikacji, np. RabbitMQ. Beszel Agent nie działał też na każdym sprzęcie, na przykład nie mogłem z powodzeniem uruchomić go na Orange Pi Zero 2. Co więcej, chciałem rozpocząć monitoring SMART dysków, które mam w RAID1. Myślałem o jakichś skryptach Bash i powiadomieniach, ale uznałem, że to bez sensu &ndash; wszystko powinno być scentralizowane. Czarę goryczy przelała sama Uptime Kuma, która zaczęła generować fałszywe alarmy, a także miewała problemy, które były oznaczone jak <code>wontfix</code> na Githubie. I nie, przesiadka na Uptime Kuma v2 nic nie dała. Finalnie też chciałem zdobywać ekspercką wiedzę w oprogramowaniu poziomu enterprise, a Zabbix bardzo mi się spodobał, bo zacząłem poświęcać mu całkiem dużo czasu w pracy. Co więcej, rozpocząłem proces certyfikacji i na moment pisania tego artykułu mam certyfikat <a href="https://www.zabbix.com/certificate/?firstname=Grzegorz&amp;lastname=Cichocki&amp;certificate=CU-2507-212&amp;version=7.0">Zabbix Certified User 7.0</a> oraz nabyłem książkę polskiego autora Mateusza Dampca pod tytułem &ldquo;Zabbix 7.0. Efektywny monitoring infrastruktury IT dla każdego&rdquo;, która bardzo mi się spodobała, ale potrzebowałem miejsca, gdzie będę mógł testować nowe rozwiązania.</p>
<h2 id="początki-zabbixa-w-moim-domu">Początki Zabbixa w moim domu</h2>
<p>Po tym, jak ułożyłem sobie potrzeby wobec monitoringu, nieco lepiej poznałem Zabbixa, a także zapoznałem się z częścią książki &ldquo;Zabbix 7.0. Efektywny monitoring infrastruktury IT dla każdego&rdquo; uznałem, że Zabbix faktycznie będzie najlepszym wyjściem. Postanowiłem jednak zrobić sobie pewnego rodzaju <em>dry-run</em> i zdeployowałem Zabbixa u siebie w domu, na komputerze Mini PC z Proxmoxem. Wykorzystałem do tego OpenTofu oraz przygotowałem sobie skrypt Cloud Init. Do tego uznałem, że najlepszym wyborem jest architektura z dwoma maszynami wirtualnymi, gdzie jedna hostuje zarówno Zabbix-Frontend (czyli moduł odpowiedzialny za GUI) oraz Zabbix-Server (czyli serce tego systemu). Natomiast na drugiej maszynie wirtualnej zainstalowałem MariaDB jako bazę danych dla Zabbixa. Dodam, że obydwie aplikacje Zabbixa zainstalowałem z użyciem Dockera, natomiast bazę danych natywnie, za pomocą wbudowanego w Debiana menedżera pakietów.</p>
<p><img alt="Użycie RAM przez router z OpenWrt" loading="lazy" src="/img/zabbix/asus-ax53-cpu.png#center" title="Użycie RAM przez router z OpenWrt"></p>
<p>Na różnych maszynach doinstalowałem agentów, skonfigurowałem media do wysyłania alarmów i&hellip; zaczęło mi się to podobać &ndash; tym bardziej, że do świata monitoringu dołączył kolejny mój sprzęt, czyli router ASUS AX-53U z OpenWrt &ndash; pakiet zabbix-agent tak sobie czekał w repozytorium na zainstalowanie i skonfigurowanie. Do tego zacząłem szukać różnych templatek i innych rzeczy do monitorowania. Tak zacząłem dodawać monitoring kontenerów Docker dzięki zabbix-agent2 i wtyczce <em>Docker</em>, monitoring <a href="https://github.com/Garfieldttt/zabbix-homeassistant/blob/main/7.0/Home%20Assistant%20-%20Zabbix.yaml">Home Assistanta z użyciem niestandardowej templatki</a> czy brokera MQTT RabbitMQ. Wiem też, że mam sporo innych rzeczy, które mogę łatwo wchłonąć do monitoringu, ale nie miałem za bardzo czasu, aby do tego przysiąść. Nie miałem czasu, bo zacząłem myśleć nad produkcyjną wersją tego monitoringu.</p>
<h2 id="przygotowania-do-wypuszczenia-zabbixa-w-świat">Przygotowania do wypuszczenia Zabbixa w świat</h2>
<p>Dalej wiedziałem, że monitoring powinien żyć poza moim domem, a więc musiał być zdeployowany w jakiejś chmurze, ale nie mógł być to Mikrus, ponieważ nie sprawdziłby się &ndash; w dłuższej perspektywie jest trudny w utrzymaniu i nie oferuje personalnego adresu IP. Mikrus ma sporo ciekawych funkcji potrzebnych i ułatwiających życie z perspektywy osoby wchodzącej w ten świat, ale ja już potrzebowałem czegoś innego. Szybko zdecydowałem więc, że najlepszym wyjściem będzie deployment w chmurze Hetzner. Nie będę kłamał, wielkim fanem tej usługi nie jestem, ale akurat w tym przypadku spełniała większość wymogów, przede wszystkim instancje EC2 można deployować za pomocą Terraforma oraz płaci się w formie Pay as you Go, a nie w abonamencie. Ponadto, nawet najniższy typ instancji EC2 jest naprawdę wydajny i spełniający wymogi, a cena za nią jest wręcz bajeczna. CX22, bo taki typ wybrałem (aktualnie zastąpiony przez jeszcze tańszy typ CX23) kosztuje lekko ponad 4 Euro z polskim VAT-em i za taki <em>hajs</em> oferuje 4 GB RAM i 2 rdzenie vCPU.</p>
<p>Koszt dwóch instancji i jednego publicznego adresu IP nie byłby wysoki, jednakże chciałem ten koszt obniżyć, a także zachować podejście projektowe, gdzie kilka osób pracuje nad utrzymaniem i rozwojem infrastruktury. Dlatego też do projektu zaprosiłem dwóch kolegów, którzy również posiadają domowe serwery. Długo namawiać ich nie musiałem, ponieważ obydwaj korzystali z Beszel i szybko zrozumieli zalety Zabbixa. To podzieliło koszty na trzech. Finalnie jednak, na moment pisania tego artykułu, w skład projektu wchodzi już 5 osób.</p>
<h2 id="deployment-w-chmurze-hetzner">Deployment w chmurze Hetzner</h2>
<p>Przejdźmy więc do głównego dania. Hetzner nie daje ogromnych możliwości w projektowaniu rozwiązań chmurowych &ndash; liczba usług jest mała, a opcje modyfikacji tych istniejących są po prostu niewielkie. Przykładowo, byłem gotowy zacząć płacić nieco więcej zyskując zmniejszenie swojej odpowiedzialności i właśnie w tym mogłaby mi pomóc instancja silnika bazodanowego, coś w stylu RDS. Niestety, Hetzner czegoś takiego nie oferuje. Również myślałem nad skorzystaniem z Load Balancera, ale pricing za takowy w Hetzner nie jest dla mnie korzystny. Co więcej, chciałem też skorzystać z bucketów S3 (chociażby do trzymania pliku stanu Terraforma), ale, ponownie, pricing za buckety w Hetzner jest niekorzystny. Finalnie potrzebowałem też menedżera sekretów, którego w Hetzner po prostu nie ma.</p>
<p>Ale to też nie oznacza, że nie da się czegoś wymyślić. Dlatego też przyjąłem kilka zasad:</p>
<ol>
<li>Architektura będzie powielona z <em>dry-run</em>, tudzież znowu postawię dwie instancje EC2, gdzie jedna będzie serwować frontend oraz serwer Zabbixa, a druga bazę danych (MariaDB).</li>
<li>Tylko instancja z serwerem będzie dostępna bezpośrednio dla użytkowników.</li>
<li>Skorzystam z usługi Networks w Hetzner, aby umieścić obydwie instancje w sieci prywatnej.</li>
<li>Skorzystam z firewalla dostępnego w Hetzner.</li>
<li>Kod IaC będzie zawierał jak najwięcej możliwie ustawień, ale bez zapisanych sekretów czystym tekstem.</li>
<li>Skorzystam z funkcji backupów w Hetzner.</li>
</ol>
<p>Musiałem więc przeskoczyć niektóre z braków Hetznera. Brak usługi RDS zastąpiłem po prostu drugą instancją EC2. Brak menedżera sekretów nadrobiłem usługą Secret Manager w BitWarden, natomiast bucket S3 zapewniła mi chmura Scaleway, z którą już miałem do czynienia. Firewall pozostał w Hetzner, ale zarządzanie domeną (tak jak planowałem od samego początku) przeniosłem do Cloudflare. <strong>Zapytacie więc jak zarządzać tym chaosem korzystania z wielu usług?</strong> Normalnie byłby to koszmar, ale mając jeden <em>interfejs</em> do tego wszystkiego nie jest tak ciężko. A właśnie takim <em>interfejsem</em> jest Terraform, choć w rzeczywistości to jego fork o lepszej licencji, czyli OpenTofu. Mając OpenTofu tak naprawdę nie ma dla mnie znaczenia gdzie spoczywają sekrety, gdzie zapisany jest plik stanu Terraforma czy inne elementy, bo w kodzie to niemalże wszystko to samo. Niejako widać to na listingu poniżej.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-hcl" data-lang="hcl"><span style="display:flex;"><span><span style="color:#66d9ef">module</span> <span style="color:#e6db74">&#34;zabbix_database&#34;</span> {
</span></span><span style="display:flex;"><span>  source <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;../../Modules/hetzner_server_instance&#34;</span><span style="color:#75715e"> #moduły są wersjonowane tagami w git, ta linia jest zamiennikiem na potrzeby artykułu
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span>  name     <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">instance</span>.<span style="color:#66d9ef">database_server</span>.<span style="color:#66d9ef">name</span>
</span></span><span style="display:flex;"><span>  location <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">hetzner</span>.<span style="color:#66d9ef">location</span>
</span></span><span style="display:flex;"><span>  type     <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">instance</span>.<span style="color:#66d9ef">type</span>
</span></span><span style="display:flex;"><span>  image    <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">instance</span>.<span style="color:#66d9ef">image</span>
</span></span><span style="display:flex;"><span>  backups <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  networking <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    ipv4_enabled <span style="color:#f92672">=</span> <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>    ipv6_enabled <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  private_network <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    network_id <span style="color:#f92672">=</span> <span style="color:#66d9ef">module</span>.<span style="color:#66d9ef">arvalis_network</span>.<span style="color:#66d9ef">id</span>
</span></span><span style="display:flex;"><span>    alias_ips  <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  cloud_init <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    config <span style="color:#f92672">=</span> <span style="color:#66d9ef">join</span>(<span style="color:#e6db74">&#34;\n&#34;</span>, [
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">templatefile</span>(<span style="color:#e6db74">&#34;${path.module}/files/cloud-init/users-init.yaml.tpl&#34;</span>, {
</span></span><span style="display:flex;"><span>        users <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">users_list</span>
</span></span><span style="display:flex;"><span>      }),
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">templatefile</span>(<span style="color:#e6db74">&#34;${path.module}/files/cloud-init/database-instance/cloud-init.yaml.tpl&#34;</span>, {
</span></span><span style="display:flex;"><span>        users                  <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">users_list</span>
</span></span><span style="display:flex;"><span>        hostname               <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">instance</span>.<span style="color:#66d9ef">database_server</span>.<span style="color:#66d9ef">name</span>
</span></span><span style="display:flex;"><span>        zabbixdb_user_password <span style="color:#f92672">=</span> <span style="color:#66d9ef">sensitive</span>(<span style="color:#66d9ef">data</span>.<span style="color:#66d9ef">bitwarden_secret</span>.<span style="color:#66d9ef">zabbixdb_user_password</span>.<span style="color:#66d9ef">value</span>)
</span></span><span style="display:flex;"><span>      })
</span></span><span style="display:flex;"><span>    ])
</span></span><span style="display:flex;"><span>    gzip          <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>    base64_encode <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  labels <span style="color:#f92672">=</span> <span style="color:#66d9ef">merge</span>(
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">common_tags</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">instance</span>.<span style="color:#66d9ef">database_server</span>.<span style="color:#66d9ef">tags</span>,
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      name <span style="color:#f92672">=</span> <span style="color:#66d9ef">local</span>.<span style="color:#66d9ef">instance</span>.<span style="color:#66d9ef">database_server</span>.<span style="color:#66d9ef">name</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  )
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>OpenTofu daje tak bardzo koherentne doświadczenie, że wiele elementów deploymentu w Proxmox mogłem po prostu skopiować do kodu infrastruktury Hetznera. Ważnym też dla mnie elementem była konfiguracja użytkowników. Ta zapisana jest w pliku <code>user-data.yaml.tpl</code> i to właśnie tam zdefiniowani są wszyscy użytkownicy wraz z publicznymi kluczami SSH. Plik ten jest częścią standardu Cloud init (często w chmurach chowającego się pod postacią skryptu User Data) i deployowany jest na obie instancje. Wspomniany Cloud Init używam również do wstępnej konfiguracji maszyn, np. instalacji Dockera czy instalacji MariaDB.</p>
<p>Wspomniane kontenery Docker również deployuję z poziomu OpenTofu, co umożliwia <a href="https://codeberg.org/cichy1173/cichyform/src/branch/main/Docker/docker_service">mój autorski moduł</a>, który ma niejako udawać Docker Compose. Definicja wygląda tak:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-hcl" data-lang="hcl"><span style="display:flex;"><span><span style="color:#66d9ef">module</span> <span style="color:#e6db74">&#34;zabbix_frontend_container&#34;</span> {
</span></span><span style="display:flex;"><span>  source       <span style="color:#f92672">=</span> &#34;git::ssh://git@codeberg.org/cichy1173/cichyform.git//Docker/docker_service?ref<span style="color:#f92672">=</span><span style="color:#66d9ef">docker_service_v1</span>.<span style="color:#ae81ff">0</span>.<span style="color:#ae81ff">0</span><span style="color:#960050;background-color:#1e0010">&#34;</span>
</span></span><span style="display:flex;"><span>  service_name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zabbix-web-nginx-mysql&#34;</span>
</span></span><span style="display:flex;"><span>  image_name   <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;zabbix/zabbix-web-nginx-mysql:alpine-7.0.21&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  volumes <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  ports <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>      internal <span style="color:#f92672">=</span> <span style="color:#ae81ff">8080</span>
</span></span><span style="display:flex;"><span>      external <span style="color:#f92672">=</span> <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>      protocol <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;tcp&#34;</span>
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  environment_variables <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>    &#34;DB_SERVER_HOST<span style="color:#f92672">=</span><span style="color:#e6db74">${</span><span style="color:#960050;background-color:#1e0010">module</span>.<span style="color:#960050;background-color:#1e0010">zabbix_database</span>.<span style="color:#960050;background-color:#1e0010">ipv4_private_address</span><span style="color:#e6db74">}</span><span style="color:#960050;background-color:#1e0010">&#34;</span>,
</span></span><span style="display:flex;"><span>    &#34;MYSQL_DATABASE<span style="color:#f92672">=</span><span style="color:#66d9ef">zabbix</span><span style="color:#960050;background-color:#1e0010">&#34;</span>,
</span></span><span style="display:flex;"><span>    &#34;MYSQL_USER<span style="color:#f92672">=</span><span style="color:#66d9ef">zabbix</span><span style="color:#960050;background-color:#1e0010">&#34;</span>,
</span></span><span style="display:flex;"><span>    &#34;ZBX_SERVER_HOST<span style="color:#f92672">=</span><span style="color:#e6db74">${</span><span style="color:#960050;background-color:#1e0010">module</span>.<span style="color:#960050;background-color:#1e0010">zabbix_server_frontend</span>.<span style="color:#960050;background-color:#1e0010">ipv4_private_address</span><span style="color:#e6db74">}</span><span style="color:#960050;background-color:#1e0010">&#34;</span>,
</span></span><span style="display:flex;"><span>    &#34;ZBX_SERVER_PORT<span style="color:#f92672">=</span><span style="color:#ae81ff">10051</span><span style="color:#960050;background-color:#1e0010">&#34;</span>,
</span></span><span style="display:flex;"><span>    &#34;ZBX_SERVER_NAME<span style="color:#f92672">=</span><span style="color:#66d9ef">Arvalis</span> <span style="color:#66d9ef">Monitoring</span><span style="color:#960050;background-color:#1e0010">&#34;</span>
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>  depends_on <span style="color:#f92672">=</span> [<span style="color:#66d9ef">module</span>.<span style="color:#66d9ef">zabbix_server_frontend</span>, <span style="color:#66d9ef">module</span>.<span style="color:#66d9ef">zabbix_database</span>]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="praca-z-zabbix-zainstalowanym-w-hetzner-oraz-koszty">Praca z Zabbix zainstalowanym w Hetzner oraz koszty</h2>
<p>Od samego początku infrastruktura zakładała skorzystanie z Zabbix Proxy w trybie Active. Dlaczego? Nie chciałem, aby każdy z nas w jakiś sposób otwierał port 10051 u siebie, tym bardziej, że niektórzy są za podwójnym NAT-em. Ponadto korzystanie z Zabbix Proxy Active jest mniej zasobożerne dla instancji Zabbixa.</p>
<p><strong>A czym jest Zabbix Proxy?</strong> W skrócie, Proxy to taka usługa, która może zbierać metryki z różnych instancji w danej sieci, a następnie przesłać je do faktycznego Zabbix Serwera. <strong>No to czym więc jest tryb Active?</strong> Zabbix Proxy w trybie Active sam inicjuje połączenie do serwera, wysyła metryki do Zabbix-Server na port 10051, a ten w odpowiedzi przesyła konfigurację. W trybie Passive połączenie odbywa się w odwrotną stronę &ndash; Server inicjuje połączenie na port 10051 Proxy, a to w odpowiedzi zwraca metryki. W dosyć analogiczny sposób działa Zabbix Agent Passive/Active, ale agenci w tej historii nie są ważni.</p>
<p><img alt="Schemat działania Zabbix Proxy" loading="lazy" src="/img/zabbix/zabbix-proxy-active-passive.jpg#center" title="Schemat działania Zabbix Proxy"></p>
<p>No więc plan zakładał, że każdy sobie deployuje Zabbix Proxy w swojej sieci, gdziekolwiek tam sobie chce, jakkolwiek sobie chce, a następnie w trybie Active przesyła dane do Zabbix Server. Ponadto, dołożyliśmy szyfrowanie za pomocą certyfikatów TLS. Zadziałało to bardzo fajnie. Zabbix Server też prowadzi działania odpytujące, aczkolwiek bardziej w celu zastąpienia Uptime Kuma, bowiem Zabbix może robić dokładnie to samo dzięki Web Scenarios. Jednak aby sobie ułatwić proces dodawania i zarządzania monitoringiem Web, utworzyliśmy skrypt Python, który, wykorzystując bibliotekę Zabbix-Python-Utils, wrzuca nam monitoring stron internetowych zarówno z poziomu internetu, jak i w sieci lokalnej (dzięki monitoringu za pomocą Zabbix Proxy).</p>
<p>Tak jak wspomniałem, do projektu dołączyły kolejne osoby, co nie zamęczyło Zabbix Server. Użycie RAM wynosi około 50%, a CPU to użycie około 10-15%. Naprawdę niewiele i mamy spory margines mocy, aby wrzucać kolejne hosty do monitorowania, a nawet całe lokalizacje wraz z Zabbix Proxy Groups. Tak, z Proxy Groups też korzystamy i to naprawdę fajna funkcja.</p>
<p><img alt="Użycie CPU przez Zabbix" loading="lazy" src="/img/zabbix/arvalis-cpu.png#center" title="Użycie CPU przez Zabbix"></p>
<p><img alt="Użycie RAM przez Zabbix" loading="lazy" src="/img/zabbix/arvalis-ram.png#center" title="Użycie RAM przez Zabbix"></p>
<p><strong>A jak kilku użytkowników może korzystać z Zabbix?</strong> Wykorzystujemy funkcję Host Groups, gdzie każdy z nas ma swoją dedykowaną, imienną grupę hostów. Natomiast hosty do monitorowania są rozdzielone między użytkownikami właśnie z użyciem tych grup. Każdy użytkownik ma dostęp tylko do swojej grupy hostów i tym samym widzi metryki i alarmy związane tylko ze swoją grupą. Rozdzielenie <em>logiczne</em> jest nieco większe, ale sercem tego podziału są właśnie te grupy.</p>
<p><strong>Co z kosztami?</strong> No jest lepiej niż myślałem. Musimy płacić za dwie instancje EC2, adres publiczny IPv4, bucket S3 (to są grosze) oraz za domenę (koszt jednorazowy, raz na rok). Finalnie miesięcznie koszt to 10-13 złotych za osobę. Jak za tak potężny monitoring jest to wręcz niewiele.</p>
<h2 id="podsumowanie">Podsumowanie</h2>
<p><strong>To nie koniec rozwoju projektu!</strong> Nadal musimy opracować wiele rozwiązań, które pomogą nam zarządzać usługą. Pierwszą rzeczą w tej kolejce jest wprowadzenie automatyzacji do obsługi zmiennego adresu IP. Chcę również dodać wykrywanie dryftów w kodzie infry (Forgejo Actions jest już gotowe, należy tylko je wdrożyć w repo), czy lepiej zautomatyzować patchowanie. Ale już na tym etapie uważam, że projekt działa fajnie. W żaden sposób nie jest skomplikowany, w zasadzie to niezwykle prosta architektura, ale z jakiegoś powodu nawet może być zadowalająca.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Adguard Home zarządzany w kodzie z użyciem OpenTofu. Dlaczego w to poszedłem?</title>
      <link>https://blog.cichy1173.eu/news/adguard-home-iac/</link>
      <pubDate>Fri, 19 Sep 2025 10:00:52 +0200</pubDate>
      <guid>https://blog.cichy1173.eu/news/adguard-home-iac/</guid>
      <description>&lt;h2 id=&#34;wstęp&#34;&gt;Wstęp&lt;/h2&gt;
&lt;p&gt;Jest taki żart brzmiący &amp;ldquo;It&amp;rsquo;s always DNS&amp;rdquo;, który wyjaśnia, że w razie jakichś problemów z dostępem do internetu, to zazwyczaj winnym jest DNS. I tak też bywa u mnie, ponieważ sam korzystam z alternatywnego DNS, aby móc blokować reklamy i inne nieprzyjemne połączenia. Wykorzystuję do tego oprogramowanie AdGuard Home, które spełnia podobną rolę jak Pi-Hole, ale AdGuard Home ma przewagę w postaci świetnie działającego providera do Terraform/OpenTofu. Dlatego też postanowiłem zmigrować konfigurację AdGuarda właśnie do OpenTofu. Wiedziałem jednak, że tylko jeden node z AdGuardem to nie jest najlepsze wyjście, a niedługo później miałem się o tym przekonać.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="wstęp">Wstęp</h2>
<p>Jest taki żart brzmiący &ldquo;It&rsquo;s always DNS&rdquo;, który wyjaśnia, że w razie jakichś problemów z dostępem do internetu, to zazwyczaj winnym jest DNS. I tak też bywa u mnie, ponieważ sam korzystam z alternatywnego DNS, aby móc blokować reklamy i inne nieprzyjemne połączenia. Wykorzystuję do tego oprogramowanie AdGuard Home, które spełnia podobną rolę jak Pi-Hole, ale AdGuard Home ma przewagę w postaci świetnie działającego providera do Terraform/OpenTofu. Dlatego też postanowiłem zmigrować konfigurację AdGuarda właśnie do OpenTofu. Wiedziałem jednak, że tylko jeden node z AdGuardem to nie jest najlepsze wyjście, a niedługo później miałem się o tym przekonać.</p>
<blockquote>
<p>W tym artykule słowa &ldquo;OpenTofu&rdquo; i &ldquo;Terraform&rdquo; będę wykorzystywać naprzemiennie.</p>
</blockquote>
<h2 id="problem-jednego-nodea-dns">Problem jednego node&rsquo;a DNS</h2>
<p>Kiedy to poprawiałem zasilanie swojej &ldquo;szafy&rdquo;, to odpiąłem z prądu komputer, na którym to AdGuard Home był zainstalowany. Po chwili mój telefon przestał odtwarzać film na YouTube, który uruchomiłem sobie w tle, a Telegram przestał otrzymywać nowe wiadomości. Szybko zrozumiałem co się stało i postanowiłem rozwiązać przyszłe występowanie tego problemu tak, abym mógł bezproblemowo odpinać node&rsquo;y z AdGuardem z zachowaniem pełnej funkcjonalności sieci.</p>
<p>Dlatego też zdecydowałem, że dołożę kolejne dwa urządzenia z instalacjami AdGuarda Home &ndash; jeden w sieci lokalnej, a drugi poza nią, w momencie pisania artykułu na serwerze Mikrus. Wszystkie te node&rsquo;y (w sumie trzy) spiąłem za pomocą sieci Tailscale. Pozostał jednak problem zarządzania konfiguracją. Nawet jeśli teraz zaprę się i ręcznie poustawiam tak samo wszystkie te instalacje, to i tak w przyszłości każda jedna zmiana będzie bolączką. Całe szczęście, miałem już konfigurację zapisaną w kodzie Terraform/OpenTofu, a więc doszło mi tylko rozdystrybuowanie jej na więcej urządzeń.</p>
<p>Postanowiłem więc pozostać w świecie Terraforma. Wyzwaniem jednak był fakt, że dokładnie ten sam kod w tym samym repozytorium miał zacząć obsługiwać kilka równorzędnych sobie node&rsquo;ów z oprogramowaniem AdGuard Home. To problem logiczny, którego do tej pory jeszcze nie spotkałem.</p>
<h3 id="dlaczego-terraform">Dlaczego Terraform?</h3>
<p>Idea IaC (Infrastructure as Code) jest mi bardzo bliska, głównie ze względu na pracę zawodową. Ideę tę postanowiłem też pielęgnować i rozwijać w ramach homelabu, jednakże w środowisku &ldquo;domowym&rdquo; zasobnik wykorzystywanych narzędzi jest znacznie inny. To jednak mnie nie zraziło i zacząłem rozwijać swój kod OpenTofu, najpierw dla maszyn wirtualnych w Proxmox (specjalnie dla OpenTofu zacząłem korzystać z Proxmoxa), a później właśnie dla AdGuard Home.</p>
<p><strong>A dlaczego w ogóle wybrałem Terraforma/OpenTofu?</strong> Przyznam, że pisanie kodu właśnie w tym narzędziu/środowisku zaczęło mi dawać dużo zabawy i chęci eksploracji. W pracy miałem dużo okazji, aby zapoznać się z Terraformem i szybko uznałem, że idea i sposób działania świetnie odnajdzie się również w środowisku homelabowym.</p>

<div style="display: flex; justify-content: center; margin: 1em 0;">
  <iframe src="https://mastodon.social/@cichy1173/114167224860456027/embed"
          class="mastodon-embed"
          style="max-width: 100%; border: 0"
          width="500"
          height="280"></iframe>
</div>
<script src="https://mastodon.social/embed.js" async="async"></script>

<p>Możliwe, że ktoś z Was korzysta z AdGuard Home zainstalowanego na wielu urządzeniach i wcale nie musiał rozwiązywać takich problemów, a przynamniej nie w taki sposób jak zrobiłem to ja. I to prawda, jest to możliwe, bowiem istnieje oprogramowanie <a href="https://github.com/bakito/adguardhome-sync">adguardhome-sync</a>, które właśnie pozwala na łatwe zarządzanie replikami Adguarda. Jednakże, jest to kolejny software, który trzeba instalować, ponadto nie jest on zgodny z ideą GitOps i, przede wszystkim, byłoby to pójście na skróty, a ja ten projekt chciałem wykorzystać do nauki.</p>
<h2 id="gitops-i-load-balancing">GitOps i &ldquo;Load Balancing&rdquo;</h2>
<p>Do nauki właśnie metodologii <a href="https://www.atlassian.com/pl/git/tutorials/gitops">GitOps</a> do zarządzania konfiguracją. Adguard Home to oprogramowanie całkiem proste, a przygotowany przeze mnie kod Terraform również nie należy do najbardziej zaawansowanych (wszystko na czystych <em>resources</em>, bez żadnych modułów). Dlatego też uznałem że mógłbym się trochę pobawić w automatyzacje i GitOps. Do tego od jakiegoś czasu korzystałem z <a href="codeberg.org">codeberg.org</a> (Forgejo), co też dawało mi okazję do pouczenia się <a href="https://forgejo.org/docs/latest/user/actions/reference/">Forgejo Actions</a> i to na <a href="https://forgejo.org/docs/latest/admin/actions/runner-installation/">własnym (self-hosted) runnerze</a>.</p>
<p>Musiałem jednak najpierw rozwiązać wcześniej wspomniane problemy. Wiedziałem, że do wszystkich node&rsquo;ów powinien być tylko jeden config, tudzież jedno repozytorium z jednym katalogiem &ndash; to ograniczy potrzebę skakania po folderach. Jednak, aby działała dystrybucja konfiguracji, to muszę mieć wiele plików stanu (plik stanu w Terraform przechowuje aktualne odwzorowanie zasobów w infrastrukturze na definicje w kodzie, dzięki czemu Terraform wie, co istnieje i jakie zmiany trzeba wprowadzić). Dlatego też uznałem, że ścieżka do pliku stanu może być zmienną podawaną na wejściu komendy <code>tofu apply</code> (komenda, która najpierw wyświetla zmiany, które zostaną wdrożone, a następnie wdraża zmiany na prawdziwą architekturę). Wszelkie inne potrzebne wartości (jak adresy IP, loginy, hasła) również zacząłem zapodawać jako <em>variables</em>, które są podawane przy komendzie wdrożenia zmian. Całe szczęście już wcześniej plik stanu miałem przechowywany w miejscu zdalnym, a dokładnie w buckecie S3. To mi znacznie ułatwiło pracę.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>tofu init -var<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;state_file_path=</span><span style="color:#e6db74">${</span>{ secrets.STATEFILE_PATH_HOST1 <span style="color:#e6db74">}</span><span style="color:#e6db74">}&#34;</span>
</span></span><span style="display:flex;"><span>tofu validate
</span></span><span style="display:flex;"><span>tofu apply -auto-approve <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>    -var<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;adguard_url=</span><span style="color:#e6db74">${</span>{ secrets.ADGUARD_URL_HOST1 <span style="color:#e6db74">}</span><span style="color:#e6db74">}&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>    -var<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;adguard_username=</span><span style="color:#e6db74">${</span>{ secrets.ADGUARD_USERNAME_HOST1 <span style="color:#e6db74">}</span><span style="color:#e6db74">}&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>    -var<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;adguard_password=</span><span style="color:#e6db74">${</span>{ secrets.ADGUARD_PASSWORD_HOST1 <span style="color:#e6db74">}</span><span style="color:#e6db74">}&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>    -var<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;state_file_path=</span><span style="color:#e6db74">${</span>{ secrets.STATEFILE_PATH_HOST1 <span style="color:#e6db74">}</span><span style="color:#e6db74">}&#34;</span>
</span></span></code></pre></div><p>Nie chciałem jednak trzy razy wpisywać <code>tofu apply</code> z różnymi zmiennymi. Wszak nie jest to zbyt wygodne i może sprawić, że zapomnę o którymś z node&rsquo;ów, a przejście na Terragrunta nie wchodziło w grę. Dlatego też zacząłem pisać własny workflow dla Forgejo Actions. Nie było to trudne, bowiem Forgejo Actions to w rzeczywistości Github Actions, więc byłem już obyty ze składnią czy konceptami. Finalnie przygotowałem workflow, który wdraża zmiany po merge&rsquo;u do głównej gałęzi. Workflow testuje kod, a następnie wdraża zmiany komendą <code>tofu apply</code> na wszystkich dostępnych node&rsquo;ach. Przyznam jednak, że workflow wymaga aktualizacji, ponieważ działa na zbyt sztywnych komendach.</p>
<p>Postanowiłem jeszcze się nieco pobawić i przygotowałem kolejne <em>workflowy</em>. Wiedziałem, że odwiecznych problemem DevOpsów są drifty, czyli rozbieżności między kodem, a realną infrastrukturą. Dlatego też przygotowałem cronjoba, który regularnie sprawdza czy takowe drifty występują. Finalnie też przygotowałem workflow, który generuje plan zmian (<code>tofu plan</code>) na wskutek utworzenia nowego PR (zmiany są dodawane jako komentarz do PR).</p>
<p>A jak zacząć korzystać z tych wszystkich node&rsquo;ów? To bardzo proste. W przypadku sieci lokalnej rozwiązanie było przewidywalne &ndash; wystarczy podać adresy obydwóch node&rsquo;ów w ustawieniach DNS w routerze. Dla reszty urządzeń wykorzystałem Tailscale, gdzie podałem wszystkie trzy node&rsquo;y jako adresy DNS. Co więcej, ustawiłem, że DNS Tailscale&rsquo;a nadpisuje domyślny DNS na urządzeniach, gdzie Tailscale jest zainstalowany, dzięki czemu mam pewność, że mój Adguard Home jest w użyciu.</p>
<h3 id="a-może-jakiś-dashboard-do-tego">A może jakiś dashboard do tego?</h3>
<p>Uznałem jednak, że fajnie byłoby wyciągać metryki ze wszystkich node&rsquo;ów i je jakoś ładnie wizualizować. Tak się składa, że Adguard Home integruje się z Home Assistant. Wystarczyło dodać wszystkie trzy instalacje AGH do Home Assistanta i utworzyć widgety z wykresami, gdzie widziałbym połączone wyniki.</p>
<p><img alt="Wykresy AdGuard Home w Home Assistant" loading="lazy" src="/img/adguard-wykresy.png#center" title="Wykresy AdGuard Home w Home Assistant"></p>
<p>Utworzyłem sobie również automatyzację, które pozwala mi włączać i wyłączać blokowanie reklam na wszystkich node&rsquo;ach jednocześnie. Wykorzystuję do tego właśnie automatyzację oraz pomocnik w postaci przełącznika, który jest w stanie ON, kiedy wszystkie node&rsquo;y mają włączone blokowanie i w stanie OFF kiedy chociaż jeden z node&rsquo;ów ma wyłączone blokowanie.</p>
<p><img alt="Przełącznik AdGuard Home w Home Assistant" loading="lazy" src="/img/adguard-switch.png#center" title="Przełącznik AdGuard Home w Home Assistant"></p>
<p>Kod tych rozwiązań udostępniłem w repozytorium. Dodam jednak, że wykresy wykorzystują zewnętrzny widget <code>custom:mini-graph-card</code>, który można zainstalować za pomocą HACS (Home Assistant Community Store).</p>
<h2 id="publikacja-projektu-adguard-home-cm-repository">Publikacja projektu <code>AdGuard Home CM Repository</code></h2>
<p>No właśnie, repozytorium. Tak się składa, że projekt postanowiłem opublikować. Nie jest on w żaden sposób zaawansowany, w zasadzie to naprawdę prosty kod i niezbyt rozbudowane automatyzacje. Jednakże projekt reprezentuje kilka ważnych dla mnie rzeczy.</p>
<ol>
<li>Projekt może być zarówno dla mnie, jak i dla innych prototypem i wzorcem dla innych repozytoriów wdrażających GitOps w homelab.</li>
<li>Projekt pokazuje inne podejście do zarządzania i konfiguracji oprogramowania Adguard Home.</li>
<li>Projekt wykazuje, że Forgejo to nowoczesne oprogramowanie typu Forge, które sprawdzi się w środowisku domowym i biznesowym.</li>
<li>Projekt dokłada malutką cegiełkę do zjawiska migracji użytkowników z GitHuba na alternatywne rozwiązania Forge.</li>
<li>Projekt, wbrew pozorom, może przydać się wielu entuzjastom selfhostingu, a jednocześnie prezentuje rzadko wykorzystywane podejście w takim środowisku. Projekt tym samym może zachęcić do nauki Terraforma/OpenTofu i poznania Forgejo Actions.</li>
</ol>

<div style="text-align: center; margin: 1em 0;">
  <strong><a href="https://codeberg.org/cichy1173/adguard-home-cm-repository">
    Sprawdź projekt AdGuard Home CM Repository na Codebergu!
  </a></strong>
</div>

<h2 id="podsumowanie">Podsumowanie</h2>
<p>Adguard Home CM Repository to projekt, z którego ciągle korzystam. Adguard spełnia u mnie kilka funkcji, jest blockerem reklam i złośliwych stron, tworzy proste przekierowania domen <code>.local</code>, a także wytworzył u mnie podstawy metodologii GitOps do homelaba. W połączeniu z Tailscale i właśnie Forgejo dostałem bardzo wygodne rozwiązanie, które potrafi sporo nauczyć i zabezpiecza mi bardzo ważny element sieci domowej, czyli właśnie DNS.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Linux na studiach informatycznych w Polsce</title>
      <link>https://blog.cichy1173.eu/news/linux-studia/</link>
      <pubDate>Thu, 11 Sep 2025 15:29:18 +0200</pubDate>
      <guid>https://blog.cichy1173.eu/news/linux-studia/</guid>
      <description>&lt;h2 id=&#34;wstęp&#34;&gt;Wstęp&lt;/h2&gt;
&lt;p&gt;Mam za sobą 6 lat studiów na polskich uczelniach, kierunek: Informatyka. 5 lat na popularnej, publicznej uczelni, czyli Politechnice Lubelskiej (3,5 roku studiów inżynierskich + 1,5 roku studiów magisterskich) w trybie dziennym, stacjonarnym oraz rok studiów na uczelni prywatnej (poziom magisterski, specjalizacja &amp;ldquo;cyberbezpieczeństwo&amp;rdquo;) w trybie niestacjonarnym. Na tych studiach korzystałem z Linuxa, również gdy te przyjęły rolę zdalnych z powodu COVID.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ten artykuł został przeze mnie udostępniony już kilka miesięcy temu, za pomocą aplikacji HedgeDoc. Udostępniam go jednak jeszcze raz tutaj, ale w nieco zmodyfikowanej, zaktualizowanej formie.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<h2 id="wstęp">Wstęp</h2>
<p>Mam za sobą 6 lat studiów na polskich uczelniach, kierunek: Informatyka. 5 lat na popularnej, publicznej uczelni, czyli Politechnice Lubelskiej (3,5 roku studiów inżynierskich + 1,5 roku studiów magisterskich) w trybie dziennym, stacjonarnym oraz rok studiów na uczelni prywatnej (poziom magisterski, specjalizacja &ldquo;cyberbezpieczeństwo&rdquo;) w trybie niestacjonarnym. Na tych studiach korzystałem z Linuxa, również gdy te przyjęły rolę zdalnych z powodu COVID.</p>
<blockquote>
<p>Ten artykuł został przeze mnie udostępniony już kilka miesięcy temu, za pomocą aplikacji HedgeDoc. Udostępniam go jednak jeszcze raz tutaj, ale w nieco zmodyfikowanej, zaktualizowanej formie.</p>
</blockquote>
<blockquote>
<p>W tym artykule słowo &ldquo;Linux&rdquo; będę wykorzystywał zamiennie ze słowem &ldquo;system operacyjny&rdquo;. Pisząc więc &ldquo;Linux&rdquo; mam na myśli &ldquo;System operacyjny typu Linux&rdquo;. Nie będę natomiast wskazywał na konkretne dystrybucje Linux, z których korzystałem, bowiem jest to tak naprawdę wtórne.</p>
</blockquote>
<h2 id="tldr">tl;dr</h2>
<p>Przejście całych studiów wykorzystując tylko system Linux jest możliwe, a nawet można uzyskać sporą przewagę nad innymi studentami niekorzystającymi z Linuxa, ale trzeba do tego OS-a podejść nieco chętniej, poznać go lepiej - mowa tu, przede wszystkim, o podstawach jego działania, korzystania z terminala i różnych menedżerów pakietów. Warto też dodać, że linuksowe GUI jest naprawdę dobre - sam uwielbiam GNOME - i zalety DE można fajnie wykorzystać w codziennej pracy (patrz: workspace&rsquo;y, tiling i inne). GNOME służy mi do dzisiaj, nie tylko prywatnie, ale również i w pracy zawodowej.</p>
<p>Warto dodać, żę są osoby, które poszły z tematem o krok dalej i uznały, że będą korzystać tylko z oprogramowania FOSS -&gt; <a href="https://www.gnu.org/education/how-i-fought-to-graduate-without-using-non-free-software.html">https://www.gnu.org/education/how-i-fought-to-graduate-without-using-non-free-software.html</a></p>
<h2 id="politechnika-lubelska">Politechnika Lubelska</h2>
<h3 id="pierwsze-15-roku-studiów">Pierwsze 1,5 roku studiów</h3>
<p>Pierwsze półtora roku studiów odbyło się w pełni stacjonarnie, wszak to jeszcze było przed pandemią. Na kierunku &ldquo;Informatyka&rdquo; pierwsze 3 semestry to czas nauki nie tylko tematów stricte komputerowych, ale też matematyki, fizyki i innych. Dlatego też ograniczę się do samych komputerów. Tak naprawdę głównie miałem programowanie i jego podstawy. Pisanie w C czy w C++ nie jest na Linuxie problemem, uważam je nawet za łatwiejsze, bo potrzebny stack jest zainstalowany na dzień dobry w większości dystrybucji. Miłym faktem było to, że uczyliśmy się również Qt, a Qt to natywna technologia dla Linuxa, zwłaszcza w KDE Plasma. Oczywiście wykorzystywany Qt Creator jest dostępny na Linux.</p>
<h4 id="niecodzienny-software">Niecodzienny software</h4>
<p>Taką wewnętrzną aplikacją dla uczelni był <a href="https://cs.pollub.pl/nsbuilder/?lang=en">NS Builder</a> - program do budowania i testowania schematów blokowych NS. Aplikacja jest open source, napisana w Qt i dostępna na Linux.</p>
<p>Problememem mógł być HLA, czyli High Level Assembler. Jednakże stack do programowania w HLA włączaliśmy w VM z Windows XP, również na uczelni. Włączenie VM na Linuxie to żaden problem (do czego będę tutaj nawiązywał wielokrotnie).</p>
<p>Był też przedmiot poświęcony Linuxowi. Użytkownik Linuxa tutaj zyskiwał pewną przewagę, bowiem jest z nim bardziej obyty, a nawet sama znajomość GUI w postaci GNOME (czyli podstawowe DE w Ubuntu) była pomocna. Warto dodać, że Ubuntu to też taki domyślny system operacyjny typu Linux, z którym z pewnością większość osób spotka się na studiach.</p>
<h3 id="semestr-iv">Semestr IV</h3>
<p>Początek 2020 roku, a więc był to pierwszy semestr zdalny. Wszystkie potrzebne aplikacje do pracy zdalnej były dostępne na Linux &ndash; a przynajmniej w przypadku mojej uczelni. Pierwszy semestr takiej pracy to też czas braku normalizacji, tudzież pewnej samowolki, dlatego dominował Discord (ale czasami potrzebny był Zoom). Jeden prowadzący zajęcia chciał korzystać z Webex, którego na Linuxa nie ma, ale udało się go namówić na Discord.</p>
<p>Jeśli chodzi o inne laboratoria (czyli zajęcia praktyczne w grupach do 15 osób), to nie miałem większych problemów - programowanie web/frontend lub w Javie wraz z narzędziami JetBrains to była przyjemność. Nie inaczej było na zajęciach z grafiki komputerowej, gdzie dominał w pełni zestaw aplikacji Open Source &ndash; Blender, GIMP czy Inkspace są dostępne na Linux. Do doświadczenia z Blenderem właśnie powoli wracam, ponieważ zakupiłem drukarkę 3D :-).</p>
<p>Reasumując, ten semestr był naprawdę nieproblematyczny i przejście go z komputerem pracującym pod kontrolą systemu Linux było jak najbardziej możliwe.</p>
<h3 id="iii-rok-studiów">III rok studiów</h3>
<p>Przechodzimy do kolejnego roku studiów, w zasadzie finalnego dla przyszłych inżynierów informatyki. No i w tym momencie zaczynają się schody, głównie z zajęciami z związanymi z mikrokontrolerami oraz systemami wbudowanymi. Wykorzystywane narzędzia były dostępne tylko na Windowsa ale:</p>
<ol>
<li>W przypadku Atmel Studio wystarczyła maszyna wirtualna z Windows 10 AME (dzisiaj ten projekt już nie istnieje w tej postaci).</li>
<li>W przypadku innych narzędzi wystarczyła maszyna wirtualna z Windows XP. Co tutaj ważne, dla lepszej kompatybilności z takiej maszyny korzystali również użytkownicy Windowsa.</li>
</ol>
<h4 id="mniej-znany-software">Mniej znany software</h4>
<p>Na tym semestrze pojawiły się również duże zalety Linuxa będące zarazem przewagą nad Windowsem. Otóż instalacja dwóch mniej znanych interpretatorów języków programowania była ułatwiona - mowa o Haskellu oraz PROLOG (+Python, ale to akurat znane rozwiązanie).</p>
<p>W kontekście baz danych, to również tutaj mamy przewagę Linuxa, ale z małą gwiazdką. MySQL i Postgres wraz z dedykowanymi klientami GUI to żaden problem na Linux, ponieważ można i skorzystać z Dockera, i z natywnych paczek. Problem pojawił się przy MS SQL. Sam silnik jest dostępny na Linuxa, ale dedykowane narzędzie GUI - SQL Server Management Studio - zostało udostępnione tylko dla użytkowników systemu od MS. Całe szczęście wystarczyło tutaj skorzystanie z DBeaver czy, w moim przypadku, Visual Studio.</p>
<p>Największym problemem był dosyć przestarzały stack deweloperski w postaci XAMPP. Istnieje on na Linuxa w wersji LAMPP, ale nie ma wszystkich narzędzi i może strasznie namieszać, ponieważ (jak dobrze pamiętam) katalog deweloperski tworzy się w <code>/opt</code>. Jest to o tyle tragiczne, że domyślnie tam dostępy są tylko dla <code>root</code>. Praca z takim stackiem wymaga kombinowania i rodzi problemy. Dlatego też programowanie w PHP z LAMPP to był dla mnie ogromny problem i z wiedzą, którą zdobyłem nieco później podszedłbym do tematu kompletnie inaczej, chociażby korzystając z Dockera.</p>
<p>w kontekście baz danych (a raczej laboratoriów dotyczących nauki zagadnień bazodanowych) pojawił się zgrzyt na tle formatów i korporacji (czyli coś, co mastodończycy uwielbiają najbardziej). Otóż pewien prowadzący chciał przyjmować sprawozdania tylko w formacie <code>.docx</code>. Udało się go jednak przekonać, że ograniczenie tylko do formatu korporacyjnego nie jest dobrym pomysłem i <code>.odt</code> został dopuszczony. Nie zabrakło jednak argumentu od drugiej strony na tle finansowym, twierdzącego, że pewnie nie stać mnie na MS Office i dlatego używam LibreOffice (xDD).</p>
<p>A co z programowaniem aplikacji na systemy mobilne? Uczelnia wybrała platformę Android, na którą to przygotowywaliśmy projekty. Tutaj mamy kolejną, wielką przewagę Linuxa, ponieważ Android Studio działa szybciej na tym systemie i nawet mając niezbyt wydajny sprzęt (a właśnie taki miałem), nadal mogliśmy cieszyć się wysoką szybkością.</p>
<h4 id="oprócz-programowania">Oprócz programowania&hellip;</h4>
<p>W zasadzie pamiętam tylko jedne zajęcia niezwiązane stricte z pisaniem kodu. Były to laboratoria &ldquo;Inżynieria oprogramowania&rdquo;, na których pracowałem w Draw.io (ciekawostka - zalecany był odpowiednik od Microsoftu, ale na niego narzekało wielu studentów, aż wszyscy wraz z prowadzącym przeszli na Draw.io, również za moim poleceniem) oraz w LibreOffice.</p>
<h3 id="ostatni-semestr-i-praca-inżynierska">Ostatni semestr i praca inżynierska</h3>
<p>W kontekście laboratoriów to dalej wykorzystywane były podobne narzędzia, które na Linux były dostępne lub po prostu istniała dowolność w doborze narzędzi.</p>
<p>Pracę inżynierską napisałem w stosie technologicznym: PHP, Laravel i MariaDB. Ponadto sama aplikacja &ldquo;stała&rdquo; na Raspberry Pi. Nie ma co tutaj dodawać, ponieważ wszystko tutaj działało na Linuxie. Problemem było jednak samo napisanie pracy, ponieważ odpowiednie formatowanie było trudne do odwzorowania w LibreOffice Writer, tym bardziej, że nie wszyscy w mojej grupie z LibreOffice korzystali. Pomoc kolegów z MS Office Word (lub z VM z Wordem) była tutaj bardzo przydatna.</p>
<h3 id="poziom-magisterski---semestr-i">Poziom magisterski - semestr I</h3>
<p>Tutaj niestety pojawiły się problemy. Na jednym z przedmiotów wykorzystywany był Microsoft Project niedostępny na Linuxie, a żadne alternatywne programy nie wchodziły w grę. Pomogła jednak maszyna wirtualna z Windows 10 AME. Na kolejnym przedmiocie wykorzystywane były inne zamknięte narzędzia i ograniczone do samego Windowsa. Byłby to problem gdyby nie fakt, że i tak nie mieliśmy licencji do uruchomienia tego oprogramowania poza uczelnią. Laboratoria można było spokojnie wykonać na uczelnianych komputerach. Co ważne, tutaj zacząłem bawić się w selfhosting i notatki oraz sprawozdania zacząłem pisać w HedgeDoc. Co więcej, HedgeDoc pomógł mi również w notowaniu na komputerach uczelnianych.</p>
<p>Reszta narzędzi z innych laboratoriów była dostępna na Linux.</p>
<h3 id="semestr-ii-i-iii-magisterki">Semestr II i III magisterki</h3>
<p>Kolejne semestry to kontynuacja wykorzystywania tych samych narzędzi - albo sam korzystałem z narzędzi linuxowych, bo była taka dowolność, albo narzucone narzędzia były dostępne na Linux. Pojawił się też PLSQL (w Oracle SQL), jednak nie miałem z nim żadnych problemów - połączenie kontenera dockerowego oraz DataGrip sprawdzało się świetnie.</p>
<p>Problemem niejako mógł być też przedmiot związany z hurtowniami danych. O ile głównie wykorzystywane narzędzie <em>Knime</em> jest Open Source i dostępne na Linux, tak problem był z Tableau. Na szczęście pomogła mi maszyna wirtualna z Windowsem 10.</p>
<h4 id="zadania-związane-z-devops">Zadania związane z DevOps</h4>
<p>Wyszczególniam ten dział z dwóch powodów - po pierwsze, zawodowo właśnie jestem inżynierem DevOps, a po drugie, tutaj też wychodzi przewaga w korzystaniu z systemu typu Linux. Zajęcia związane z chmurą internetową dotyczyły głównie Dockera, a jeśli mówimy o Dockerze, to też mówimy o Linuxie. Znajomość pisania konfiguracji, korzystania z Dockera czy pisania skryptów Bash była tutaj nieoceniona. Budowanie obrazów Docker również było wygodniejsze na Linuxie, głównie ze względu na znacznie wyższą wydajność. Kiedy przeszliśmy do fazy wdrożeń, to korzystaliśmy z Github Actions, które również bazują na Linuxie.</p>
<h3 id="praca-magisterska">Praca magisterska</h3>
<p>Finałem studiów była praca magisterska. Nauczony doświadczeniem, magisterkę pisałem tym razem w LaTeX, czyli po prostu w kodzie. Problemem mogło być napisanie artykułu naukowego (publikacja takiego artykułu była obowiążkowa dla każdego studenta POLLUB), co było możliwe tylko w Microsoft Word. Pomogła mi tutaj maszyna wirtualna.</p>
<p>A praca magisterska? No cóż, pisałem o Linuxie :-), a dokładnie o menedżerach pakietów Flatpak i Snap. OGROMNYM skrótem pracy jest artykuł naukowy, który znajdziecie <a href="https://ph.pollub.pl/index.php/jcsi/article/view/4587">tutaj</a>. Przy okazji dodam, że sam szablon pracy dyplomowej LaTeX udostępniłem publicznie m.in. na <a href="https://codeberg.org/cichy1173/pollub_dyplom_latex">Codeberg</a>.</p>
<h2 id="druga-uczelnia">Druga uczelnia</h2>
<p>Tak jak wspomniałem, Rozpocząłem również studia na drugiej uczelni. Ponownie na poziomie magisterskim, tym razem jednak na innej specjalizacji. Tutaj też mówimy o mniejszej, prywatnej uczelni, gdzie studiowałem w trybie niestacjonarnym.</p>
<h3 id="druga-magisterka---rok-pierwszy">Druga magisterka - rok pierwszy</h3>
<p>Jako osoba doświadczona korzystałem ze stacku już mi znanego na Linuxie - powróciłem do PHP, Laravel oraz Pythona. Tylko jeden przedmiot wymagał oprogramowania niedostępnego na Linuxie (MS Office Excel), ale wysyłałem arkusze zaliczeniowe w LibreOffice Calc, które były pozytywnie oceniane.</p>
<p>Mogę wspomnieć o małym narzędziu, które utworzyłem z myślą o studiach i ułatwieniu sobie pracy. Otóż plan zajęć zmieniał się bardzo często i nie byliśmy o tym informowani. Sam plan natomiast był udostępniany jako arkusz kalkulacyjny. Dlatego też przygotowałem bota, który pobierał aktualnie znajdujący się plan zajęć z systemu e-learningowego (Moodle) i porównywał go z poprzednią wersją (z użyciem skrótów kryptograficznych). Jeśli została wykryta zmiana, to była wysyłana wiadomość na kanał telegramowy z należytą informacją oraz plikiem najnowszego planu zajęć. Skrypt był uruchamiany w cronie. Ten mały projekcik został doceniony też przez innych studentów.</p>
<h2 id="podsumowanie">Podsumowanie</h2>
<p>Cóż, tl;dr to było dobre podsumowanie, ale chętnie powtórzę. Studia informatyczne w Polsce dla użytkowników Linuxa są możliwe do ukończenia i nie jest to niczym specjalnym. Polskie uczelnie chętnie wykorzystują open sourcowy stack - pewnie z różnych, finansowych powodów, ale jest to na korzyść takich studentów jakim byłem ja. Oczywiście pojawiły się zamknięte narzędzia, ale też nie uważam, że nie wolno takowych uczyć, zwłaszcza jak są bardzo popularne. Gorzej jednak jak student nie jest dopuszczony do wykorzystywania własnych alternatyw, które spełniają założenia laboratoriów (np. LibreOffice zamiast Microsoft Office jako narzędzie do sporządzenia sprawozdania).</p>
<p>Mało mówiłem o selfhostingu, ale ten też okazał się pomocny i żałuję, że nie zacząłem się w to bawić wcześniej. HedgeDoc i Overleaf (selfhosted jest naprawdę szybki i dobrze działający) to narzędzia niezwykle przydatne. Taki też był NextCloud z dostępem do Decka, kalendarza czy list zadań. Przydatna była też Vikunja, którą zresztą przedstawiałem na swojej uczelni jako rozwiązanie do realizacji projektów zespołowych. Dostępnych jest też wiele aplikacji naśladujących popularne rozwiązania do notatek itd. Zapewne ich funkcje znacznie ułatwią i uprzyjemnią naukę.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
