# llms.txt - pełna tekstowa reprezentacja strony LinuxLab.pl # LinuxLab to część grupy SysGroup Sp. z o.o. (https://sysgroup.pl). === STRONA GŁÓWNA === Linux Lab - Profesjonalna Administracja Serwerami Linux Monitoring 24/7 Profesjonalna administracja serwerami Linux. Zapewniamy kompleksową opiekę nad Twoją infrastrukturą IT. DevOps, monitoring, backup i bezpieczeństwo w jednym miejscu. ## Nasze usługi Kompleksowe rozwiązania dla Twojej infrastruktury serwerowej. ### Szybka pomoc Doraźna interwencja przy awariach serwerów Linux. Reagujemy natychmiast, gdy Twój biznes tego potrzebuje. ### Linux SRV Pełna opieka serwera: aktualizacje, monitoring 24/7, backup oraz kompleksowe wsparcie DevOps/SysOps. ### Linux MIN Podstawowa opieka z regularnymi aktualizacjami i wsparciem przy rozwiązywaniu problemów. ## Dlaczego LinuxLab? Łączymy wieloletnie doświadczenie z nowoczesnymi technologiami. Monitoring proaktywny z powiadomieniami SMS i email. Migracja aplikacji bez przestojów, specjalizacja w e-commerce. Kopie zapasowe w polskich klastrach serwerowych. Bezpieczeństwo: regularne aktualizacje i hardening. ## Z naszej bazy wiedzy Na stronie głównej prezentowane są trzy najnowsze poradniki z bazy wiedzy wraz z odnośnikiem do pełnej listy. ## Kontakt i konsultacja Skontaktuj się i otrzymaj bezpłatną konsultację. === PODSTRONA: USŁUGI === # Nasze usługi Kompleksowe rozwiązania dla Twojej infrastruktury IT. Od doraźnej pomocy po pełną opiekę nad serwerami. ## Pakiety usług ### Szybka pomoc Doraźna interwencja przy awariach i problemach z serwerami Linux. Reakcja, diagnoza, naprawa i raport. ### Linux SRV Pełna opieka nad serwerem z monitoringiem 24/7 i wsparciem DevOps. Monitoring, aktualizacje, backup, powiadomienia SMS/email. ### Linux MIN Podstawowa opieka z aktualizacjami i wsparciem. Idealny dla małych projektów i środowisk deweloperskich. ## Specjalizacje Monitoring proaktywny 24/7, Migracja aplikacji, Kopie zapasowe, Bezpieczeństwo. === PODSTRONA: O NAS === # O nas LinuxLab to zespół doświadczonych administratorów i inżynierów DevOps. Pomagamy w zarządzaniu infrastrukturą serwerową i zapewnianiu bezpieczeństwa, wydajności oraz ciągłości działania. ## Misja Dostarczanie profesjonalnych usług administracyjnych pozwalających klientom skupić się na biznesie. ## Doświadczenie i wartości Ponad dekada doświadczenia, 24/7 wsparcie techniczne, uptime gwarantowany. ## Technologie Linux, Docker, Kubernetes, Ansible, Terraform, Prometheus, Grafana, Jenkins, Git, PostgreSQL, Redis. ## Proces współpracy 1. Konsultacja 2. Analiza infrastruktury 3. Wdrożenie monitoringu i zabezpieczeń 4. Ciągła opieka i monitoring 24/7. === PODSTRONA: CENNIK === # Cennik Przejrzyste ceny bez ukrytych kosztów. ## Pakiety: - Szybka pomoc: 350 PLN za interwencję. - Linux SRV: 1400 PLN / miesiąc (1190 PLN z roczną zniżką). - Linux MIN: 500 PLN miesięcznie (425 PLN z roczną zniżką). ## Usługi dodatkowe: Migracja serwera, Audyt bezpieczeństwa, Konfiguracja SSL, Optymalizacja wydajności, Dodatkowy backup, Konsultacja DevOps. ## FAQ: Szybki start współpracy, zmiana pakietu, rozliczenia miesięczne/roczne, VAT. === PODSTRONA: KONTAKT === # Kontakt ## Dane kontaktowe Telefon: 780 006 792 Email: info@linuxlab.pl Godziny pracy: Pon–Pt 8:00–18:00 Odpowiedź w ciągu 24h Awarie: dostępne 24/7 dla klientów z pakietem SRV. ## Formularz kontaktowy Kreator zgłoszenia z wyborem usługi, szczegółami problemu oraz danymi kontaktowymi. ## Lokalizacja Działamy zdalnie – obsługa klientów w całej Polsce. === PODSTRONA: BAZA WIEDZY (BIURO PRASOWE) === # Baza wiedzy Praktyczne poradniki o administracji serwerami Linux, DevOps i automatyzacji. Dzielimy się tym, czego używamy na co dzień w opiece nad infrastrukturą klientów. ## Artykuł: Lab do testów na Terraform i OpenTofu: powtarzalne maszyny wirtualne na KVM Data: 10 września 2026. Kategoria: Automatyzacja i DevOps. Autor: Zespół LinuxLab. Budowa labu z czterema systemami testowymi (Debian 12, Debian 13, Ubuntu 24.04 LTS, Ubuntu 26.04 LTS) opisanego kodem, na libvirt/KVM. Opis realnie używanego labu LinuxLab. Podział ról: Terraform dostarcza PUSTE maszyny (procesor, pamięć, dysk, sieć, konto, klucz). Zawartość dokłada druga warstwa - narzędzie do zarządzania konfiguracją. Lab jest kompletny dopiero razem, a obie warstwy mają inny cykl życia. Artykuł opisuje wyłącznie warstwę Terraform. Koszt sprzętu: lab nie wymaga serwera. Zmierzone zapotrzebowanie czterech maszyn to 8 GiB pamięci (tylko gdy wszystkie działają naraz), 40 GiB na dyski i 6 GiB na obrazy bazowe, razem ok. 46 GiB. Opisywany lab DZIAŁA na ThinkPadzie T490 (38 GiB pamięci, 8 wątków - odczytane z danych identyfikacyjnych płyty), obsługując przy tym także maszyny usługowe; przy 16 GiB uruchamia się 2-3 maszyny, przy 24 GiB wszystkie cztery. Maszyny zwykle stoją wyłączone i wtedy nie kosztują ani pamięci, ani procesora. Sens własnego labu to zniesiona blokada przed eksperymentem: można zepsuć zaporę, wykasować zły katalog, zrobić aktualizację między wydaniami - i odtworzyć maszynę jednym poleceniem. Terraform kontra OpenTofu: OpenTofu to odgałęzienie Terraform po zmianie licencji na BUSL, rozwijane pod Linux Foundation. Sprawdzone: ta sama konfiguracja bez żadnej zmiany przechodzi init i validate pod Terraform 1.16.1 oraz OpenTofu 1.12.6. Jedyna różnica to host rejestru w pliku blokady (registry.terraform.io kontra registry.opentofu.org); provider dmacvicar/libvirt 0.8.3 jest w obu. Przełączenie całego labu to zmiana jednej zmiennej (TF=tofu w Makefile). Nie należy mieszać obu narzędzi na tym samym stanie. Architektura: dwa katalogi główne z OSOBNYMI stanami - base/ (pula obrazów, obrazy bazowe, sieć NAT lab 192.168.123.0/24 z DHCP i DNS) oraz testboxes/ (maszyny). Powód: kasowanie maszyn nie rusza obrazów, które waża gigabajty. Katalog maszyn czyta identyfikatory obrazów i nazwę sieci z base/ przez terraform_remote_state. Definicja maszyny leży raz w module modules/vm-group. Kolejność: base buduje się PIERWSZY, kasuje OSTATNI. Wersje deklarowane wprost: required_version >= 1.3, provider dmacvicar/libvirt = 0.8.3. Zapis ~> 0.8 wpuszcza serię 0.9 (istnieją 0.9.0-0.9.9) i zepsuł walidację bez zmian po naszej stronie. Katalog systemów trzyma pełne URL-e, bo Debian wstawia datę do katalogu I do nazwy pliku, a Ubuntu tylko do katalogu. enabled_distros musi pokrywać wszystkie systemy używane przez maszyny. Maszyny: jedna mapa vms, wiersze krótkie dzięki optional() w typie obiektu (domyślnie 2 rdzenie, 2048 MiB, 10 GiB, sieć lab, autostart false). Pole group pozwala pracować na podzbiorze przez only_groups - filtr na wejściu zamiast wskazywania zasobów z linii poleceń. wait_for_lease=false przyspiesza tworzenie, ale narzędzie nie zna wtedy adresów. cloud-init: hostname, konto z sudo NOPASSWD, klucz publiczny, pakiety qemu-guest-agent (host odczytuje IP gościa), python3 (Ansible), sudo, curl. package_upgrade: false celowo - maszyna ma wstawać szybko i w stanie zgodnym z obrazem. final_message na konsoli szeregowej jest pierwszą informacją diagnostyczną, gdy maszyna "nie wstaje". GŁÓWNA PUŁAPKA (przyczyna i fix): provider 0.8.3 przy disk { file = ... } wpisuje do opisu maszyny , IGNORUJĄC rzeczywisty format pliku. Obrazy chmurowe są qcow2, więc firmware czyta nagłówek qcow2 tam, gdzie spodziewa się tablicy partycji - SeaBIOS mówi "not a bootable disk", OVMF ląduje w powłoce UEFI. qemu-img i fdisk działały, bo same wykrywają format; virt-install bootował, bo wpisuje format poprawny. FIX: obraz bazowy ma być RAW (qemu-img convert -O raw), provider dziedziczy format ze źródła, a maszyny tworzy się z disk_strategy="copy". Obrazy raw trzymać w katalogu TRWAŁYM, nie /tmp. Koszt: raw zajmuje pełne miejsce, stąd 4 maszyny = równe 40 GiB. Poboczne: warstwa CoW potykała się o AppArmor (brak pliku bazowego na liście), a cloud-init jako napęd optyczny nie działa na q35 - podpinany jest jako zwykły dysk virtio. Powtarzalność: obraz "najnowszy" kontra z konkretnego dnia - ta sama decyzja co przy wersji providera. GOTCHA: serwery Debiana usuwają stare zrzuty po kilku tygodniach, więc adres sprzed pół roku zwróci błąd. Operacje dnia drugiego: odtworzenie jednej maszyny wymaga -replace na TRZECH zasobach naraz (vm_disk, vm_init, vm) - sam dysk bez konfiguracji startowej da stary klucz i nazwę hosta; powiększenie dysku tylko w górę; make ssh-config generuje ~/.ssh/config-lab z adresami odczytanymi najpierw przez agenta gościa, bo DNS gości bywa zawodny. Plik jest nadpisywany w całości, a wpisy celowo nie sprawdzają kluczy hostów - ustępstwo tylko dla labu. Sprzątanie w kolejności odwrotnej: najpierw maszyny, na końcu base. Sieć domyślna hosta nie jest zarządzana. CZEGO TEN KOD NIE ROBI (warunki wstępne pierwszego uruchomienia): (1) nie przygotowuje hosta - libvirt, QEMU, firmware UEFI i grupa uprawniająca muszą już być; (2) pula na dyski VM musi ISTNIEĆ - zarządzana jest tylko pula na obrazy systemów, bo tamta jest wspólna z maszynami spoza labu; (3) konwersja obrazów do formatu surowego dzieje się poza Terraformem, ręcznym skryptem, bez celu w Makefile; (4) NAJBARDZIEJ PODSTĘPNE - reguły ignorowania w repozytorium wykluczają wszystkie pliki ze zmiennymi oraz katalog z obrazami surowymi. Sprawdzone na świeżym klonie: nie ma ani pliku wskazującego obrazy surowe, ani ustawiającego pełną kopię dysku, ani samych obrazów. Lista maszyn ma wartość domyślną, więc polecenie wykona się BEZ OSTRZEŻENIA, sięgając po domyślne qcow2 z Internetu i dysk jako warstwę - czyli dokładnie kombinację dającą maszyny niebootujące. Wnioski ogólne: reguły ignorowania przeglądać pod kątem konfiguracji, nie tylko sekretów i stanu (ratunkiem są wersje przykładowe w repo); test odtwarzalności robić na CZYSTEJ maszynie, bo na roboczej wszystko zadziała niezależnie od zawartości repozytorium. Braki dotyczą PIERWSZEGO uruchomienia - codzienne odtwarzanie maszyny działa bez zastrzeżeń. PELNE ODTWORZENIE — ZMIERZONE 2026-09-10: lab zostal skasowany i zbudowany od nowa. Kasowanie maszyn (19 zasobow) i warstwy bazowej (14 zasobow) natychmiastowe; odbudowa warstwy bazowej 70 s; odbudowa szesciu maszyn 205 s; start i cloud-init ok. 2 min. Od pustego miejsca do maszyn, na ktore mozna sie zalogowac: OKOLO SZESCIU MINUT. Najdluzszy krok to odbudowa maszyn - widac koszt formatu raw (kazdy dysk to pelna kopia). Po odbudowie adresy DHCP sa inne, wiec trzeba odswiezyc plik konfiguracji SSH; logowanie po nazwie maszyny potwierdzone. Zastrzezenie: to byl host z zainstalowanym libvirt, gotowymi obrazami raw i plikami ze zmiennymi - zmierzony jest cykl skasuj/odbuduj, a nie postawienie labu na maszynie, ktora nigdy go nie widziala. DEB11 JAKO PRZYKLAD (nieplanowane znalezisko z tej odbudowy): piec z szesciu maszyn zakonczylo cloud-init czysto, Debian 11 zglosil status: error. Przyczyna: "Release file for .../bullseye-security/InRelease is expired (invalid since 2d 16h 44min 11s)" - plik z podpisem repozytorium bezpieczenstwa wygasl dwa dni wczesniej, bo wydanie wypadlo ze wsparcia i nikt go juz nie odswieza. Maszyna wstala i wpuscila po SSH (konto i klucz powstaja przed instalacja pakietow), ale krok apt-get update zwrocil kod 100 i cala konfiguracja startowa dostala status bledu. Wniosek: jesli cloud-init ma wlaczone odswiezanie listy pakietow, to ODTWORZENIE MASZYNY JEST ZARAZEM TESTEM, CZY JEJ SYSTEM NADAL ZYJE - i pierwsza osoba, ktora sie o tym dowiaduje, jest maszyna testowa, a nie serwer klienta. Ograniczenia: to lab, nie miniatura produkcji; stan w pliku lokalnym nie nadaje się dla zespołu; opis dotyczy providera 0.8.3; format raw zajmuje pełne miejsce; konfiguracja startowa działa tylko przy pierwszym uruchomieniu; lab nie zastępuje etapu przejściowego. ## Artykuł: AWX na k3s: instalacja, pierwszy job i bezpieczna eksploatacja Data: 10 września 2026. Kategoria: Automatyzacja i DevOps. Autor: Zespół LinuxLab. Powtarzalna instalacja pojedynczej instancji AWX na jednej maszynie wirtualnej z k3s. Wszystkie liczby pochodzą z instancji AWX działającej w labie LinuxLab i realnie używanej, a nie z maszyny postawionej na potrzeby tekstu. Lab celowo stoi w sieci prywatnej, bez publicznego DNS i bez ruchu z Internetu do portów 80/443 - stąd jedyny test, którego nie dało się domknąć, to wydanie certyfikatu z Let's Encrypt. Zadeklarowanie wersji oznacza wpisanie dokładnego numeru zamiast etykiety latest: obrazy pobiera się po tagu, a latest znaczy "to, co akurat najnowsze", więc to samo polecenie może dziś i za miesiąc pobrać inny obraz. Przy AWX deklaruje się dwie wersje, bo operator i aplikacja wydawane są osobno. AWX to otwarty projekt sponsorowany przez Red Hat (Apache 2.0) i upstream komponentu automation controller - tego, co wcześniej nosiło nazwę Ansible Tower - w komercyjnym Red Hat Ansible Automation Platform. Jest darmowym odpowiednikiem płatnego produktu, ale nie jego klonem: zależność biegnie odwrotnie, bo automation controller powstaje z wybranych wydań AWX, utwardzonych pod długoterminowe wsparcie (model jak Fedora i RHEL). AWX ma nowe buildy mniej wiecej co dwa tygodnie, wsparcie wyłącznie społecznościowe i bez płatnego wsparcia Red Hata; etykieta "stable" nie oznacza przydatności produkcyjnej, a na pytanie, czy Red Hat rekomenduje AWX na produkcję, FAQ projektu odpowiada: nie. AWX nie jest Ansiblem zainstalowanym na serwerze: zadanie wykonuje się w execution environment (kontenerze), a nie w ansible-core na maszynie z k3s, więc klucze SSH i kolekcje muszą być dostępne dla AWX i jego EE, a nie w ~/.ssh użytkownika. Stan zmierzony na maszynie testowej: Ubuntu 24.04.4, 4 vCPU, 7,7 GiB RAM; k3s v1.34.3+k3s3 z containerd 2.1.5; domyślna StorageClass local-path i IngressClass traefik; AWX Operator 2.19.1, AWX 24.6.1, baza z obrazu quay.io/sclorg/postgresql-15-c9s; PVC bazy 8 GiB w stanie Bound; /api/v2/ping/ zwraca HTTP 200 i wersję 24.6.1. Artykuł prowadzi krok po kroku od pustej maszyny wirtualnej: cała droga ma osiem kroków, każdy z jawnym dowodem wykonania. Wymagania maszyny zestawione są z minimum k3s z dokumentacji (2 rdzenie i 2 GB dla węzła serwera) i z tym, co realnie wzięto dla AWX: 4 rdzenie, 8 GiB RAM, 40 GiB dysku, Ubuntu 24.04 LTS. Pokazane jest tworzenie maszyny z obrazu chmurowego przez cloud-init (user-data, meta-data, seed.iso przez genisoimage) i virt-install z --dry-run do walidacji parametrów, a także cztery kontrole gotowości przed instalacją k3s: system i zasoby, synchronizacja zegara, sudo oraz wyjście na zewnątrz do get.k3s.io, quay.io i github.com - przy czym quay.io/v2/ poprawnie zwraca 401, bo pytamy o punkt wejścia rejestru bez logowania. Pułapka operatora 2.19.1: upstreamowy manifest wskazuje gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0, a obraz został wycofany - zapytanie o manifest zwraca 404 MANIFEST_UNKNOWN, a lista tagów całego repozytorium jest pusta. Obejście: podmiana w Kustomize na quay.io/brancz/kube-rbac-proxy:v0.15.0 (macierzyste repozytorium projektu, ta sama wersja), zapisana jawnie w kustomization.yaml i potwierdzona renderem: kubectl kustomize operator | grep dwóch obrazów musi zwrócić dwie linie. Render zawiera też obiekt Namespace, cztery CRD i wdrożenie kontrolera. Sekrety: hasło administratora i SECRET_KEY tworzone jawnie jako Kubernetes Secrets przed wdrożeniem, bo SECRET_KEY szyfruje poświadczenia w bazie i odtworzenie bazy z nowym kluczem uniemożliwia ich odszyfrowanie. Pole garbage_collect_secrets ma domyślnie false, więc usunięcie zasobu AWX nie kasuje sekretów - ta wartość domyślna działa na korzyść administratora. Manifest AWX przechodzi kubectl apply --dry-run=server wobec CRD operatora 2.19.1: image_version 24.6.1, service_type ClusterIP, ingress_type ingress, ingress_class_name traefik, ingress_hosts z hostname i tls_secret, postgres_storage_class local-path, postgres_storage_requirements 8Gi, postgres_data_volume_init true. Pole auto_upgrade ma domyślnie true - upgrade operatora pociąga za sobą upgrade instancji AWX, więc podbicie operatora nie jest odizolowanym krokiem. Enum service_type: LoadBalancer/ClusterIP/NodePort; enum ingress_type: none/Ingress/ingress/Route/route; pola hostname i ingress_tls_secret są przestarzałe. Kolejność wdrożenia: najpierw operator i CRD, potem zasób AWX - nie w jednym apply -k. Ingress i TLS sprawdzone osobno: Ingress klasy traefik z sekretem TLS zwraca po HTTPS 200 i odpowiedź AWX, nieznany Host zwraca 404 z Traefika. Pułapka: HTTP na porcie 80 nadal zwraca 200 i pełną odpowiedź aplikacji, bo Traefik w k3s nie ma domyślnego przekierowania na HTTPS. Naprawa: zasób Middleware traefik.io/v1alpha1 z redirectScheme (scheme https, permanent true) plus adnotacja traefik.ingress.kubernetes.io/router.middlewares o postaci NAMESPACE-NAZWA@kubernetescrd - po niej port 80 zwraca 301, a HTTPS nadal 200. W operatorze przekazuje się to polem ingress_annotations, które w CRD jest typu string, więc wymaga bloku YAML. Execution environment: świeża instalacja AWX 24.6.1 rejestruje trzy globalne EE - AWX EE (24.6.1) i Control Plane Execution Environment na quay.io/ansible/awx-ee:24.6.1 oraz AWX EE (latest) na quay.io/ansible/awx-ee:latest. Ustawienie DEFAULT_EXECUTION_ENVIRONMENT jest puste, więc zadanie bez jawnie wskazanego środowiska poszło na AWX EE (latest) i pobrało obraz latest. Oba obrazy różnią się w cache węzła (696 MB kontra 469 MB), dlatego EE deklaruje się jawnie w job template albo buduje własny obraz przez ansible-builder. Weryfikacja wykonania: pojedyncze zadanie doraźne (ad-hoc) z modułem ping zakończyło się stanem successful po 85,0 s (z pierwszym pobraniem obrazu EE), kolejne dwa - już z obrazem w cache - poniżej 4 s. Test używał ansible_connection: local, czyli Ansible wykonał moduł wewnątrz kontenera zamiast łączyć się przez sieć, a poświadczenie Machine było puste; dlatego dowodzi tylko wewnętrznego łańcucha AWX (kolejka, przydział, uruchomienie poda, wykonanie kodu), a nie działania klucza SSH, repozytorium, DNS ani uprawnień na docelowych serwerach. KAŻDE zadanie dostaje własny pod o nazwie automation-job--, usuwany po zakończeniu - sprawdzono to dwoma zadaniami uruchomionymi naraz, powstały dwa niezależne pody. Grupy instancji: controlplane ma jedną instancję i pojemność 79, default zero instancji i 0, ale zerowa pojemność nie jest usterką - default jest grupą kontenerową (is_container_group), nie ma stałych instancji, tylko tworzy pod na każde zadanie, i to do niej trafiają zadania. Pojemność 79 to wyliczana przez AWX liczba równoległych procesów Ansible: 4 rdzenie dały 16, 7,7 GiB pamięci dało 79, AWX przyjął wyższą. Na jednej maszynie pody zadań i tak konkurują z AWX o ten sam procesor i pamięć, więc granicą są zasoby maszyny, a nie liczba instancji. Pierwszy realny dowód działania daje playbook ping.yml uruchomiony z Job Template na dedykowanym hoście testowym: potwierdza projekt, inventory, poświadczenie, start poda EE, połączenie SSH i wykonanie modułu. Ograniczenia aktualizacji: podnoszenie wersji AWX jest przewidziane wyłącznie dla instalacji przez awx-operator na Kubernetesie, a bezpośrednie aktualizacje "w miejscu" między wcześniejszymi wersjami AWX nie są wspierane - przy zaległości kilku wydań planuje się ciąg kroków przez wersje pośrednie, każdy zaczynany backupem. Artykuł zawiera słownik pojęć (AWX, operator, CRD, CR, EE, job template, SECRET_KEY, Ingress), diagram przepływu, tabelę obiektów AWX z częstymi błędami (Machine kontra Source Control credential, projekt z Git kontra katalog z laptopa), tabelę diagnostyczną od objawu do dowodu, sekcję o backupie (backup bazy nie wystarcza - musi obejmować SECRET_KEY; zasoby AWXBackup i AWXRestore; projects_persistence domyślnie false), listę ograniczeń oraz checklistę wdrożenia. Nie zostało sprawdzone: wydanie certyfikatu Let's Encrypt (brak publicznego DNS i portów 80/443), instalacja od zera jednym przebiegiem, połączenie SSH z EE do rzeczywistych hostów oraz przebieg odtworzenia z AWXBackup/AWXRestore - te punkty są w artykule nazwane wprost. ## Artykuł: Hardening usług systemd dla Nginx, PHP-FPM i MariaDB Data: 8 września 2026. Kategoria: Bezpieczeństwo. Autor: Zespół LinuxLab. Izolacja procesów trzech usług stosu LEMP przez drop-iny systemd w /etc/systemd/system/NAZWA.service.d/60-hardening.conf, bez edycji plików pakietu. Sandbox systemd obejmuje proces usługi i jego potomków, więc ograniczenia Nginx nie dotyczą procesu PHP-FPM; każda usługa potrzebuje własnego profilu. Hardening nie zastępuje aktualizacji, uprawnień plików i kont bazy, firewalla, kopii zapasowych, ochrony aplikacji ani monitoringu. Inwentaryzacja przed zmianą: systemctl list-unit-files --type=service 'php*-fpm.service', systemctl cat, systemctl show -p FragmentPath -p DropInPaths, systemd-delta oraz systemd-analyze security jako punkt odniesienia (wynik exposure jest wskazówką, nie dowodem bezpieczeństwa). Sześć pytań kontrolnych: katalogi zapisu po restarcie, socket/PID/pliki tymczasowe w /tmp, /var/tmp, /home lub /run/user, mail() uruchamiające lokalny program pocztowy, PCRE JIT w Nginx i OPcache JIT w PHP, replikacja i nietypowy datadir bazy, zakres dostępu sieciowego do bazy. Wspólna warstwa bazowa: ProtectSystem=full, PrivateTmp, PrivateDevices, ProtectKernelTunables, ProtectKernelModules, ProtectKernelLogs, ProtectControlGroups, ProtectClock, ProtectHostname, RestrictRealtime, RestrictNamespaces, RestrictSUIDSGID, LockPersonality, SystemCallArchitectures=native - z opisem, co każda dyrektywa robi, przed czym chroni i czego nie robi. Ustawienia warunkowe osobno dla Nginx (NoNewPrivileges, RestrictAddressFamilies, MemoryDenyWriteExecute kontra PCRE JIT, CapabilityBoundingSet z omówieniem CAP_NET_BIND_SERVICE, CAP_SETUID, CAP_SETGID, CAP_KILL, CAP_CHOWN i szerokiego CAP_DAC_OVERRIDE), dla PHP-FPM (mail() z bitem setuid, OPcache JIT, ProtectHome przy docroot pod /home) oraz dla MariaDB (CapabilityBoundingSet=~CAP_SYS_ADMIN, ProtectSystem=strict z ReadWritePaths=/var/lib/mysql i /run/mysqld, secure_file_priv, IPAddressDeny/IPAddressAllow, odradzone PrivateNetwork i DynamicUser). ProtectSystem=full nie czyni /var/www tylko do odczytu; ProtectSystem=strict wymaga wąskiej listy ReadWritePaths, a wpis ReadWritePaths=/var oddaje większość ochrony. Studium przypadku: jeden vhost, sklep Magento pod example.test/ i blog WordPress pod example.test/news/ w osobnych katalogach, z konfiguracją Nginx opartą na location ^~ /news/, alias, zagnieżdżonej obsłudze PHP, blokadach wp-config.php i skryptów PHP w wp-content/uploads oraz include nginx.conf.sample Magento. Prefiks URL nie jest granicą bezpieczeństwa systemu operacyjnego, a wspólny master PHP-FPM oznacza wspólny sandbox: ReadWritePaths obejmuje sumę potrzeb obu aplikacji, więc rozdział wymaga osobnych masterów i jednostek systemd. Wdrożenie: kolejność Nginx, każda jednostka PHP-FPM, na końcu MariaDB; daemon-reload nie zakłada nowego sandboxa (robi to dopiero restart lub try-restart); walidacja przez systemd-analyze verify, systemctl cat i systemctl show; testy funkcjonalne aplikacji zamiast samego kodu HTTP 200; wycofanie przez zmianę nazwy dodanego pliku na .disabled zamiast systemctl revert, który usuwa też inne lokalne nadpisania. Restart=on-failure i RestartSec opisane jako dostępność, nie hardening; MemoryHigh, MemoryMax, TasksMax i CPUQuota bez wartości przykładowych. Artykuł zawiera checklistę wdrożenia i listę ograniczeń podejścia. ## Artykuł: Jak zapisać aktualny stan strony w GitHub bez przenoszenia historii Data: 20 sierpnia 2026. Kategoria: Automatyzacja i DevOps. Autor: Zespół LinuxLab. Praktyczny proces przeniesienia gotowej strony do wspólnego repozytorium jako jednego, aktualnego snapshotu źródeł. W repozytorium docelowym znajdują się pliki potrzebne do odtworzenia obecnej wersji: strony, zasoby, generator i jego jawne dane wejściowe. Lokalny katalog .git i wcześniejsza historia pozostają poza tym procesem; nie są kasowane ani przepisywane. Zakres wykluczeń obejmuje backup poprzedniego CMS-a, bazy danych, cache, logi, pliki tymczasowe, konfigurację formularza, tokeny, pliki .env i klucze prywatne. Opisany jest bezpieczny szablon .gitignore, kopiowanie przez rsync z --dry-run i --delete używanym wyłącznie po sprawdzeniu katalogu docelowego, a także kontrola przed commitem: git status --short, git diff --cached --name-status, --stat, --check oraz git check-ignore -v. Push do GitHub nie jest automatycznie deployem: wdrożenie i weryfikacja HTTP stanowią osobny, kontrolowany krok. Wszystkie nazwy w przykładach są fikcyjne i nie identyfikują żadnej infrastruktury. ## Artykuł: Ansible od podstaw: playbooki, role, idempotencja i Vault Data: 16 czerwca 2026. Kategoria: Automatyzacja i DevOps. Autor: Zespół LinuxLab. W LinuxLab korzystamy z Ansible, aby przyspieszać i automatyzować powtarzalne zadania administracyjne, co przekłada się na skuteczne zapobieganie awariom serwerów. Omawiane pojęcia: czym jest Ansible (agentless, SSH, deklaratywność), inventory, playbooki, taski i moduły, idempotencja (z trybem check/dry-run), zmienne i fakty, szablony Jinja2, handlery, role (struktura katalogów, ponowne użycie) oraz Ansible Vault (szyfrowanie sekretów). Artykuł zawiera praktyczne przykłady kodu YAML. ## Artykuł: Terraform od podstaw: providery, stan, zmienne i moduły Data: 16 czerwca 2026. Kategoria: Automatyzacja i DevOps. Autor: Zespół LinuxLab. W LinuxLab korzystamy z Terraform, aby przyspieszać i automatyzować powtarzalne zadania związane z infrastrukturą (provisioning), co przekłada się na skuteczne zapobieganie awariom serwerów. Omawiane pojęcia: czym jest Terraform (IaC, deklaratywność, niezależność od dostawcy), język HCL, providery, zasoby i data sources, stan (state) i backend zdalny z blokadą, cykl pracy init/plan/apply, zmienne i outputy, moduły (ponowne użycie), idempotencja i graf zależności, bezpieczeństwo sekretów oraz jak Terraform i Ansible uzupełniają się (Terraform tworzy infrastrukturę, Ansible ją konfiguruje). Przykłady kodu w HCL. ## Artykuł: WordPress na Nginx + PHP-FPM + MariaDB + Certbot (Debian 13) Data: 17 czerwca 2026. Kategoria: Serwery i hosting. Autor: Zespół LinuxLab. Skrótowy przegląd (wstęp do serii) uruchomienia kompletnego stacku LEMP pod WordPressa na czystym Debianie 13 (Trixie): aktualizacja systemu, instalacja Nginx, PHP-FPM (PHP 8.4 z rozszerzeniami), MariaDB (baza + dedykowany użytkownik), pobranie i konfiguracja WordPressa, vhost Nginx spinający PHP-FPM przez gniazdo, oraz darmowy certyfikat SSL Let's Encrypt przez Certbot (--nginx, auto-odnawianie). Każdy komponent dostanie osobny, szczegółowy wpis. Przykłady poleceń powłoki i konfiguracji Nginx. ## Artykuł: Zaawansowany Nginx na Debianie 13: HTTP/2, PHP-FPM, Redis, Memcached i rate limiting Data: 17 czerwca 2026. Kategoria: Serwery i hosting. Autor: Zespół LinuxLab. Głębsze rozwinięcie wpisu o LEMP. Wydajna, produkcyjna konfiguracja Nginx na konkretnym przykładzie, z odpowiedzią "po co tak używać?" dla każdego dodatku i aspektem bezpieczeństwa: HTTP/2 (dyrektywa http2 on; tylko po TLS/ALPN), PHP-FPM (osobne pule per strona, izolacja, open_basedir, disable_functions), Redis (cache obiektów i sesje PHP; bind localhost, requirepass, protected-mode, rename-command), Memcached (ulotny wielowątkowy cache; -l 127.0.0.1, -U 0 przeciw DDoS amplification). Ograniczanie ruchu: ngx_http_limit_req (limit_req_zone, rate, burst, nodelay - ochrona logowania/brute-force) oraz ngx_http_limit_conn (limit_conn_zone, limit równoczesnych połączeń - ochrona przed slowloris). Bezpieczeństwo przekrojowe: server_tokens off, nagłówki HSTS/X-Content-Type-Options/X-Frame-Options, blokada plików ukrytych, usługi cache i baza tylko na localhost. Pełny przykład vhosta z konfiguracją limitów w kontekście http. ## Artykuł: Jak znaleźć obciążające zapytania MySQL/MariaDB i dodać właściwy indeks Data: 15 lipca 2026. Kategoria: Bazy danych. Autor: Zespół LinuxLab. Praktyczny przewodnik po diagnostyce MariaDB: SHOW FULL PROCESSLIST, EXPLAIN, rozmiary tabel, liczniki InnoDB, iowait i analiza kodu aplikacji. Artykuł wyjaśnia dobór indeksu złożonego dla pobrania ostatniego wpisu historii oraz indeksu unikalnego UUID poprzedzonego kontrolą duplikatów. Pokazuje wdrożenie przez ALGORITHM=INPLACE i LOCK=NONE, walidację planów po zmianie oraz sposób oceny innodb_buffer_pool_size względem danych, indeksów i pamięci RAM. ## Artykuł: Z iptables na nftables na Debianie 13: praktyczne tłumaczenie reguł Data: 10 sierpnia 2026. Kategoria: Bezpieczeństwo. Autor: Zespół LinuxLab. Przewodnik migracji firewalla na Debianie 13 (Trixie). Punkt wyjścia: w Debianie polecenie iptables jest dowiązaniem do iptables-nft, więc reguły i tak trafiają do nftables - sprawdzenie przez iptables --version (nf_tables vs legacy) i update-alternatives --display iptables. Inwentaryzacja przed zmianą: iptables-save, ip6tables-save, nft list ruleset oraz ustalenie, kto ładuje reguły po restarcie (netfilter-persistent i /etc/iptables/rules.v4 kontra nftables.service i /etc/nftables.conf, nakładki ufw/firewalld). Tłumaczenie automatyczne: iptables-translate dla pojedynczej reguły oraz iptables-restore-translate -f dla całego zrzutu (przekłada też polityki łańcuchów). Ograniczenia: iptables-translate -P zwraca "Translation not implemented", a -m recent nie jest tłumaczony. Słownik poleceń: iptables -L -n -v = nft list ruleset (oraz nft -a dla uchwytów i nft -s bez liczników); iptables -A INPUT -p tcp --dport 28 -j ACCEPT = nft add rule inet filter input tcp dport 28 accept; -I = insert rule; -D po numerze = delete rule ... handle N; -F = flush chain; -P = policy w definicji łańcucha; -N = add chain; -j lancuch = jump/goto; -m multiport --dports = tcp dport { 80, 443 }; -i/-o = iifname/oifname; -m conntrack --ctstate = ct state; -m limit = limit rate; -j LOG = log prefix; -j REJECT --reject-with tcp-reset = reject with tcp reset; -t nat POSTROUTING MASQUERADE = łańcuch type nat hook postrouting + masquerade; iptables i ip6tables osobno = jedna reguła w rodzinie inet; iptables-save/restore = nft list ruleset / nft -f. Struktura nftables: brak wbudowanych tabel i łańcuchów, łańcuch bazowy wymaga type/hook/priority (filter=0, srcnat=100, dstnat=-100), rodzina inet dla IPv4+IPv6, oraz zasada, że accept nie kończy przetwarzania pakietu między tabelami - ostateczne jest tylko drop. Liczniki: w nftables counter jest opcjonalny (dlatego iptables-translate go dopisuje); nft list counters, nft reset counters, diagnostyka przez meta nftrace set 1 i nft monitor trace. Zbiory i mapy: named set z flagą interval dla podsieci, nft add/delete element bez zmiany reguł, zbiór dynamiczny z timeout jako zamiennik -m recent (add @bruteforce { ip saddr limit rate over 10/minute }) - z zastrzeżeniem, że nie zastępuje fail2ban. Gotowy /etc/nftables.conf w rodzinie inet (SSH na porcie 28, WWW, ICMPv6 neighbor discovery, logowanie z limitem tempa). Wdrożenie: nft -c -f, atomowość transakcji nft -f, wyzwalacz wycofania przez setsid/sleep z potwierdzeniem z drugiej sesji SSH, systemctl enable nftables i wyłączenie netfilter-persistent, test po restarcie. Ostrzeżenie: zatrzymanie nftables.service czyści ruleset. Współistnienie: flush ruleset kasuje tabele dockera i fail2ban (inet f2b-table) - zamiast tego wzorzec ograniczony do własnej tabeli (table / delete table / table) dający idempotentny plik. ## Artykuł: Rozjazd lokalnego main z origin/main: dlaczego przewinięcie odmawia i jak to naprawić Data: 17 sierpnia 2026. Kategoria: Automatyzacja i DevOps. Autor: Zespół LinuxLab. Studium przypadku z repozytorium konfiguracji serwerów, w którym gałąź main jest źródłem prawdy dla narzędzia automatyzacji. Gałąź robocza powstała z nieodświeżanej lokalnej kopii main (4 commity za stanem zdalnym), scalenie do main wykonano wyłącznie lokalnie i nigdy nie wypchnięto, a w tym czasie origin/main otrzymał 4 inne commity. Powstał rozjazd gałęzi: git status -sb pokazywał "## main...origin/main [do przodu 1, wstecz 4]", a git merge --ff-only origin/main kończyło się komunikatem "fatal: Nie da się przewinąć, przerywanie." (ang. "Not possible to fast-forward, aborting."). Wyjaśnione pojęcia: nazewnictwo main kontra master - obie nazwy oznaczają gałąź domyślną, Git nie ma wbudowanego pojęcia "gałęzi głównej", historycznie git init tworzył master, a Git 2.28 (2020) dodał ustawienie init.defaultBranch, po czym serwisy hostujące przeszły na main (odejście od terminologii master/slave); sprawdzenie gałęzi domyślnej przez git symbolic-ref refs/remotes/origin/HEAD --short, odtworzenie przez git remote set-head origin --auto, ustawienie dla nowych repozytoriów przez git config --global init.defaultBranch main, oraz uwaga, że zmiana nazwy w istniejącym repozytorium (git branch -m master main) wymaga też przestawienia gałęzi domyślnej po stronie serwisu hostującego i odświeżenia kopii w całym zespole. Dalej: origin jako nazwa repozytorium zdalnego; różnica między gałęzią main a origin/main, która jest lokalną notatką aktualizowaną wyłącznie przez fetch/pull/push, a nie podglądem stanu serwera na żywo; git fetch (bezpieczne pobranie, nie zmienia gałęzi roboczej ani plików) kontra git pull (fetch plus scalenie); przewinięcie (fast-forward) możliwe tylko wtedy, gdy commit bieżącej gałęzi jest przodkiem commitu docelowego, oraz znaczenie przełącznika --ff-only jako świadomego zabezpieczenia, które przerywa pracę zamiast wykonać operację o innych skutkach. Dlaczego rozjazd był groźny: zmiana istniała na serwerze, ale nie w gałęzi main, z której czyta automatyzacja, więc kolejne uruchomienie automatu cofnęłoby poprawkę. Rozróżnienie czterech stanów zmiany: pliki w katalogu roboczym, commit lokalny, gałąź wypchnięta na serwer, zmiana obecna w gałęzi main na serwerze - "zatwierdzone i wysłane" to stan trzeci, automatyzacja czyta ze stanu czwartego. Diagnoza: git fetch origin, git status -sb, git log --oneline --graph --left-right main...origin/main (trzy kropki = różnica symetryczna; znak < to commity tylko po lewej stronie, znak > tylko po prawej). Naprawa: git merge origin/main tworzące commit scalający o dwóch rodzicach, git merge --abort jako bezpieczne wycofanie przy konflikcie, oraz uwaga o rebase, który daje historię liniową, ale zmienia commity i nadaje się tylko do tych jeszcze niewypchniętych. Weryfikacja: git diff --stat origin/main HEAD przed wypchnięciem (powinno pokazać dokładnie zamierzoną zmianę i nic poza nią) oraz git merge-base --is-ancestor COMMIT origin/main po wypchnięciu jako potwierdzenie stanu zdalnego nadające się do skryptów. Poprawna ścieżka: git fetch origin; git switch -c NAZWA origin/main (gałąź wprost ze stanu zdalnego); commit; git push -u origin NAZWA; git switch main; git merge --ff-only origin/main; git merge --no-ff NAZWA; git diff --stat; git push origin main; potwierdzenie przez merge-base; usunięcie gałęzi przez git push origin --delete oraz git branch -d (małe -d nie kasuje niescalonej pracy). Pułapka poboczna: gałąź bez ustawionego śledzenia (git branch -vv bez nawiasu kwadratowego) - status nie pokazuje wyprzedzenia ani opóźnienia, a push i pull bez argumentów nie mają celu; naprawa przez git branch -u origin/NAZWA. === LINKI WEWNĘTRZNE === https://linuxlab.pl/ https://linuxlab.pl/uslugi.html https://linuxlab.pl/o-nas.html https://linuxlab.pl/cennik.html https://linuxlab.pl/kontakt.html https://linuxlab.pl/baza-wiedzy.html https://linuxlab.pl/ansible-od-podstaw.html https://linuxlab.pl/terraform-od-podstaw.html https://linuxlab.pl/wordpress-lemp-debian-13.html https://linuxlab.pl/nginx-redis-memcached-http2-debian-13.html https://linuxlab.pl/mysql-mariadb-obciazajace-zapytania-indeksy.html https://linuxlab.pl/iptables-nftables-debian-13.html https://linuxlab.pl/git-rozjazd-main-fast-forward.html https://linuxlab.pl/git-import-aktualnego-stanu-do-github-bez-historii.html https://linuxlab.pl/hardening-systemd-nginx-php-fpm-mariadb.html https://linuxlab.pl/awx-na-k3s-instalacja-pierwszy-job.html https://linuxlab.pl/lab-testowy-terraform-opentofu-kvm.html