Seriál o ASP.NET Core na Raspberry Pi měl původně mít jenom čtyři pokračování. Ale výrobce v jeho průběhu uvedl nový model, Raspberry Pi Zero 2. Ten je z mnoha důvodů zajímavý, takže jsem mu věnoval bonusový, pátý díl seriálu. A zároveň jsem popsal, jak používat framework-dependent deployment, tedy jak nainstalovat na Raspberry .NET runtime a provozovat univerzální multiplatformní binárky.

Raspberry Pi Zero 2

Běžné počítače Raspberry Pi mají velikost asi jako běžná krabička cigaret a cenu okolo 35 dolarů. Existuje ale ještě menší řada, Raspberry Pi Zero. Počítače této řady jsou ještě omezenější svým výkonem a konektivitou, ale jsou výrazně levnější a menší.

Úplně první bylo Raspberry Pi Zero. Počítač s cenou pět dolarů (v českých podmínkách 127 Kč u oficiálního distributora RPishop.cz). Jeho největší slabinou je, že se nativně neumí připojit k síti. Nemá Wi-Fi ani ethernetové rozhraní a je nutné ho k němu dodatečně přidat přes USB. Nástupcem je Raspberry Pi Zero W. To za dvojnásobnou cenu ($ 10 nebo 279 Kč) nabízí navíc 2,4 GHz Wi-Fi. Existují i verze s "H" na konci, ale to jenom znamená, že mají napájené hlavičky na univerzálním konektoru a nemusíte to dělat sami, pokud je budete chtít využít.

Tyto modely byly pro .NET programátory nezajímavé, protože na jejich procesorech .NET běžet neumí. Nepodporují totiž instrukční sadu ARMv6, kterou .NET vyžaduje. To se změnilo s modelem Raspberry Pi Zero 2 W. Ten stojí patnáct dolarů (410 Kč) a má stejný procesor jako Raspberry Pi 3. Má výrazně vyšší výkon než jeho předchůdci, srovnatelný s Raspberry Pi 3. A .NET na něm běží.

Řada Zero je předurčena k malým věcem. A to doslova, protože destička má pouhých 65 x 30 mm a je tedy menší než platební karta. Nabízí Wi-Fi konektivitu, jeden MicroUSB port s funkcí OTG (druhý MicroUSB konektor slouží k napájení) a MicroHDMI pro grafický výstup.

Od počítače s těmito parametry nelze čekat žádné výkonové zázraky. Spouštění webové aplikace v .NETu je dostatečné, ale taková kompilace je jenom pro trpělivé a i instalace trvá výrazně déle. Ostatě s pouhými 512 MB RAM není čemu se divit. Na druhou stranu jsou aplikace, kde nízký výkon nevadí a oceníme nízkou cenu, rozměry a spotřebu.

Framework-Dependent Deployment

Vlastní postup instalace tak, jak byl popsán v předchozích dílech našeho seriálu, je zcela univerzální, bez ohledu na použitý model RPi. Zero 2 lze nainstalovat přesně stejně, jako jeho větší bratříčky.

Proto jsem se v tomto modelu vydal poněkud jinou cestou a rozhodl se aplikaci spustit ve FDD režimu, který vyžaduje instalaci .NET runtime na Raspberry Pi. Upřímně řečeno, nedává to moc smysl - právě u Zero verze se mnohem víc hodí SCD (Self-Contained Deployment), kdy na server nahráváme nativní binárku. Ale tu už jsem popisoval dříve, takže jsem se vydal komplikovanější cestou.

Sám postup je docela dobře popsán v článku Deploy .NET apps to Raspberry Pi. Od nasazení na "velký" Linux se liší především v tom, že není k dispozici instalace pomocí package manageru a vše se musí dělat "ručně". Přičemž ovšem "ručně" obnáší spuštění jednoho shell skriptu.

Sekvence příkazů pro instalaci .NETu je následující:

curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current
echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc
echo 'export PATH=$PATH:$HOME/.dotnet' >> ~/.bashrc
source ~/.bashrc
dotnet --version

Uvedeným postupem se nainstaluje kompletní SDK, takže nyní lze použít všechny metody deploymentu. Kompilaci ze zdrojáků však důrazně nedoporučuji, přišla mi i u primitivní aplikace extrémně pomalá, nejspíš s ohledem na malé množství operační paměti.

Použití FDD vyžaduje změnu v souboru /etc/systemd/system/kestrel-askme.service. Nespouštíme přímo binárku aplikace, ale binárku /home/pi/.dotnet/dotnet jíž jako argument předáváme název spouštěného DLL. Dále pak jsem tady neřešil běh pod low-privileged účtem a vše běží pod uživatelem pi. Definiční soubor služby pak vypadá takto:

[Unit]
Description=ASKme .NET 5 Web Application

[Service]
WorkingDirectory=/home/pi/AskMe/
ExecStart=/home/pi/.dotnet/dotnet Altairis.AskMe.Web.RazorPages.dll
Restart=always
RestartSec=10
SyslogIdentifier=dotnet-askme
User=pi
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target

Provoz holého Kestrelu

Vzhledem k omezenému výkonu jsem se rozhodl nezatěžovat počítač ještě navíc Nginxem a Kestrel si musí poradit sám o sobě. Změnil jsem konfiguraci tak, aby naslouchal na standardním portu 80.

S tím je ovšem spojen drobný problém. Na Linuxu standardně na portech pod 1000 smějí naslouchat pouze procesy běžící pod oprávněním roota. Následujícím příkazem přidáme proces dotnet do výjimek:

sudo setcap CAP_NET_BIND_SERVICE=+eip /home/pi/.dotnet/dotnet

To řešení není úplně ideální (povolí naslouchat všem .NET aplikacím na všech nízkých portech), ale pro účely našeho dema je zcela postačující.

Tímto dílem končí náš oficiální seriál o hostování ASP.NET aplikací na Raspberry Pi, ale rozhodně to není poslední článek o této platformě. Ostatně, minulou neděli jsem vydal jako článek odpověď na dotaz čtenáře, jak řešit deployment na Linux "na jedno tlačítko" z Visual Studia pomocí SCP.

Pokud máte nějaké další dotazy a náměty, můžete mi napsat na Twitteru, Facebooku nebo mailem.