small www

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-06 23:20:37 +02:00
1 parent 3d6c49df65
commit fda15b194b
7 files changed
+336 -72

No files matched your search

+83 -26
View File
@@ -1,6 +1,6 @@
# Rust Package Builder
Minimalny kontener, który cyklicznie sprawdza branch Git, buduje projekt Rust i publikuje podpisane repozytoria APT oraz RPM/DNF.
Minimalny automat Docker, który cyklicznie sprawdza branch Git, buduje projekt Rust i publikuje podpisane repozytoria APT oraz RPM/DNF. Projekt zawiera również mały, utwardzony serwer HTTP udostępniający gotowe repozytorium i stronę z instrukcją instalacji.
## Obsługiwane cele
@@ -26,14 +26,40 @@ Nie utrzymuje drugiej kopii konfiguracji systemd RustProxy. Wersja i nazwa binar
## Uruchomienie
Najprostszy wariant wymaga ustawienia tylko dwóch wartości:
Ustawiasz ręcznie tylko dwie wartości:
```bash
cp .env.example .env
# edytuj .env i ustaw SOURCE_REPO oraz REPOSITORY_URL
nano .env
```
Przykład dla serwera `192.168.1.100`:
```env
SOURCE_REPO=https://git.linuxiarz.pl/gru/RustProxy.git
REPOSITORY_URL=http://192.168.1.100
```
Następnie:
```bash
./start.sh
```
Jeżeli w `REPOSITORY_URL` nie podasz portu, `start.sh` automatycznie ustawi `18765` i zapisze efektywny adres, np.:
```text
http://192.168.1.100:18765
```
Jeżeli chcesz inny port, wystarczy wpisać go bezpośrednio w adresie:
```env
REPOSITORY_URL=http://192.168.1.100:23456
```
Nie trzeba ustawiać osobnego `HTTP_PORT` ręcznie — skrypt pobierze go z adresu. `HTTP_PORT` jest zapisywany pomocniczo do `.env`, aby Compose zachował tę samą konfigurację.
`start.sh` automatycznie:
- sprawdza Docker i Docker Compose,
@@ -41,35 +67,57 @@ cp .env.example .env
- buduje obraz buildera,
- przy pierwszym uruchomieniu generuje trwały klucz GPG RSA 3072 bez hasła,
- zapisuje klucz prywatny jako `gpg/private-key.asc`, publiczny jako `gpg/public-key.asc` oraz fingerprint jako `gpg/fingerprint`,
- przy kolejnych uruchomieniach ponownie używa tego samego klucza,
- uruchamia usługę przez `docker compose up -d`,
- builder natychmiast sprawdza repozytorium Git i po udanym buildzie publikuje APT oraz RPM/DNF.
- przy kolejnych uruchomieniach używa tego samego klucza,
- uruchamia builder i mikroserwer HTTP,
- builder natychmiast sprawdza repozytorium Git i po udanym buildzie publikuje APT oraz RPM/DNF,
- strona główna HTTP automatycznie pokazuje instrukcję instalacji i linki do klucza/metadanych.
Można też uruchomić bez wcześniejszego tworzenia `.env`:
```bash
SOURCE_REPO=https://git.linuxiarz.pl/gru/RustProxy.git \
REPOSITORY_URL=https://packages.linuxiarz.pl \
REPOSITORY_URL=http://192.168.1.100 \
./start.sh
```
W takim przypadku `start.sh` zapisze te dwie wartości do `.env`.
## Mikro HTTP
Publiczny katalog repozytorium:
Repozytorium jest wystawiane przez osobny kontener `repository-http` oparty o `nginxinc/nginx-unprivileged:stable-alpine-slim`.
Domyślnie:
```text
./data/repository/
http://ADRES_SERWERA:18765/
```
Wystaw ten katalog przez nginx/RustProxy/Apache pod adresem z `REPOSITORY_URL`. Builder celowo nie uruchamia własnego HTTP ani TLS.
Serwer HTTP jest celowo bardzo prosty:
RustProxy 0.26.6 wymaga podczas builda Python 3.10+; obraz zawiera Python 3.11 i ustawia `RUST_PROXY_PYTHON=/usr/bin/python3.11`.
- działa jako użytkownik nieuprzywilejowany,
- kontener ma `cap_drop: ALL`,
- ma `no-new-privileges`,
- root filesystem jest read-only,
- repozytorium jest montowane read-only,
- obsługuje wyłącznie `GET` i `HEAD`,
- nie pozwala na upload,
- nie pokazuje listingów katalogów,
- blokuje pliki ukryte,
- dodaje podstawowe nagłówki bezpieczeństwa,
- posiada `/healthz`,
- logi idą do `docker compose logs`.
### Klucz GPG
Przed pierwszym udanym buildem `/` wyświetla prostą informację, że repozytorium jest inicjalizowane. Po publikacji builder atomowo podmienia stronę na właściwą instrukcję instalacji.
### HTTPS
Wbudowany mikroserwer świadomie obsługuje tylko HTTP. Jeżeli `REPOSITORY_URL` zaczyna się od `https://`, zakładane jest, że przed nim stoi zewnętrzny reverse proxy/TLS (np. RustProxy/nginx/Caddy). Sam builder nadal wystawia lokalny HTTP na porcie `18765` lub `HTTP_PORT`.
Dla kompletnego uruchomienia bez reverse proxy użyj `http://IP_LUB_HOST`.
## Klucz GPG
Klucz jest generowany tylko wtedy, gdy `gpg/private-key.asc` nie istnieje. Nie usuwaj katalogu `gpg/` po publikacji repozytorium: zmiana klucza spowoduje, że klienci z wcześniej zainstalowanym kluczem przestaną ufać nowym podpisom.
Do backupu wystarczy zachować co najmniej:
Do backupu zachowaj co najmniej:
```text
gpg/private-key.asc
@@ -87,11 +135,12 @@ SOURCE_REPO
REPOSITORY_URL
```
Domyślne:
Domyślne / automatyczne:
```text
SOURCE_BRANCH=master
POLL_INTERVAL=300
HTTP_PORT=18765
REPO_DISTRIBUTION=stable
REPO_COMPONENT=main
PACKAGE_RELEASE=auto
@@ -100,17 +149,17 @@ GPG_PRIVATE_KEY_FILE=/run/secrets/gpg/private-key.asc
GPG_PASSPHRASE_FILE=/run/secrets/gpg/passphrase
```
`GPG_PASSPHRASE_FILE` nie musi istnieć dla klucza bez hasła. `GPG_KEY_ID` może być podany przez ENV; jeśli go brak, builder wybiera pierwszy zaimportowany klucz prywatny.
`GPG_PASSPHRASE_FILE` nie musi istnieć dla automatycznie generowanego klucza bez hasła. `GPG_KEY_ID` może być podany przez ENV; jeśli go brak, builder wybiera pierwszy zaimportowany klucz prywatny.
## Dane trwałe
```text
/var/lib/package-builder/
├── aptly/ # baza/pool aptly
├── cargo/ # registry + target cache
├── aptly/
├── cargo/
├── packages/
│ ├── deb/ # historia zbudowanych DEB
│ └── rpm/x86_64/ # historia zbudowanych RPM
│ ├── deb/
│ └── rpm/x86_64/
├── repository/
│ ├── current -> releases/<build>
│ ├── apt -> current/apt
@@ -137,14 +186,22 @@ clone -> cargo build --release -> nFPM DEB/RPM -> podpisy -> aptly -> createrepo
Publiczny symlink `repository/current` jest podmieniany dopiero na końcu. Błąd kompilacji, pakowania, podpisu lub generowania metadata nie przełącza publicznego repozytorium. `last_commit` jest zapisywany dopiero po udanej publikacji, więc nieudany commit zostanie ponowiony w następnym cyklu.
Kolejne snapshoty w `repository/releases/` używają hardlinków do niezmienionych plików poprzedniego snapshotu, więc zachowanie historii nie oznacza pełnej kopii wszystkich paczek przy każdym buildzie.
Kolejne snapshoty w `repository/releases/` używają hardlinków do niezmienionych plików poprzedniego snapshotu.
## Podpisy
- DEB: podpis GPG nFPM (`_gpgorigin`) oraz podpisane `Release.gpg`/`InRelease` przez aptly.
- RPM: podpis GPG pakietu nFPM.
- RPM metadata: `repodata/repomd.xml.asc`; instrukcja używa `repo_gpgcheck=1` i `gpgcheck=1`.
- publiczny klucz: `https://.../repo-key.gpg` jako ASCII-armored OpenPGP, zgodny z `gpg --dearmor` i `rpm --import`.
- publiczny klucz: `http(s)://.../repo-key.gpg` jako ASCII-armored OpenPGP, zgodny z `gpg --dearmor` i `rpm --import`.
## Logi i kontrola
```bash
docker compose logs -f rust-package-builder
docker compose logs -f repository-http
curl -f http://127.0.0.1:18765/healthz
```
## Test plików dostarczonego RustProxy
@@ -153,10 +210,6 @@ Kolejne snapshoty w `repository/releases/` używają hardlinków do niezmieniony
./tests/check-rustproxy-source.sh /sciezka/do/RustProxy
```
## HTTP
Builder nie uruchamia serwera HTTP i nie obsługuje TLS. Generuje katalog `repository/` oraz prosty `index.html` z instrukcją instalacji dopasowaną do `REPOSITORY_URL` i nazwy pakietu.
## Własny klucz GPG (opcjonalnie)
Jeżeli zamiast automatycznie generowanego klucza chcesz użyć własnego, umieść go przed pierwszym `./start.sh` jako:
@@ -173,3 +226,7 @@ chmod 600 gpg/private-key.asc
```
`start.sh` wykryje istniejący klucz i nie wygeneruje nowego. Klucz prywatny nie jest kopiowany do obrazu. Kontener otrzymuje katalog `gpg/` wyłącznie jako read-only mount `/run/secrets/gpg`.
## Rocky Linux 9 / pakiety bazowe
Dockerfile używa `dnf --allowerasing`, ponieważ obrazy Rocky Linux 9 mogą zawierać `coreutils-single` i `curl-minimal`. Podczas budowy są one zastępowane pełnymi pakietami `coreutils` i `curl`, wymaganymi przez builder.