LW IT Solutions
« Przegląd bloga /Raspberry Pi / Lokalny CI/CD dla Raspberry Pi: Automatyzacja wdrożeń...
Ten artykuł w innych językach:

Lokalny CI/CD dla Raspberry Pi: Automatyzacja wdrożeń Docker Compose

Część 3 z 4 serii Homelab na Raspberry Pi

Lokalny CI/CD dla Raspberry Pi: Automatyzacja wdrożeń Docker Compose
Spis treści
  1. 1. Architektura lokalnego GitOps na urządzeniach Edge
  2. 2. Automatyzacja wdrożeń za pomocą Webhooków
  3. 3. Zarządzanie cyklem życia kontenerów bez SSH
  4. 4. Bezpieczeństwo lokalnych potoków CI/CD
  5. 5. Push zamiast pull: GitHub Actions i aktualizacje obrazów według harmonogramu
  6. Pytania i odpowiedzi
  7. Źródła

Zarządzanie skonteneryzowaną infrastrukturą na urządzeniach typu edge, takich jak Raspberry Pi, często wiąże się z koniecznością powtarzalnego logowania przez SSH, ręcznego pobierania obrazów oraz bezpośredniego wywoływania poleceń Docker Compose. Wdrożenie lokalnego potoku CI/CD umożliwia pełną automatyzację cyklu życia usług – w tym Home Assistant, Nextcloud oraz skryptów w języku Python – z wykorzystaniem repozytoriów Git, nasłuchiwaczy Webhook oraz lokalnych agentów wdrożeniowych.

1. Architektura lokalnego GitOps na urządzeniach Edge

Zastosowanie metodyki GitOps przenosi centralne źródło prawdy dla całej konfiguracji infrastruktury ze zmian wprowadzanych lokalnie w systemie plików do centralnego repozytoria Git. Zamiast bezpośredniej edycji plików YAML na serwerze, wszystkie definicje wdrożeniowe utrzymywane są pod kontrolą wersji.

  • Deklaratywna konfiguracja: Wszystkie usługi, definicje sieci oraz wolumeny trwałe są precyzyjnie definiowane w plikach docker-compose.yml przechowywanych w repozytorium kodu.
  • Pełna historia zmian i wycofania (Rollback): System kontroli wersji zapewnia niemodyfikowalny rejestr modyfikacji, co umożliwia natychmiastowe przywrócenie stabilnego stanu w przypadku wystąpienia błędów po aktualizacji.
  • Bezobsługowe wdrożenia: Serwer edge funkcjonuje jako automatyczny konsument stanu repozytorium, co eliminuje potrzebę interaktywnego dostępu do powłoki systemowej podczas rutynowych aktualizacji.
Pionowy potok CI/CD od git push przez webhook weryfikowany HMAC i git pull do docker compose i health-checków
Urządzenie brzegowe jest konsumentem, nie celem: samo pobiera stan repozytorium i doprowadza swój stos do zgodności. Kontrola HMAC jest bramą — niezweryfikowany webhook nigdy nie dociera do pobrania.

2. Automatyzacja wdrożeń za pomocą Webhooków

W celu całkowitego wyeliminowania ręcznych poleceń SSH, na platformie Raspberry Pi da się uruchomić lekkie serwery Webhook (np. adnanh/webhook lub dedykowane demony automatyzacji). Usługi te nasłuchują żądań HTTP POST generowanych przez zdarzenia typu push w repozytorium kodu lub przez zewnętrzne systemy CI/CD.

Przepływ pracy usługi Webhook

  • Weryfikacja żądań: Przychodzące wywołania są kryptograficznie sprawdzane za pomocą tokenów HMAC w celu zapobiegania nieautoryzowanemu zdalnemu uruchamianiu zadań.
  • Automatyczna synchronizacja Git: Po pomyślnej weryfikacji lokalna usługa inicjuje pobranie najnowszej wersji kodu z gałęzi głównej repozytorium.
  • Rekonwergencja stosu: Narzędzie automatyzujące wykonuje polecenie docker compose up -d --remove-orphans, dzięki czemu odtwarzane są wyłącznie zmienione obrazy kontenerów lub zmodyfikowane definicje usług.

3. Zarządzanie cyklem życia kontenerów bez SSH

Architektury ciągłego wdrażania w środowiskach self-hosted korzystają z wyspecjalizowanych agentów lokalnych, którzy monitorują rejestry obrazów i realizują procesy aktualizacji w sposób całkowicie bezobsługowy.

  • Automatyczne sprawdzanie rejestrów: Narzędzia z rodziny Watchtower cyklicznie weryfikują skróty (digesty) obrazów dla uruchomionych kontenerów i automatycznie restartują usługi, gdy dostępna jest nowa wersja. Pierwotne repozytorium containrrr/watchtower zostało zarchiwizowane w grudniu 2025 roku, a starszy projekt Ouroboros nie jest już rozwijany; utrzymywane forki społecznościowe, takie jak nickfedor/watchtower, stanowią bezpośredni zamiennik.
  • Lokalne budowanie obrazów: W przypadku własnych skryptów Python lub mikrousług lokalny mechanizm może budować pliki Dockerfile bezpośrednio na architekturze ARM, unikając złożoności kompilacji skrośnej.
  • Kontrola stanu (Health Checks): Zastosowanie natywnych testów sprawności Docker Health Check gwarantuje natychmiastowe wykrycie błędów uruchomienia nowych wersji bez konieczności ręcznego analizowania logów.

4. Bezpieczeństwo lokalnych potoków CI/CD

Udostępnianie zautomatyzowanych punktów końcowych w sieci wymagają ścisłego rygoru w zarządzaniu uprawnieniami. Demony Webhook nigdy nie powinny pracować z uprawnieniami root; dostęp do gniazda Dockera należy kontrolować poprzez dedykowane uprawnienia grupowe lub serwery proxy w trybie tylko do odczytu. Ponadto umieszczenie usług nasłuchujących w wydzielonym podsieci VLAN do zarządzania zapobiega dostępowi z nieautoryzowanych urządzeń końcowych.

5. Push zamiast pull: GitHub Actions i aktualizacje obrazów według harmonogramu

We wzorcu z webhookiem Raspberry Pi sam pobiera swój stan. Kierunek odwrotny, w którym wdrożenie uruchamia workflow CI, jest częsty w GitHub Actions i występuje w dwóch wariantach. Różnią się one przede wszystkim tym, na ile urządzenie musi być osiągalne z zewnątrz.

  • Runner hostowany przez GitHub, połączenie SSH: workflow działa w chmurze GitHub i otwiera połączenie SSH z Pi. Port SSH urządzenia musi wtedy być osiągalny z internetu, co przeczy czysto lokalnej architekturze.
  • Runner self-hosted na Pi: GitHub obsługuje runnery self-hosted na Linuksie dla architektur ARM64 i ARM32. Runner potrzebuje jedynie wychodzących połączeń HTTPS na porcie 443, więc żaden port przychodzący nie musi być otwarty. GitHub zaleca runnery self-hosted wyłącznie dla repozytoriów prywatnych, ponieważ pull request z forka repozytorium publicznego może uruchomić swój kod na maszynie z runnerem.

Ograniczenie klucza wdrożeniowego

Jeśli wariant SSH pozostaje w użyciu, klucz zapisany jako sekret repozytorium da się w pliku ~/.ssh/authorized_keys osobnego użytkownika wdrożeniowego przypiąć do jednej czynności:

restrict,command="/usr/local/bin/deploy-stack" ssh-ed25519 AAAA… ci-deploy

Opcja command= przy każdym logowaniu tym kluczem uruchamia zapisany skrypt i ignoruje polecenie przesłane przez klienta; pierwotne żądanie trafia do skryptu tylko przez zmienną środowiskową SSH_ORIGINAL_COMMAND. restrict wyłącza przekierowanie portów, agenta i X11, a także przydzielanie PTY i wykonywanie ~/.ssh/rc. Wyciek sekretu pozwala wtedy wyłącznie na wywołanie wdrożenia. Członkostwo w grupie docker nie stanowi przy tym żadnego ograniczenia: według dokumentacji Dockera grupa ta daje uprawnienia na poziomie roota.

Harmonogram aktualizacji Watchtower

Domyślnie Watchtower sprawdza dostępność nowych obrazów co 86 400 sekund (24 godziny). Stałe okno serwisowe wyznacza zmienna WATCHTOWER_SCHEDULE, czyli wyrażenie cron z sześcioma polami, w którym pierwsze pole oznacza sekundy; 0 0 4 * * * uruchamia sprawdzenie codziennie o 4:00. Harmonogram wymaga strefy czasowej ustawionej przez TZ lub zamontowany plik /etc/localtime i nie łączy się z WATCHTOWER_POLL_INTERVAL. WATCHTOWER_CLEANUP=true usuwa stare obrazy po aktualizacji, dzięki czemu karta SD lub dysk SSD nie zapełnia się z czasem. Przy WATCHTOWER_LABEL_ENABLE=true Watchtower aktualizuje tylko kontenery z etykietą com.centurylinklabs.watchtower.enable=true, więc to plik Compose decyduje, których usług narzędzie w ogóle dotyka.

Pytania i odpowiedzi

Czy przy nieudanym wdrożeniu jedyną drogą wycofania jest git revert i kolejny webhook, czy da się to zrobić szybciej?

Revert i webhook to droga właściwa, bo repozytorium pozostaje źródłem prawdy, ale trwa ona tyle, ile pełne przejście przez Git.

Szybsza jest ta sama operacja wykonana lokalnie: pobranie poprzedniej wersji pliku (git checkout <sha> -- docker-compose.yml) i ponowne uruchomienie stosu. Warunek jest jeden i łatwo o nim zapomnieć w nocy: revert musi trafić do repozytorium zaraz potem. Inaczej najbliższy push przywróci awarię, a nikt nie połączy tych dwóch zdarzeń.

Jest jeszcze trzecia rzecz, która decyduje o tym, czy wycofanie w ogóle działa: tag obrazu. Przy :latest cofnięcie pliku nie cofa obrazu, więc kontener uruchomi się z tą samą, nową zawartością. Dopiero przypięcie do konkretnego digestu sprawia, że stan sprzed godziny da się faktycznie odtworzyć, i to jest różnica między wersjonowaną konfiguracją a wersjonowanym wdrożeniem.

Homelab na Raspberry Pi

  1. Raspberry Pi 4 i 5: uruchamianie systemu z dysku SSD przez zmianę bootloadera
  2. Zasilanie awaryjne (UPS) dla Raspberry Pi 4 i 5: Top 5 urządzeń do wymagających projektów
  3. Lokalny CI/CD dla Raspberry Pi: Automatyzacja wdrożeń Docker Compose
  4. Autonomiczny serwer domowy Docker-Compose z Traefik, SSL i Watchtower
Lukas Wójcik

Lukas Wójcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Napisanie komentarza

Doświadczenia z innymi modelami i pytania o konfigurację są tu mile widziane.

Adres e-mail nie jest publikowany. Pola obowiązkowe oznaczono gwiazdką.

Artykuły i kategorie

CCTV

Śledź tę kategorię przez RSS

Cloud & AI

Wszystkie artykuły w tej kategorii (11) Śledź tę kategorię przez RSS

Data Privacy

Wszystkie artykuły w tej kategorii (18) Śledź tę kategorię przez RSS

Digital Analytics

Wszystkie artykuły w tej kategorii (58) Śledź tę kategorię przez RSS

Digital Marketing

Wszystkie artykuły w tej kategorii (37) Śledź tę kategorię przez RSS

IT & Networks

Wszystkie artykuły w tej kategorii (17) Śledź tę kategorię przez RSS

Music Production

Wszystkie artykuły w tej kategorii (16) Śledź tę kategorię przez RSS

Raspberry Pi

Śledź tę kategorię przez RSS

SaaS & Internet Earning

Artykuły w przygotowaniu

Smart Home

Wszystkie artykuły w tej kategorii (18) Śledź tę kategorię przez RSS

Tworzenie stron internetowych

Wszystkie artykuły w tej kategorii (11) Śledź tę kategorię przez RSS

Wtyczki i triki WordPress

Wszystkie artykuły w tej kategorii (13) Śledź tę kategorię przez RSS