Rádi bychom představili pěkný nástroj pro správu debianích repozitářů a popsali způsob, jakým jej my používáme.
Při správě serverů nejspíš každý z nás v jeden moment dojde do situace, kdy potřebuje distribuovat vlastní nástroje, které mu usnadní život.
Už jsme viděli spousty kreativních řešení. My jsme se jsme si položili jednoduchou otázku: Proč distribuci nedělat jako jí dělá distribuce samotná?
V době, kdy jsme dělali rešerši řešení, byla dostupná pro nás převážně komplikovaná řešení. Většinou se jednalo o upload souboru do konkrétního adresáře a následně spuštění scriptu (buď cronem nebo přes ssh).
Narazili jsme ale na Aptly (Github), které bylo v prvotní fázi vývoje a jeho jednoduché API se nám tak líbilo, že bylo celkem rychle rozhodnuto. Nyní se již jedná o stabilní komponentu Debianu.
Jako alternativu lze zvážit využití integrace v Gitlab package registry (v současné době jen experimentálně). Zatím ale zůstaneme věrní aptly. Zastáváme názor, že jeden nástroj by měl dělat jen jednu věc a snažíme se věci držet co nejvíce jednoduché.
Debian sice krásně podporuje hostování repozitářů pro více distribucí na jedné adrese a Aptly tuto podporu má v sobě, my jsme ale měli nějaké porodní bolesti, které nám toto nasazení komplikovalo.
Rozhodli jsme se tedy dělat věci jednoduše. A tak pro každou distribuci vytváříme nový server, kde každý repozitář je subdoména. Výsledná adresa tedy vypadá následovně:
PROJEKT.DISTRIBUCE.deb.DOMENA
(např. demo.bookworm.deb.DOMENA
).
Díky tomuto oddělení jsme získali některé dobré vlastnosti:
Vidíme jednoduše (tj. bez nutnosti filtrace) v accesslogu, které servery repozitář využívají.
Vidíme balíčky jen pro danou distribuci a projekt a můžeme udělat jednoduše jejich revizi.
Jednotlivé projekty jsou vzájemně oddělené a můžeme k nim jednoduše řídit přístupové oprávnění.
Čištění repozitáře při ukončení podpory distribuce je velmi jednoduché - smažeme celý server.
Přípravu repozitářů máme maximálně automatizovanou, takže pro vytvoření nového repozitáře stačí do puppet přidat:
demo:
auth_users: [ 'demo:$apr1$qm06z9ya$BcszwIX1RDz9rwV7uZXmZ1' ]
api_auth_users: [ 'demo_upload:$apr1$t0fe48k9$vFp/zPdlaC4fKQWZ00xvh.' ]
To nám vytvoří nový repozitář pro projekt demo
s ověřením pomocí http authentizace, která je rozdělená na veřejnou část (servery) a API (build pipeline).
Aptly je mocný nástroj a umí mimojiné i mirrorování repozitářů.
Původně nám přišlo jako dobrý nápad, aby se aplikace nasazovaly konzistentně - čili udělal se mirror celého repozitáře a nasadily se všechny změny. Později se ale ukázalo, že je-li v repozitáři trochu více balíků, tak tento přístup vyžaduje trochu organizace a plánování při nasazování.
My ale chceme dostávat do produkce jednotlivé komponenty co nejrychleji. Nahradili jsme tedy mirrorování repozitářů oddělenými repozitáři a balíky v konkrétních verzích kopírujeme mezi repozitáři.
Upozornění: Následující je ukázka bez jakéhokoliv zabezpečení.
Aptly je už nějakou dobu součástí Debianu, pro instalaci tedy stačí tedy jen:
apt install aptly gnupg
Příprava GPG pro podpis repozitáře
Vytvoříme soubor ~/gpg.conf
s obsahem:
Key-Type: RSA
Key-Length: 4096
Subkey-Type: RSA
Subkey-Length: 4096
Name-Real: Server zone
Name-Comment: Generated by puppet
Name-Email: info@serverzone.cz
Expire-Date: 0
%no-protection
%commit
Následně si vytvoříme gpg klíče:
mkdir -p /var/www/public/
/usr/bin/gpg --batch --gen-key ~/gpg.conf
/usr/bin/gpg --export -a "ServerZone" > /var/www/public/apt.asc
Vytvoříme aptly repozitář
Soubor: ~/.aptly.conf
{
"rootDir": "/var/www/",
"downloadConcurrency": 4,
"downloadSpeedLimit": 0,
"downloadRetries": 0,
"downloader": "default",
"databaseOpenAttempts": -1,
"architectures": [],
"dependencyFollowSuggests": false,
"dependencyFollowRecommends": false,
"dependencyFollowAllVariants": false,
"dependencyFollowSource": false,
"dependencyVerboseResolve": false,
"gpgDisableSign": false,
"gpgDisableVerify": false,
"gpgProvider": "gpg",
"downloadSourcePackages": false,
"skipLegacyPool": true,
"ppaDistributorID": "ubuntu",
"ppaCodename": "",
"skipContentsPublishing": false,
"skipBz2Publishing": false,
"FileSystemPublishEndpoints": {},
"S3PublishEndpoints": {},
"SwiftPublishEndpoints": {},
"AzurePublishEndpoints": {},
"AsyncAPI": false,
"enableMetricsEndpoint": false
}
Proti výchozímu jsou tam jen 2 změny:
"rootDir": "/var/www/",
"architectures": ["amd64"],
Vytvoříme základní strukturu repozitáře spuštěním:
aptly repo create -distribution stable demo
Zároveň jej rovnou vypublikujeme, abychom jej mohli používat:
aptly publish repo demo
Instalace nginxu pro distribuci souborů
apt install nginx
Upravíme výchozí virtualhost - /etc/nginx/sites-available/default
:
server {
listen *:80;
listen [::]:80;
server_name demo;
location / {
root /var/www/public;
}
location /api/ {
proxy_pass http://localhost:8080;
}
}
Rovnou jsme si udělali přípravu proxy pro přístup k API, které budeme spouštět před uploadem souborů.
Přidání repozitáře na počítači (testujeme lokálně)
Do souboru /etc/apt/sources.list.d/demo.list
vložíme:
deb [signed-by=/var/www/public/apt.asc] http://localhost stable main
A spustíme apt update
:
$ apt update
Hit:1 http://localhost stable InRelease
Hit:2 http://security.debian.org/debian-security bookworm-security InRelease
Hit:3 http://deb.debian.org/debian bookworm InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
Nyní máme repozitář v provozním stavu a pustíme se do přípravy API pro upload nových kusů.
Aptly API
Spustíme aptly API server:
/usr/bin/aptly api serve -listen=":8080"
Upload balíčku a publikace repozitáře
Nahrajeme první balíček:
curl -f -s -S -X POST -F file=@demo_1.deb http://localhost/api/files/upload
Řekneme Aptly, aby si přidal do databáze nové soubory:
curl -f -s -S -X POST http://localhost/api/repos/demo/file/upload
A vypublikujeme repozitář:
curl -f -s -S -X PUT -H 'Content-Type: application/json' --data '{}' http://localhost/api/publish/:./stable
Aptly nám každý den pomáhá spravovat velké množství serverů, rychle distribuovat nové aplikace a my na něj nedáme dopustit. V roce 2020 to s jeho vývojem sice nevypadalo dobře, ale nyní se aptly chytl nový člověk a postupně jej posouvá dál, za což jsme rádi.