Docker Compose w Homelab: organizacja, profile i najlepsze praktyki

Ostatnia aktualizacja: 24 2026 maja
  • Organizacja Docker Compose według profili i ról upraszcza zarządzanie laboratoriami domowymi z dziesiątkami usług.
  • Centralizacja konfiguracji w .env, korzystanie z nadpisów i wersjonowanie w Git sprawiają, że środowisko jest przenośne i łatwe do migracji.
  • Dedykowane sieci, Traefik i kontrole stanu zdrowia poprawiają bezpieczeństwo, izolację i odporność usług.
  • Monitorowanie, kontrolowane logi i automatyczne kopie zapasowe sprawiają, że homelab jest stabilną platformą w perspektywie długoterminowej.

Docker Compose Homelab

Konfiguracja nowoczesnego laboratorium domowego z kontenerami stała się ulubionym hobby wielu osób zajmujących się technologią. Docker Compose jest niemal zawsze sercem tej konfiguracji : zdefiniuj usługi w YAML, wersjonuj je za pomocą Gita i uruchom całe środowisko jednym poleceniem.

Jednak wraz z rozwojem firmy wszystko się zmienia: od dwóch lub trzech kontenerów przechodzimy do dziesiątek usług, sieci wewnętrznych, serwerów proxy odwrotnych, baz danych i serwerów CI . Wtedy pojawia się kluczowe pytanie: pojedyncza, gigantyczna instancja Docker Compose czy wiele małych plików? Jak zorganizować profile, sieci, kopie zapasowe, zabezpieczenia i dodatkowo ułatwić migrację?

Praktyczne podejście do konfiguracji Docker Compose w laboratorium domowym

Konfiguracja Homelab z Docker Compose

W praktyce osoby korzystające z Homelabs od dłuższego czasu zazwyczaj pracują z trzema różnymi modelami organizacji Compose, z których każdy ma swoje zalety i wady. Wybór odpowiedniego podejścia pozwala zaoszczędzić wiele problemów podczas skalowania lub migracji na nową maszynę.

Z jednej strony są tacy, którzy zaczynali od samodzielnych poleceń Docker Run, potem przeszli na Portainer, a w końcu na Docker Compose . To typowy scenariusz: Portainer oferuje doskonałą przejrzystość, przyjazny interfejs użytkownika, szablony itp., ale ostatecznie edycja złożonych parametrów lub migracja konfiguracji staje się uciążliwa, jeśli nie ma niczego w plikach.

Na drugim biegunie znajduje się ten, który skonsolidował wszystko w pojedynczym „mega” pliku docker-compose.yml, zdolnym do uruchomienia absolutnie wszystkich usług homelab: odwrotnego serwera proxy, multimediów, narzędzi, monitorowania, LLM, baz danych... Wszystko w jednym stosie.

Tymczasem wielu użytkowników stosuje podejście mieszane: kilka małych plików docker-compose.yml pogrupowanych według kontekstu (np. media, infrastruktura, produktywność, monitorowanie), wszystkie w tym samym repozytorium i zwykle współdzielą globalne zmienne środowiskowe.

Dość eleganckie rozwiązanie łączy oba światy: „root” docker-compose, który zawiera inne pliki (każdy w podfolderze aplikacji lub usług). W ten sposób zachowujesz globalny widok homelab, ale bez konieczności przechodzenia przez tysiącwierszowy plik YAML, którego nie da się odczytać.

Profile, grupowanie według funkcji i duże laboratoria domowe

profile docker compose homelab

Gdy liczba usług w Twoim laboratorium domowym zbliża się do 30, 40 lub 50 (w tym usług kopii zapasowych, takich jak bazy danych, pamięci podręczne czy indeksatory), kluczowe jest ich uporządkowanie. W tym miejscu z pomocą przychodzi grupowanie według funkcji oraz korzystanie z profili Docker Compose.

Bardzo powszechnym schematem jest grupowanie wszystkiego w jednym „projekcie” Compose, ale logicznie podzielonym według profili. Na przykład:

  • Profil główny:rdzeń homelab z Traefikiem jako odwrotnym serwerem proxy i dostawcą tożsamości (np. OAuth lub Authentik) w celu uwierzytelniania wszystkich aplikacji w tej samej domenie za pomocą protokołu HTTPS.
  • Profil medialnyUsługi takie jak Plex, Sonarr, Radarr, Ombi, SABnzbd czy qBittorrent, odpowiedzialne za selekcję, pobieranie i udostępnianie treści multimedialnych.
  • Profil narzędziNarzędzia takie jak Portainer, Watchtower (jeśli używane), Diun, dockcheck lub podobne służące do zarządzania kontenerami i aktualizacjami oraz monitorowania ich.
  • Profil infrastruktury/monitorowania: Traefik, cAdvisor, Prometheus, Grafana, Uptime Kuma, Dozzle i wszystko, co związane z monitorowaniem i rejestrowaniem.
  • Profile eksperymentalne lub LLM:specyficzne stosy dla LLM lub ciekawych aplikacji (ChatGPT Next Web local, LibreOffice Online itp.), które są zazwyczaj domyślnie wyłączone.

Zaletą profili jest to, że można wdrożyć tylko część infrastruktury w razie potrzeby. Na przykład, można uruchomić tylko profil „rdzeń + infrastruktura” na energooszczędnym minikomputerze, a profil „media” wdrożyć tylko na dużym serwerze z większą liczbą dysków i procesorów graficznych.

W dobrze zaprojektowanych repozytoriach zazwyczaj znajduje się w katalogu głównym plik „docker-compose.yml”, który za pomocą polecenia include przesyła poszczególne pliki do folderu apps/ lub services/ . Ponadto prawie wszystkie usługi są konfigurowane za pomocą jednego globalnego pliku .env, a niektóre sekrety są przechowywane w katalogu secrets/ , co znacznie upraszcza początkową konfigurację.

Zgodnie z tym schematem, zarządzanie homelabem sprowadza się zasadniczo do edycji pliku .env i sekretów, włączania lub wyłączania profili oraz decydowania, które usługi mają zostać uruchomione na każdym hoście . Jest to idealne rozwiązanie, jeśli zamierzasz wdrożyć ten sam zestaw aplikacji na wielu maszynach.

Jeden gigantyczny plik docker-compose kontra kilka małych plików

Struktura plików Docker Compose Homelab

To odwieczna debata: jeden plik docker-compose.yml zawierający wszystko, czy wiele plików dla każdej usługi/stosu? Prawdziwa odpowiedź brzmi zazwyczaj: „to zależy od tego, co chcesz priorytetowo traktować: prostotę migracji czy przejrzystość dla każdej usługi”.

Zwolennicy jednolitego pliku głównego zazwyczaj podkreślają kilka zalet:

  • Migracja hostów jest superłatwaKlonujesz repozytorium, kopiujesz plik .env i sekrety, montujesz woluminy i uruchamiasz polecenie `docker compose up -d`. Nie ma potrzeby przechodzenia katalog po katalogu.
  • Infrastruktura jako kodeks prawdy:cała topologia homelaba (usługi, sieci, woluminy, zależności) znajduje się w jednym miejscu.
  • Centralne aktualizacje:zmieniasz wersję obrazu, zasady ponownego uruchamiania lub jakieś rejestrowanie i dokładnie wiesz, gdzie tego dokonać.
  Bezpieczeństwo w systemach operacyjnych: porady i zalecenia

Ale ma też oczywiste wady: ogromny plik YAML jest trudniejszy w utrzymaniu, konflikty przy scalaniu nasilają się, a podczas debugowania konkretnego problemu napotykamy monstrum setek wierszy. Nierzadko odczuwamy lekki żal, gdy wszystko staje się zbyt duże.

Innym podejściem jest posiadanie pliku docker-compose.yml dla każdej aplikacji lub stosu logicznego w ramach takiej struktury:

docker/
├── bookstack/
│   └── docker-compose.yml
├── dashy/
│   └── docker-compose.yml
└── traefik/
    └── docker-compose.yml

Dzięki temu każdy kontener będzie miał nazwę taką jak bookstack-app-1 lub traefik-reverse-proxy-1 , co pozwoli Ci szybko zlokalizować problemy: jeśli kontener bookstack-app-1 ulegnie awarii, będziesz dokładnie wiedział, w którym folderze szukać.

Wizualnie jest o wiele bardziej przejrzysty i pozwala zarządzać każdą usługą niezależnie (uruchamiać, zatrzymywać lub aktualizować ją bez wpływu na pozostałe). Co więcej, aplikacje takie jak Dozzle korzystają z oddzielnych stosów, aby lepiej organizować logi.

Wadą jest to, że jeśli wszystko zbyt mocno oddzielisz, koordynacja między wspólnymi usługami (takimi jak Traefik lub współdzielone sieci) będzie wymagała nieco więcej uwagi : musisz zadeklarować sieci zewnętrzne, określone etykiety Traefik i pamiętać nomenklaturę sieci utworzonych przez inne narzędzia docker-compose.

Najlepsze praktyki dotyczące .env, nadpisywania i kontroli wersji

Jednym z najbardziej niedocenianych trików jest centralizacja konfiguracji w plikach .env . Zamiast wypełniać plik docker-compose.yml zmiennymi środowiskowymi, można zdefiniować coś takiego:

DB_USERNAME=myuser
DB_PASSWORD=secretpassword

Następnie w pliku YAML odwołują się do nich jako ${DB_USERNAME} lub ${DB_PASSWORD} . Dzięki temu Compose jest czytelny na pierwszy rzut oka, można udostępniać zmienne między wieloma usługami i, co najważniejsze, przechowuje hasła w osobnym pliku (który można wykluczyć z Gita).

W różnych środowiskach (produkcja, testowanie, rozwój) bardzo przydatne jest wykorzystanie pliku docker-compose.override.yml . Chodzi o to, aby mieć bazowy plik docker-compose.yml i w ramach nadpisywania nadpisywać tylko te zmiany, które się pojawią: porty, ścieżki, flagi debugowania itp.

Na przykład podczas tworzenia aplikacji możesz załadować nadpisanie, w którym udostępniasz inny port, włączasz debugowanie i montujesz lokalny kod źródłowy . Nie zmieniasz głównego pliku YAML, ale dostosowujesz stos do środowiska, w którym go uruchamiasz.

Oczywiście, wersjonowanie wszystkiego za pomocą Gita jest obowiązkowe, jeśli chcesz, aby Twoje laboratorium domowe było choć trochę profesjonalne . Zazwyczaj będzie to wyglądać mniej więcej tak:

homelab-docker/
├── docker-compose.yml
├── .env.example
├── services/
│   ├── media/
│   ├── infra/
│   └── ...
└── scripts/

Następnie inicjujesz repozytorium, zatwierdzasz zmiany w infrastrukturze, a jeśli coś się zepsuje, możesz w kilka sekund przywrócić poprzednią wersję Compose . Dla ambitnych laboratoriów domowych to nie tylko opcja; to jedyny sposób, aby uniknąć szaleństwa.

Sieci, Traefik i bezpieczne udostępnianie usług

W prawie wszystkich średnio zaawansowanych homelabach pojawia się ta sama kombinacja: Traefik jako odwrotny serwer proxy i scentralizowany dostawca tożsamości (Auth lub Authentik) . Pozwala to na udostępnianie wielu aplikacji w subdomenach z HTTPS i logowaniem jednokrotnym (SSO).

Klasycznym podejściem jest skonfigurowanie dedykowanej sieci Docker, takiej jak reverse_proxy lub podobnej, w której Traefik i wszystkie usługi sieciowe, które będą świadczone zewnętrznie, są połączone. Pozostałe kontenery (bazy danych, pamięci podręczne itp.) pozostają w odizolowanych sieciach wewnętrznych.

Jeśli używasz Traefika i rozdzielasz swoje usługi na różne instancje Docker Compose, musisz zdefiniować współdzieloną sieć zewnętrzną . Na przykład tak:

services:
  bookstack:
    image: lscr.io/linuxserver/bookstack
    networks:
      - traefik-net
    labels:
      - "traefik.docker.network=traefik_default"

networks:
  traefik-net:
    name: traefik_default
    external: true

W tym przypadku sieć traefik_default jest tworzona przez stos Traefik, a pozostałe usługi są do niej dodawane za pośrednictwem sieci zewnętrznej o nazwie traefik-net. Etykiety informują Traefik, której sieci ma używać do routingu ruchu.

Gdy pojedynczy stos zawiera usługi zaplecza (na przykład kontener internetowy i jego bazę danych), można połączyć je ze współdzieloną siecią domyślną i przyznać kontenerowi internetowemu dostęp tylko do sieci Traefik . Baza danych będzie miała etykietę ustawioną na `traefik.enable=false`, dzięki czemu Traefik ją zignoruje.

Ten typ konfiguracji oferuje dwie kluczowe korzyści: izolację między usługami i kontrolowaną ekspozycję . Tylko kontenery oznaczone etykietami Traefik i znajdujące się w sieci proxy stają się dostępne z zewnątrz.

Trwałość danych, woluminy i struktura dysku

Laboratorium domowe bez trwałych danych nie jest zbyt przydatne: bazy danych, konfiguracje, media, dokumenty… wszystko musi przetrwać awarię Docker Compose. Woluminy i montowania powiązań to Twoja deska ratunku.

  systemd 259: obsługa musl, bezpieczeństwa i zmian kluczy

Wiele osób organizuje swoje przechowywanie, korzystając z następującej struktury:

/mnt/storage/
├── downloads/
│   ├── movies/
│   └── tv/
├── media/
│   ├── movies/
│   ├── tv/
│   └── music/
└── srv/
    └── 

Pomysł jest taki, że programy pobierające (qBittorrent, SABnzbd itp.) widzą tylko folder pobierania , menedżery takie jak Radarr/Sonarr mają dostęp zarówno do pobieranych plików, jak i multimediów (w celu przenoszenia/tworzenia twardych linków), a serwery takie jak Plex lub Jellyfin widzą tylko folder multimediów.

W ten sposób stosujesz zasadę najmniejszych uprawnień : każdy kontener ma dostęp tylko do tego, czego faktycznie potrzebuje. Przejrzysty podział pomaga również przy podejmowaniu decyzji, które woluminy lub ścieżki mają być kopiowane do chmury lub na dyski zewnętrzne.

Katalog srv jest zazwyczaj używany do przechowywania konfiguracji aplikacji (na przykład /srv/jellyfin/config, /srv/traefik, /srv/paperless itp.). Zazwyczaj jest on częściowo wersjonowany (szablony, Caddyfile itp.), z pominięciem elementów krytycznych lub wymagających dużej ilości zasobów.

W niektórych przypadkach przydatne jest użycie twardych linków w łańcuchu pobierania: usługi takie jak Radarr czy Sonarr mogą łączyć pobrane pliki, aby utrzymać seeding bez duplikowania miejsca na dysku. Struktura katalogów proponowana przez przewodniki takie jak TRaSHGuides opiera się właśnie na tej zasadzie.

Automatyzacja wdrożeń za pomocą GitHub Actions i lokalnych programów uruchamiających

Jeśli chcesz pójść o krok dalej, możesz zautomatyzować aktualizacje homelabu za pomocą CI/CD . Kilku użytkowników zastąpiło Jenkinsa i podobne narzędzia przepływem pracy wykorzystującym GitHub Actions i moduł uruchamiający hostowany samodzielnie w homelabu.

Mechanizm jest prosty: za każdym razem, gdy przesyłasz zmiany do głównej gałęzi repozytorium homelab, uruchamiany jest przepływ pracy GitHub Actions, który uruchamia testy, lintery i, jeśli wszystko pójdzie dobrze, wdraża zmiany na serwerze.

Typowy przepływ pracy obejmuje następujące kroki:

  • Tajny skaner typu Gitleaks:na wypadek gdybyś przypadkowo przesłał hasła lub tokeny do repozytorium.
  • podszewka kodu YAML lub infrastruktury, aby zachować czytelny i spójny format.
  • Aktualizacja repozytorium w samym laboratorium domowym: git pull na serwerze docelowym.
  • Kontrolowana rekreacja kontenerów:zatrzymaj stare, uruchom nowe i sprawdź status.

Zalety: zwiększone bezpieczeństwo (kontrolujesz wycieki poufnych informacji), lepsza jakość kodu i powtarzalne wdrożenia za pomocą jednego pushu . A ponieważ korzystasz z lokalnego serwera uruchomieniowego, obrazy i woluminy nie opuszczają Twojej sieci; wystarczy wykorzystać interfejs GitHub do wizualizacji potoków.

Dlaczego Docker Compose tak bardzo ułatwia życie w laboratorium domowym

Wiele osób przez lata korzystało z Docker Run i Portainer, aż w końcu, po incydencie lub migracji, musiało ponownie przeanalizować swoje podejście. W przypadku utraty hosta lub konieczności przeniesienia usług na inną maszynę, poleganie wyłącznie na pojedynczych poleceniach lub konfiguracjach w Portainer jest pułapką.

Największą różnicą po przejściu na Compose jest to, że cała definicja usługi staje się tekstem : woluminy, porty, sieci, etykiety, zmienne... Wszystko w pliku YAML, który można kopiować, udostępniać, tworzyć wersje i ponownie wykorzystywać.

Edycja usługi nie polega już na „ręcznym przebudowywaniu kontenera”, ale na modyfikacji wiersza w pliku, zapisaniu go i uruchomieniu polecenia `docker compose up -d` . Nie musisz pamiętać oryginalnego polecenia ani klikać w wiele ekranów Portainera.

Co więcej, jeśli pracujesz z wieloma serwerami (mini PC, NAS, komputerami stacjonarnymi), niezwykle wygodna jest możliwość skopiowania tego samego pliku Compose na inną maszynę, dostosowania czterech ścieżek i uruchomienia tego samego stosu na innym sprzęcie . W rzeczywistości wiele osób przyznaje, że po obawach związanych z utratą danych lub chaotycznymi migracjami, Compose pozwolił im zaoszczędzić mnóstwo czasu w przyszłości.

Dodatkową zaletą jest to, że tworzenie nowych usług na podstawie starych staje się banalnie proste: na przykład klonowanie konfiguracji Plex w celu skonfigurowania Jellyfin przy ponownym użyciu tych samych ścieżek multimedialnych i urządzeń transkodujących zajmuje tylko kilka minut, jeśli wykonuje się to poprzez kopiowanie bloków YAML.

Optymalizacja: kontekst kompilacji, kompilacje wieloetapowe i zasoby

Chociaż wiele kontenerów Homelab pochodzi z publicznych obrazów, w niektórych przypadkach będziesz kompilować własne. W takich przypadkach ważne jest zarządzanie kontekstem kompilacji : nie przesyłaj całego repozytorium bez filtrowania, ale ogranicz się do folderu projektu (używając silnej dyrektywy `.dockerignore`), aby zapewnić szybkie i lekkie kompilacje.

Inną bardzo przydatną techniką jest stosowanie wieloetapowych kompilacji w plikach Dockerfile: w pierwszym etapie instalujesz zależności i kompilujesz, a w drugim kopiujesz tylko niezbędne artefakty do małego obrazu bazowego. Rezultatem są znacznie mniejsze i bezpieczniejsze obrazy finalne , ponieważ nie przenoszą niepotrzebnych łańcuchów narzędzi ani bibliotek.

  Architektura procesorów wielordzeniowych i systemy wieloprocesorowe

Po stronie Compose masz możliwość zdefiniowania limitów procesora i pamięci RAM (szczególnie w środowiskach Swarm lub gdy Docker respektuje te parametry), aby zapobiec nadmiernemu zajęciu zasobów przez aplikacje intensywnie wykorzystujące zasoby. W Homelabs pomaga to zapobiec sparaliżowaniu reszty systemu przez błędnie skonfigurowaną usługę.

Nie zapomnij o zasadach ponownego uruchamiania (restart: zawsze, o ile nie zostanie zatrzymane, w przypadku awarii). Dzięki nim możesz mieć pewność, że krytyczne usługi (odwrotny serwer proxy, VPN, kluczowe bazy danych) zostaną automatycznie uruchomione ponownie po ponownym uruchomieniu lub jednorazowej awarii.

Na koniec zaleca się zaplanowanie okresowych zadań czyszczenia za pomocą poleceń takich jak docker image prune, docker container prune i docker volume prune, aby usunąć pozostałości starych kompilacji, zatrzymanych kontenerów lub osieroconych woluminów i w ten sposób odzyskać miejsce na dysku.

Usługi zdrowotne, rejestrowanie i monitorowanie

Aby zapobiec przekształceniu się domowego laboratorium w czarną skrzynkę, ważne jest skupienie się na trzech kluczowych aspektach: sprawdzaniu kondycji, kontrolowanym logowaniu i monitorowaniu . Docker Compose pozwala deklarować sprawdzanie kondycji dla każdej usługi (za pomocą poleceń takich jak `curl -f http://localhost` lub określonych skryptów), które określają, czy kontener jest sprawny.

Dzięki temu możesz mieć pewność, że tylko „zdrowe” kontenery otrzymują ruch (na przykład przez Traefik) i że jeśli przestaną odpowiadać, zostaną ponownie uruchomione zgodnie ze skonfigurowaną polityką. To znacznie zwiększa odporność przy minimalnym wysiłku.

Jeśli chodzi o logi, dostosowanie sterownika pliku json do limitów maksymalnego rozmiaru i maksymalnego rozmiaru pliku zapobiega zapełnieniu dysku gigabajtami zapomnianych logów. Narzędzia internetowe, takie jak Dozzle, umożliwiają przeglądanie logów wszystkich kontenerów z poziomu przeglądarki, co jest bardzo wygodne w przypadku debugowania określonych usług.

W przypadku metryk i ciągłego monitorowania klasyczną kombinacją jest cAdvisor + Prometheus + Grafana . cAdvisor udostępnia statystyki wykorzystania procesora, pamięci, dysku i sieci dla każdego kontenera; Prometheus zbiera je okresowo, a Grafana wyświetla je na atrakcyjnych pulpitach, wysyłając alerty w przypadku gwałtownych wzrostów.

Dobrze skonfigurowane laboratorium domowe zazwyczaj obejmuje Uptime Kuma do kontroli dostępności (HTTP, ICMP, TCP itp.) oraz zautomatyzowany system tworzenia kopii zapasowych, taki jak Duplicati, do kopiowania krytycznych danych na inne dyski lub do chmury. W ten sposób wiesz, co się dzieje, a jeśli coś pójdzie nie tak, nie stracisz tego, co ważne.

Bezpieczeństwo i zdalny dostęp do laboratorium domowego

Niezależnie od tego, jak samodzielnie skonfigurujesz swój serwer NAS, bezpieczeństwo nie jest opcjonalne. Wiele osób decyduje się nie udostępniać bezpośrednio swojego serwera NAS ani jego usług światu zewnętrznemu , ograniczając zdalny dostęp przez VPN (WireGuard jest bardzo popularną opcją ze względu na wydajność i prostotę).

W tym modelu router działa jak brama: dla serwera VPN otwierany jest tylko losowy port, a po nawiązaniu połączenia wszystkie żądania do usług wewnętrznych przechodzą przez szyfrowany tunel . Ani Traefik, ani aplikacje nie są narażone na dostęp do internetu bez wcześniejszego filtrowania.

Ci, którzy nie chcą zarządzać własną siecią VPN, czasami korzystają z Cloudflare Tunnel lub Tailscale , aby uzyskać dostęp do domowego laboratorium bez otwierania portów. To wygodne alternatywy, jednak jeśli prywatność jest dla Ciebie priorytetem, musisz rozważyć, jakie metadane mogą gromadzić te podmioty zewnętrzne.

Inną dobrą praktyką jest szyfrowanie dysków serwera i NAS , regularne instalowanie poprawek i ograniczanie automatycznych aktualizacji (wiele osób unika Watchtower na rzecz kontrolowanych aktualizacji ręcznych). Lepiej być trochę w tyle, ale z kontrolą, niż zepsuć połowę Homelaba przez aktualizację, której nie sprawdziłeś.

Jak widać, nie musisz osiągać poziomu „przedsiębiorstwa”, ale wskazane jest ustalenie minimalnego poziomu bezpieczeństwa i dyscypliny , aby Twoje domowe laboratorium nie było sitem lub stałym źródłem strachu.

Ostatecznie skonfigurowanie poważnego laboratorium domowego z Docker Compose wymaga połączenia organizacji, zdrowego rozsądku i chęci eksperymentowania: jeśli zgrupujesz usługi, dobrze zdefiniujesz sieci, udokumentujesz w Git i trochę zautomatyzujesz, otrzymasz środowisko, które możesz uruchomić za pomocą jednego polecenia, łatwo przenieść na inną maszynę i stopniowo rozbudowywać, nie stając się przy tym niekontrolowaną dżunglą.