# 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