From 9631ec9a92eaf63a88eb74952372003e631c4d19 Mon Sep 17 00:00:00 2001 From: Jens Reinemann Date: Sun, 17 May 2026 22:51:07 +0200 Subject: [PATCH] chore: ungestagede Aenderungen und neue Docs committen --- .github/prompts/nextstep.prompt.md | 6 +- .github/skills/vps-deploy/SKILL.md | 8 +- .../app/ui/settings/SettingsScreen.kt | 16 +- docs/server.md | 302 ++++++++++++++++++ inventar.md | 110 +++++++ 5 files changed, 431 insertions(+), 11 deletions(-) create mode 100644 docs/server.md create mode 100644 inventar.md diff --git a/.github/prompts/nextstep.prompt.md b/.github/prompts/nextstep.prompt.md index 1fa16a2..7c6b5f9 100644 --- a/.github/prompts/nextstep.prompt.md +++ b/.github/prompts/nextstep.prompt.md @@ -46,7 +46,11 @@ Die Ausgabe hat das Format: `# [] (Order: )` ## Schritt 2 – Board-Status aktualisieren -Setze den Board-Status auf **"In Progress"**. +Setze den Board-Status auf **"In Progress"**: + +```powershell +& ".github/skills/gh-tickets/set-board-status.ps1" -IssueNumber -Status InProgress +``` ## Schritt 3 – Weiterleitung anhand des Typs diff --git a/.github/skills/vps-deploy/SKILL.md b/.github/skills/vps-deploy/SKILL.md index 8b2b44d..aa94e64 100644 --- a/.github/skills/vps-deploy/SKILL.md +++ b/.github/skills/vps-deploy/SKILL.md @@ -18,9 +18,9 @@ Deployt den Bollwerk Ktor-Server auf den 1984 Hosting VPS in Island. | IP | `195.246.231.210` | | DNS PTR | vps-195-246-231-210.1984.is | | OS | Debian 12 (Bookworm) | -| RAM | 1024 MB | +| RAM | 2048 MB (Upgrade Mai 2026) | | CPU | 1 | -| Disk | 25 GB SSD | +| Disk | 50 GB SSD (Upgrade Mai 2026) | | Transfer | 1 TB/Monat | | Docker | Docker CE 29.x + docker-compose-plugin | | App-Verzeichnis | `/opt/krisenvorrat/` | @@ -96,10 +96,10 @@ FROM eclipse-temurin:21-jre-alpine WORKDIR /app COPY server.jar server.jar EXPOSE 8080 -ENTRYPOINT ["java", "-Xmx384m", "-jar", "server.jar"] +ENTRYPOINT ["java", "-Xmx768m", "-jar", "server.jar"] ``` -**Hinweis:** `-Xmx384m` begrenzt den JVM-Heap, weil der VPS nur 1 GB RAM hat. +**Hinweis:** `-Xmx768m` begrenzt den JVM-Heap (VPS hat 2 GB RAM seit Upgrade Mai 2026). ### docker-compose.yml (`/opt/krisenvorrat/docker-compose.yml`) diff --git a/app/src/main/java/de/bollwerk/app/ui/settings/SettingsScreen.kt b/app/src/main/java/de/bollwerk/app/ui/settings/SettingsScreen.kt index 96d5e25..65e237e 100644 --- a/app/src/main/java/de/bollwerk/app/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/de/bollwerk/app/ui/settings/SettingsScreen.kt @@ -432,7 +432,7 @@ internal fun SettingsScreen( style = MaterialTheme.typography.bodyMedium ) Text( - text = "v${BuildConfig.VERSION_NAME} (Build ${BuildConfig.VERSION_CODE})", + text = "Version ${BuildConfig.VERSION_NAME}.${BuildConfig.VERSION_CODE}", style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant ) @@ -441,11 +441,15 @@ internal fun SettingsScreen( Spacer(modifier = Modifier.height(8.dp)) when (val s = updateState.status) { - is UpdateStatus.Available -> Text( - text = "Update v${s.versionName} verfügbar", - style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.primary - ) + is UpdateStatus.Available -> TextButton( + onClick = updateViewModel::startDownload + ) { + Text( + text = "Update v${s.versionName} verfügbar – jetzt installieren", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.primary + ) + } is UpdateStatus.Checking -> Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp) diff --git a/docs/server.md b/docs/server.md new file mode 100644 index 0000000..bedb146 --- /dev/null +++ b/docs/server.md @@ -0,0 +1,302 @@ +# VPS Server-Dokumentation + +> Letzte Aktualisierung: Mai 2026 +> Zweck: Vollständige Beschreibung der Server-Infrastruktur für eine Neuaufsetzen falls nötig. + +--- + +## Hosting & Hardware + +| Eigenschaft | Wert | +|--------------|-------------------------------------------| +| Anbieter | 1984 Hosting (1984.is), Reykjavik, Island | +| VPS-Name | vpshoxc2sc | +| IP | `195.246.231.210` | +| DNS PTR | vps-195-246-231-210.1984.is | +| RAM | 2048 MB (Upgrade Mai 2026) | +| CPU | 1 vCore | +| Disk | 50 GB SSD (Upgrade Mai 2026) | +| Transfer | 1 TB/Monat | + +--- + +## Betriebssystem + +| Eigenschaft | Wert | +|-------------|-----------------------------| +| OS | Debian GNU/Linux 12 (Bookworm) | +| Kernel | 6.1.0-30-amd64 | + +--- + +## Installierte System-Software + +| Paket / Dienst | Version | Installationsweg | Systemd-Service | +|----------------|-------------|------------------|---------------------| +| Docker CE | 29.5.0 | apt (Docker repo) | `docker.service` | +| Docker Compose | v5.1.3 | docker-compose-plugin (apt) | – | +| Caddy | v2.11.3 | apt (caddy repo) | `caddy.service` | +| OpenSSH Server | Debian-Standard | apt | `ssh.service` | +| cron | Debian-Standard | apt | `cron.service` | +| rsyslog | Debian-Standard | apt | `rsyslog.service` | + +### Docker installieren (bei Neuaufsetzen) + +```bash +# Docker GPG Key & Repo +install -m 0755 -d /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc +echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable" \ + > /etc/apt/sources.list.d/docker.list +apt-get update +apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin +``` + +### Caddy installieren (bei Neuaufsetzen) + +```bash +apt-get install -y debian-keyring debian-archive-keyring apt-transport-https curl +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \ + | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg +curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \ + | tee /etc/apt/sources.list.d/caddy-stable.list +apt-get update +apt-get install -y caddy +``` + +--- + +## Verzeichnisstruktur + +``` +/opt/ +├── krisenvorrat/ # Bollwerk App-Stack +│ ├── Dockerfile # Bollwerk-Server Image +│ ├── docker-compose.yml # App + DB + Backup +│ ├── server.jar # Aktuelles Server-JAR +│ ├── data/ # App-Datendateien (persistent) +│ └── backup/ +│ ├── Dockerfile # Backup-Container Image +│ └── backup.sh # Backup-Script (pg_dump + Rotation) +└── mail/ + └── docker-compose.yml # Mail-Stack (Maddy + Snappymail) + +/etc/caddy/ +└── Caddyfile # Reverse-Proxy Konfiguration + +/etc/letsencrypt/ +└── live/mail.bollwerk.online/ + ├── fullchain.pem # TLS-Zertifikat (Mail) + └── privkey.pem # TLS-Privat-Key (Mail) +``` + +--- + +## App-Stack: `/opt/krisenvorrat/` + +### docker-compose.yml + +```yaml +services: + db: + image: postgres:17-alpine + container_name: bollwerk-db + restart: unless-stopped + environment: + POSTGRES_DB: bollwerk + POSTGRES_USER: bollwerk + POSTGRES_PASSWORD: + ports: + - "127.0.0.1:5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + + bollwerk: + build: . + container_name: bollwerk-server + restart: unless-stopped + ports: + - "127.0.0.1:8080:8080" + environment: + - BOLLWERK_JWT_SECRET= + - BOLLWERK_APP_VERSION_CODE= + - BOLLWERK_APP_VERSION_NAME= + - BOLLWERK_DB_URL=jdbc:postgresql://db:5432/bollwerk + - BOLLWERK_DB_USER=bollwerk + - BOLLWERK_DB_PASSWORD= + volumes: + - backup_data:/backups:ro + - ./data:/app/data + depends_on: + - db + + backup: + build: ./backup + container_name: bollwerk-backup + restart: unless-stopped + environment: + - POSTGRES_HOST=db + - POSTGRES_DB=bollwerk + - POSTGRES_USER=bollwerk + - POSTGRES_PASSWORD= + volumes: + - backup_data:/backups + depends_on: + - db + +volumes: + pgdata: + backup_data: +``` + +### Dockerfile (Server) + +```dockerfile +FROM eclipse-temurin:21-jre-alpine +WORKDIR /app +COPY server.jar server.jar +EXPOSE 8080 +ENTRYPOINT ["java", "-Xmx768m", "-jar", "server.jar"] +``` + +> **Hinweis:** `-Xmx768m` belässt ~1,2 GB für OS + andere Container. Bei weiterem Upgrade ggf. erhöhen. + +### Backup-Container + +- **Image-Basis:** Alpine (minimal) +- **Funktion:** Regelmäßiger `pg_dump` der PostgreSQL-Datenbank +- **Deduplizierung:** MD5-Checksumme des Dump-Inhalts (ohne Timestamps) – kein Backup bei unveränderten Daten +- **Rotation:** Älteste `.sql.gz`-Dateien werden gelöscht, sobald `/backups/` 1 GB überschreitet +- **Speicherort:** Docker-Volume `backup_data`, eingebunden in `/backups/` + +--- + +## Mail-Stack: `/opt/mail/` + +### docker-compose.yml + +```yaml +services: + maddy: + image: foxcpp/maddy:0.7 + container_name: maddy + restart: unless-stopped + hostname: mail.bollwerk.online + ports: + - 25:25 # SMTP (eingehend) + - 465:465 # SMTPS + - 587:587 # SMTP Submission + - 143:143 # IMAP + - 993:993 # IMAPS + volumes: + - maddy_data:/data + - /etc/letsencrypt/live/mail.bollwerk.online/fullchain.pem:/data/tls/fullchain.pem:ro + - /etc/letsencrypt/live/mail.bollwerk.online/privkey.pem:/data/tls/privkey.pem:ro + - /etc/letsencrypt/archive:/etc/letsencrypt/archive:ro + environment: + - MADDY_HOSTNAME=mail.bollwerk.online + - MADDY_DOMAIN=bollwerk.online + + snappymail: + image: djmaze/snappymail:latest + container_name: snappymail + restart: unless-stopped + ports: + - 127.0.0.1:8888:8888 + volumes: + - snappymail_data:/var/lib/snappymail + +volumes: + maddy_data: + snappymail_data: +``` + +> **TLS-Zertifikate:** Liegen unter `/etc/letsencrypt/`. Wurden vermutlich per `certbot` oder Caddy ausgestellt. Bei Neuaufsetzen: `certbot certonly --standalone -d mail.bollwerk.online` (während Caddy gestoppt ist). + +--- + +## Reverse Proxy: Caddy + +**Konfigurationsdatei:** `/etc/caddy/Caddyfile` + +``` +bollwerk.online { + reverse_proxy localhost:8080 { + header_up X-Forwarded-Proto {scheme} + header_up X-Forwarded-Host {host} + } +} + +mail.bollwerk.online { + reverse_proxy localhost:8888 { + header_up X-Forwarded-Proto {scheme} + header_up X-Forwarded-Host {host} + } +} +``` + +- Caddy übernimmt automatisch TLS via Let's Encrypt für `bollwerk.online` und `mail.bollwerk.online` +- Der Bollwerk-Server ist nur lokal auf Port 8080 gebunden (nicht direkt von außen erreichbar) +- Snappymail-Webmail ist nur lokal auf Port 8888 gebunden + +--- + +## Netzwerk & Ports + +| Port | Protokoll | Dienst | Erreichbarkeit | +|------|-----------|---------------------|----------------| +| 22 | TCP | SSH | Extern | +| 80 | TCP | Caddy (HTTP→HTTPS) | Extern | +| 443 | TCP | Caddy (HTTPS) | Extern | +| 25 | TCP | Maddy SMTP | Extern | +| 143 | TCP | Maddy IMAP | Extern | +| 465 | TCP | Maddy SMTPS | Extern | +| 587 | TCP | Maddy Submission | Extern | +| 993 | TCP | Maddy IMAPS | Extern | +| 5432 | TCP | PostgreSQL | Nur lokal (127.0.0.1) | +| 8080 | TCP | Bollwerk-Server | Nur lokal (127.0.0.1) | +| 8888 | TCP | Snappymail | Nur lokal (127.0.0.1) | + +--- + +## SSH-Zugang + +```bash +ssh root@195.246.231.210 +# Key: Ed25519, Fingerprint: SHA256:J/qjVt9r8CqnoshZFQWutau+3KG7JxDzRLHPyX41+gA +``` + +> **Achtung:** `PasswordAuthentication yes` und `PermitRootLogin yes` sind aktiv. Bei Neuaufsetzen empfohlen: `PasswordAuthentication no` setzen, sobald SSH-Key-Zugang bestätigt ist. + +--- + +## Neuaufsetzen: Schritt-für-Schritt + +1. **VPS bestellen** bei 1984.is (Debian 12, min. 2 GB RAM, 50 GB SSD) +2. **SSH-Key hinterlegen** im 1984-Panel oder beim ersten Login +3. **System aktualisieren:** `apt-get update && apt-get upgrade -y` +4. **Docker installieren** (siehe oben) +5. **Caddy installieren** (siehe oben) +6. **Caddyfile anlegen** unter `/etc/caddy/Caddyfile` (Inhalt siehe oben) +7. **Caddy starten:** `systemctl enable --now caddy` +8. **TLS-Zertifikat für Mail holen** (optional, falls Caddy es nicht übernimmt): + ```bash + apt-get install -y certbot + systemctl stop caddy + certbot certonly --standalone -d mail.bollwerk.online + systemctl start caddy + ``` +9. **App-Verzeichnis anlegen:** + ```bash + mkdir -p /opt/krisenvorrat/backup /opt/krisenvorrat/data + ``` +10. **Dateien hochladen:** `Dockerfile`, `docker-compose.yml`, `backup/Dockerfile`, `backup/backup.sh`, `server.jar` +11. **Secrets in `docker-compose.yml` eintragen** (`BOLLWERK_JWT_SECRET`, Passwörter) +12. **App-Stack starten:** `cd /opt/krisenvorrat && docker compose up -d --build` +13. **Mail-Verzeichnis anlegen:** `mkdir -p /opt/mail` +14. **Mail `docker-compose.yml` hochladen** und starten: `cd /opt/mail && docker compose up -d` +15. **Backup aus altem Server wiederherstellen** (falls vorhanden): + ```bash + # .sql.gz aus backup_data-Volume in neuen DB-Container importieren + gunzip -c backup.sql.gz | docker exec -i bollwerk-db psql -U bollwerk bollwerk + ``` diff --git a/inventar.md b/inventar.md new file mode 100644 index 0000000..e7685f6 --- /dev/null +++ b/inventar.md @@ -0,0 +1,110 @@ +# Bollwerk – Vorratsinventar + +> Stand: Mai 2026 +> Quelle: handschriftliche Notiz, digitalisiert und ergänzt + +--- + +## Getreide & Hülsenfrüchte + +| Artikel | Menge | Jahrgang / MHD | Lagerung | Notizen | +| --- | --- | --- | --- | --- | +| Dinkelkorn | ~16 Beutel | von 2019 | Vakuumbeutel | | +| Weizen (Naturland) | 36 kg | von 2023 | | | +| Dinkel | 40 kg | von 2023 | | | +| Bio-Weizen | 18 kg | von 2019 | | | +| Bio-Weizen | 200 kg | 05/2026 | Kunststoffbehälter, O₂-Absorber, Trockenmittel | lose, luftdicht | +| Grüne Erbsen | 10 kg | von 2019 | | | +| Gelbe Schälerbsen | 10 kg | von 2019 | | | +| Berglinsen (1 kg) | 1 Pkg. | MHD 2021 | | **abgelaufen** | +| Berglinsen (500 g) | 4 Pkg. | MHD 2023 | | **abgelaufen** | +| Weiße Bohnen | 2 Pkg. | MHD 2022 | | **abgelaufen** | +| Sojamehl (6-L-Behälter) | 7 | MHD 2023 | | **abgelaufen** | +| Sojamehl (1-L-Behälter) | 3 | von 2021 | | **abgelaufen** | +| Jodsalz | 25 kg | | | | + +--- + +## Konserven + +| Artikel | Menge | MHD | Notizen | +| --- | --- | --- | --- | +| Kondensmilch gezuckert (Dovgan) | 88 Dosen | MHD prüfen | | +| Corned Beef (Exeter) | 48 Dosen | MHD prüfen | | +| Geschälte Tomaten | 2 × 2,5 kg | **abgelaufen** | | +| Tomatenmark (200 g) | 24 | **abgelaufen** | | +| Sardinen | 5 | **abgelaufen** | | +| Heringsfilet in Tomatensoße | 11 | **abgelaufen** | | +| Thunfisch groß (900 g) | 3 | **abgelaufen** | | +| Thunfisch klein | 9 | **abgelaufen** | | +| Brathering Filet | 2 | **abgelaufen** | | +| Dosenbrot | 6 | **abgelaufen** | | + +--- + +## Öle & Fette + +| Artikel | Menge | MHD | Notizen | +| --- | --- | --- | --- | +| Olivenöl (750 ml) | 3 | 2022 | **abgelaufen** | +| Avocadoöl (250 ml) | 3 | 2026 | läuft bald ab – prüfen | +| Sonnenblumenöl (1 L) | 3 | 2021 | **abgelaufen** | +| Sonnenblumenöl (500 ml) | 1 | 2023 | **abgelaufen** | + +--- + +## Getränke & Ergänzung + +| Artikel | Menge | MHD | Notizen | +| --- | --- | --- | --- | +| Instant-Kaffee | 12 | 2024 | **abgelaufen** | +| Trek'N'Eat Peronin | 8 | 2024 | **abgelaufen** | +| Vitamine | 3 × 240 + 2 × 120 = 960 Stk. | | | + +--- + +## Notfallrationen + +| Artikel | Menge | Produktion | MHD | Notizen | +| --- | --- | --- | --- | --- | +| Conserva-Set (à 2.300 kcal/Tag) | 30 Manntage | | | [conserva.de](https://www.conserva.de) | +| NRG-5 Katadyn (à 2.300 kcal/Tag) | 96 Tagesrationen (4 × 24) | April 2026 | April 2036 | | +| NRG-5 Katadyn (Altbestand) | 19 Tagesrationen (5 verbraucht) | 2019 | ca. 2029 | | +| **NRG-5 gesamt** | **115 Tagesrationen = 264.500 kcal** | | | | + +--- + +## Hygiene & Desinfektion + +| Artikel | Menge | Notizen | +| --- | --- | --- | +| Shampoo Mini | 50 × 20 ml | | +| Ethanol | 30 × 1 L | | +| Isopropanol | 4 × 1 L | | +| Methanol | 1 L | | +| Desinfektionsmittel | 5 × 1 L | | + +--- + +## Brennstoffe + +| Artikel | Menge | Notizen | +| --- | --- | --- | +| Petroleum | 50 L | | + +--- + +## Kommunikation & Ausrüstung + +| Artikel | Menge | Notizen | +| --- | --- | --- | +| PMR-Funkgerät (Midland G9 Pro) | 2 | | + +--- + +## Hinweise + +- **Dovgan Kondensmilch & Exeter Corned Beef**: MHD direkt auf der Dose prüfen und nachtragen. +- **Avocadoöl**: MHD 2026 – zeitnah verbrauchen oder ersetzen. +- Viele Fisch-/Ölkonserven sind abgelaufen – Qualität prüfen. Trockenwaren (Getreide, Hülsenfrüchte) sind in guter Lagerung oft Jahre über MHD nutzbar. +- Weitere Artikel (Medikamente, Wasser, Beleuchtung) können später über die App erfasst werden.