Mój pierwszy serwer — początki self-hostingu cz. 2, Proxmox i pierwszy blog z Publii

W poprzednim wpisie opisywałem, jak przygotować sprzęt potrzebny do uruchomienia serwera, publiczny adres IP, dynamiczny DNS oraz domenę. W tym wpisie omówię, jak uruchomić naszego pierwszego bloga przy wykorzystaniu Proxmoxa. Wewnątrz niego zainstalujemy Publii - statyczny CMS oraz Nginx służący jako reverse proxy. Taki zestaw możemy nazwać "pakietem startowym" dla naszego blogowania.

Głównym kryterium, jakie sobie postawiłem, była możliwość łatwego instalowania i zarządzania wieloma serwisami. Najlepszym do tego rozwiązaniem będzie właśnie Proxmox, ponieważ posiada duże możliwości, a w razie potrzeby możemy wewnątrz maszyny wirtualnej VM czy kontenera LXC zainstalować także Dockera. Wpis ten jest usystematyzowaniem i udokumentowaniem zabawy ze swoim homelabem, ale liczę na to, że przyda się komuś jeszcze na początek drogi z selfhostingiem.

Spis treści

Proxmox

Proxmox VE to w skrócie otwartoźródłowa platforma do wirtualizacji, która pozwala uruchamiać wiele maszyn wirtualnych (VM) i kontenerów (LXC) na naszym fizycznym serwerze. Można powiedzieć, że jest to taki system do uruchamiania, zarządzania i administrowania wirtualnymi serwerami. Proxmox to potężne i jednocześnie proste w użyciu narzędzie, idealne do hostowania wielu serwisów na naszym skromnym terminalu. Technicznie rzecz biorąc jest to dystrybucja Linuxa oparta na Debianie.

We wpisie skupię się na kontenerach LXC, ponieważ mają one mniejszy narzut niż maszyny wirtualne VM i przede wszystkim efektywniej zarządzają pamięcią RAM. Możemy liczyć nawet na dwukrotnie mniejsze zużycie pamięci względem VM, głównie ze względu na współdzielenie pamięci pomiędzy wszystkimi kontenerami. Ograniczeniem kontenerów LXC jest korzystanie z jądra Proxmoxa. Dla nas nie będzie to stanowić problemu, ponieważ i tak będziemy bazować na Debianie.

Instalacja Proxmoxa

Sama instalacja nie różni się specjalnie od instalowania przeciętnej dystrybucji Linuxa. Pobieramy obraz systemu, wgrywamy go na pamięć USB i podpinamy go do naszego serwera. Nie będę się rozwodził nad szczegółami instalacji - w internetach dostępnych jest mnóstwo tutoriali. Dodam tylko, że na czas instalacji będziemy potrzebowali podłączyć monitor i klawiaturę do naszego serwera. Po udanej instalacji odłączamy nasze peryferia i od tej pory uzyskujemy dostęp do panelu administracyjnego w naszej sieci lokalnej pod adresem, jaki ustaliliśmy podczas instalacji. Jeśli ktoś jednak jest zainteresowany szczegółami instalacji, to odsyłam do wpisu na blogu Tomasza Duni.

Nginx

Po co nam Nginx jako reverse proxy? Można powiedzieć, że działa on jak recepcjonista stojący przed naszymi serwisami. Przyjmuje wszystkie wejścia od użytkowników i przekazuje je do właściwego serwisu, a potem odsyła odpowiedź z powrotem. Dzięki temu możemy uruchomić wiele usług posiadając tylko jeden publiczny adres IP.

Nginx pełniący funkcję Reverse Proxy nie jest wymagany jeśli chcemy hostować tylko jedną stronę. Nawet jednak w tym przypadku jest polecany ze względu na to, że pełni dodatkową warstwę bezpieczeństwa oraz umożliwia łatwe zarządzanie certyfikatami SSL. Jeśli jednak zamierzamy mieć więcej usług, to Nginx okazuje się koniecznością.

Instalujemy LXC z Nginx

Skoro już mamy zainstalowany Proxmox VE, to czas na utworzenie naszego pierwszego kontenera z Nginx. Zanim jednak zaczniemy samą instalację, musimy pobrać szablon (template), z systemem który będzie niezbędny do postawienia naszych serwisów. Osobiście korzystam z Debiana, jednak nic nie stoi na przeszkodzie, żeby wybrać np. Ubuntu.

W oknie z lewej strony (lista naszych serwerów) wybieramy:
local (proxmox) -> CT Templates -> Templates
Pojawi nam się okno z listą dostępnych szablonów.
Wybieramy lxc Debian-13-standard i klikamy Download

Jak już udało nam się pobrać obraz Debiana, to zabieramy się za instalację kontenera. Klikamy Create CT (prawy górny róg strony). Otworzy nam się okno z zakładkami:

 - General
Uzupełniamy poszczególne pola:
Hostname - nasza nazwa kontenera, czyli nginx
Password - wpisujemy silne hasło
Confirm Password - potwierdzamy nasze hasło
- Template
W pozycji Template wybieramy pobranego wcześniej debian-13-standard
- Disks
W polu Disk size (GiB) określamy rozmiar dysku, jaki przydzielimy naszemu kontenerowi. Śmiało możemy przydzielić względnie małą ilość pamięci, ponieważ w dowolnym momencie łatwo można go powiększyć jeśli zajdzie taka potrzeba. Wystarczająca ilość dla nginx to 2 GiB.
- CPU
W polu Cores wybieramy ilość rdzeni procesora, które przydzielimy naszemu kontenerowi. W przypadku Nginx w zupełności wystarczy 1 rdzeń.
- Memory
W polu Memory przydzielamy pamięć dla kontenera, a polu Swap możemy wpisać taką samą wartość. Optymalną ilością pamięci będzie 256 MiB.
- Network
W tej zakładce najbardziej interesuje nas IPv4. Pozostawiamy Static i w polu IPv4/CIDR nadajemy adres lokalny dla kontenera, np. 192.168.1.200/24. W polu Gateway (IPv4) wpisujemy 192.168.1.1
- DNS
Pozostawiamy domyślne ustawienia
- Confirm
Zobaczymy podsumowanie parametrów naszego kontenera. Zaznaczamy pole Start after created i klikamy Finish.

Na liście z serwerami pojawi się i automatycznie uruchomi pierwsza pozycja 100 (nginx). Po utworzeniu kontenera z Debianem pozostaje nam instalacja samego Nginx oraz certobota do zarządzania certyfikatami SSL.

Wybieramy nasz kontener, otwieramy zakładkę Console, logujemy się podanymi wcześniej danymi i zabieramy się za instalację:

apt update && apt upgrade -y #aktualizacja systemu
apt install nginx -y #instalacja nginx
systemctl enable nginx #aktywacja nginx
systemctl start nginx #uruchomienie nginx
rm /etc/nginx/sites-enabled/default #usuwamy domyślny config
systemctl reload nginx #przeładowujemy nginx
apt install certbot python3-certbot-nginx -y #instalujemy certbota

Tym samym nasz Nginx jest zainstalowany i gotowy do pracy. Mamy już przygotowaną podstawę, która pozwoli nam hostować nie tylko bloga, ale również inne usługi w przyszłości. Dodatkowo przygotowaliśmy Certbota, który ułatwi zarządzanie certyfikatami SSL. Taka konfiguracja pozwoli nam w przyszłości łatwo dodawać kolejne serwisy i udostępniać je przez jeden publiczny adres IP. Teraz pora przejść do instalacji naszego bloga.

Publii

Publii to bardzo łatwy w obsłudze statyczny CMS do generowania szybkich stron internetowych i jednocześnie idealne narzędzie do uruchomienia naszego pierwszego bloga. Działa jako aplikacja instalowana na komputerze – tworzymy naszą stronę w edytorze wizualnym, a następnie wrzucamy ją na serwer. Największą zaletą (oprócz szybkości działania) jest łatwa i przystępna aplikacja do obsługi strony czy bloga - wszystko z łatwością możemy wyklikać. Po zainstalowaniu i skonfigurowaniu aplikacji właściwie wszystko mamy już gotowe. Do nas należy tylko to, co najważniejsze, czyli tworzenie treści.

Instalujemy LXC z Publii

Żeby zainstalować Publii, utworzymy drugi kontener. Robimy to analogicznie jak w przypadku tworzenia kontenera dla Nginx. Opiszę tylko zakładki specyficzne dla kontenera z Publii:

 - General
Uzupełniamy poszczególne pola:
Hostname -
nasza nazwa kontenera, czyli publii
Password -
wpisujemy silne hasło
Confirm Password -
potwierdzamy nasze hasło
- Disks

Możemy rozważyć nieco więcej miejsca na dane jeśli zamierzamy dodawać zdjęcia czy wideo do swoich wpisów.
- Network
W tej zakładce wpisujemy lokalny adres IP dla Publii, w naszym przypadku może być to np. 192.168.1.201/24. Gateway pozostaje takie samo.

Po utworzeniu drugiego kontenera klikamy na liście z serwerami w 101 (publii), wchodzimy w zakładkę Console i zabieramy się za przygotowanie kontenera pod Publii.

Uwaga: podczas konfiguracji będziemy się przełączać na liście serwerów pomiędzy hostem (proxmox), 100 (nginx) oraz 101 (publii).

# komedy wykonywane w konsoli na hoście (Proxmox)
mkdir -p /srv/publii #utworzenie współdzielonego katalogu
pct set 101 -mp0 /srv/publii,mp=/var/www/publii #podłączenie katalogu do 101 (publii)
pct set 101 -mp0 /srv/publii,mp=/var/www/publii #podłączenie katalogu do 100 (nginx)
chown -R 100000:100000 /srv/publii #uprawnienie dla nieuprzywilejowanego LXC
pct restart 100 #restart nginx
pct restart 101 #restart publii
# komedy wykonywane w konsoli na 100 (nginx)
ls -la /var/www/publii
#sprawdzamy widoczność katalogu
nano /etc/nginx/sites-available/publii # tworzymy config nginx dla publii i wklejamy:

server {
    listen 80;
    server_name naszadomena.pl;

    root /var/www/publii;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
# opcjonalnie dodajemy kompresję gzip dla szybszego wczytywania strony
gzip on;
gzip_comp_level 6;
gzip_vary on;
gzip_types
text/css
application/javascript
application/xml
image/svg+xml;
}

#aktywujemy config w nginx
ln -s /etc/nginx/sites-available/publii /etc/nginx/sites-enabled/
nginx -t #testujemy poprawność configu
systemctl reload nginx #przeładowujemy nginx
# komedy wykonywane w konsoli na 101 (publii)
ls -la /var/www/publii
#sprawdzamy widoczność katalogu
# konfiguracja SSH (jeśli chcemy mieć dostęp za pomocą loginu i hasła - mniej bezpieczne rozwiązanie. polecam rozważyć używanie klucza):
nano /etc/ssh/sshd_config
# zmieniamy:
PermitRootLogin yes
PasswordAuthentication yes
# zapisujemy i restartujemy SSH:
systemctl restart ssh
# w tym przypadku jako login i hasło używamy tych samych danych co podczas tworzenia kontenera z publii.

Mamy już przygotowane środowisko. Pozostaje nam teraz podłączenie domeny, pobranie certyfikatu SSL i finalne wgranie naszego bloga do kontenera za pomocą aplikacji Publii. Cała infrastruktura po stronie serwera jest już gotowa — Proxmox zarządza kontenerami, Nginx obsługuje ruch przychodzący jako reverse proxy, a Publii generuje statyczną stronę.

Osobne LXC dla  Nginx i Publii - wyjaśnienie

Dlaczego rozdzieliłem Nginx i Publii na dwa osobne kontenery? W końcu statyczny CMS jest tak mały, że bez problemu mógłby działać razem z Nginx na jednym LXC. Teoretycznie można więc uznać, że rozdzielenie tych usług na dwa kontenery jest lekkim overkillem.

Wybrałem jednak takie rozwiązanie, ponieważ z założenia izoluję wszystkie uruchomione serwisy. Dodatkowa izolacja oznacza większe bezpieczeństwo, osobne backupy oraz lepszą kontrolę nad poszczególnymi usługami. Jeśli spojrzymy na zużycie zasobów, okazuje się, że rozdzielenie serwisów nie wiąże się wcale z dużym narzutem. Kontener z Publii wykorzystuje około 25 MB pamięci RAM, a jego instalacja zajmuje około 700 MB przestrzeni dyskowej. Są to pomijalne wartości w skali całego serwera.

Domena i dynamiczny DNS

Zakładam, że macie już wykupioną domenę oraz skonfigurowany dynamiczny DNS (dla zmiennego adresu IP). Jak to zrobić opisywałem w poprzednim wpisie.

Certyfikat SSL

Skoro mamy już wykupioną domenę, czas na wygenerowanie i konfigurację certyfikatu SSL dla naszego bloga w nginx. Certbot, który wcześniej zainstalowaliśmy, posłuży nam do pobrania i odnawiania certyfikatów SSL.

Żeby dodać certyfikat do naszego bloga wystarczy wykonać jedną komendę:

certbot --nginx -d mojadomena.pl

W terminalu powinniśmy zobaczyć informację zwrotną o poprawnym pobraniu i zainstalowaniu certyfikatu. Certbot automatycznie zaktualizuje nam konfigurację w nginx.

Instalacja Publii

Ostatnim, co nam pozostało, jest zainstalowanie aplikacji Publii. Jest to aplikacja wieloplatformowa, a na oficjalnej stronie znajdziemy instalatory dla systemów Linux, Windows oraz macOS. Możemy również skorzystać z repozytorium naszej dystrybucji. Jeśli używacie Arch Linux lub jego pochodnych (np. CachyOS), Publii znajdziecie także w AUR.

Po instalacji musimy jeszcze skonfigurować połączenie SSH pomiędzy aplikacją Publii a naszym kontenerem 101 (publii). Otwieramy aplikację i przechodzimy do zakładki Server. Konfigurujemy odpowiednio:

Website URL: naszadomena.pl
Server: 192.168.1.201 - adres kontenera 101 (publii)
Username: root (lub użytkownik którego stworzyliśmy)
Authentication metod: zaznaczamy Password lub Key file w zależności jak skonfigurowaliśmy wcześniej SSH.
Remote path: /var/www/publii

Zapisujemy ustawienia i klikamy Sync your website, żeby sprawdzić, czy wszystko poprawnie skonfigurowaliśmy. Jeśli synchronizacja się powiodła, oznacza to, że nasza strona została właśnie wrzucona na serwer.

Pozostało nam otworzyć bloga w przeglądarce i sprawdzić, czy certyfikat SSL został poprawnie zainstalowany. Jeśli strona otwiera się bez żadnych ostrzeżeń, oznacza to, że wszystko działa tak, jak powinno.

Podsumowanie

W ten sposób uruchomiliśmy naszego pierwszego bloga na własnym serwerze. Mamy przygotowaną infrastrukturę na Proxmoxie bazującą na kontenerach LXC. Nginx pełni rolę reverse proxy, obsługuje ruch przychodzący oraz zarządza certyfikatami SSL, natomiast Publii odpowiada za generowanie i publikację statycznej strony.

Całe rozwiązanie bazujące na Proxmoxie, które stworzyliśmy, jest dopiero początkiem naszej przygody z selfhostingiem. Teraz z łatwością możemy dokładać kolejne serwisy według potrzeb, aż całkowicie uwolnimy się od rozwiązań chmurowych firm trzecich (o ile jeszcze z takich korzystacie).

Jest dyskusja na Mastodonie