chore: ungestagede Aenderungen und neue Docs committen

This commit is contained in:
Jens Reinemann 2026-05-17 22:51:07 +02:00
parent d00b5b245a
commit 9631ec9a92
5 changed files with 431 additions and 11 deletions

View file

@ -46,7 +46,11 @@ Die Ausgabe hat das Format: `#<Nummer> [<Typ>] <Titel> (Order: <N>)`
## Schritt 2 Board-Status aktualisieren ## 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 <N> -Status InProgress
```
## Schritt 3 Weiterleitung anhand des Typs ## Schritt 3 Weiterleitung anhand des Typs

View file

@ -18,9 +18,9 @@ Deployt den Bollwerk Ktor-Server auf den 1984 Hosting VPS in Island.
| IP | `195.246.231.210` | | IP | `195.246.231.210` |
| DNS PTR | vps-195-246-231-210.1984.is | | DNS PTR | vps-195-246-231-210.1984.is |
| OS | Debian 12 (Bookworm) | | OS | Debian 12 (Bookworm) |
| RAM | 1024 MB | | RAM | 2048 MB (Upgrade Mai 2026) |
| CPU | 1 | | CPU | 1 |
| Disk | 25 GB SSD | | Disk | 50 GB SSD (Upgrade Mai 2026) |
| Transfer | 1 TB/Monat | | Transfer | 1 TB/Monat |
| Docker | Docker CE 29.x + docker-compose-plugin | | Docker | Docker CE 29.x + docker-compose-plugin |
| App-Verzeichnis | `/opt/krisenvorrat/` | | App-Verzeichnis | `/opt/krisenvorrat/` |
@ -96,10 +96,10 @@ FROM eclipse-temurin:21-jre-alpine
WORKDIR /app WORKDIR /app
COPY server.jar server.jar COPY server.jar server.jar
EXPOSE 8080 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`) ### docker-compose.yml (`/opt/krisenvorrat/docker-compose.yml`)

View file

@ -432,7 +432,7 @@ internal fun SettingsScreen(
style = MaterialTheme.typography.bodyMedium style = MaterialTheme.typography.bodyMedium
) )
Text( Text(
text = "v${BuildConfig.VERSION_NAME} (Build ${BuildConfig.VERSION_CODE})", text = "Version ${BuildConfig.VERSION_NAME}.${BuildConfig.VERSION_CODE}",
style = MaterialTheme.typography.bodyMedium, style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
@ -441,11 +441,15 @@ internal fun SettingsScreen(
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
when (val s = updateState.status) { when (val s = updateState.status) {
is UpdateStatus.Available -> Text( is UpdateStatus.Available -> TextButton(
text = "Update v${s.versionName} verfügbar", onClick = updateViewModel::startDownload
) {
Text(
text = "Update v${s.versionName} verfügbar jetzt installieren",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.primary color = MaterialTheme.colorScheme.primary
) )
}
is UpdateStatus.Checking -> Row( is UpdateStatus.Checking -> Row(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp) horizontalArrangement = Arrangement.spacedBy(8.dp)

302
docs/server.md Normal file
View file

@ -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: <DB_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=<SECRET>
- BOLLWERK_APP_VERSION_CODE=<versionCode>
- BOLLWERK_APP_VERSION_NAME=<versionName>
- BOLLWERK_DB_URL=jdbc:postgresql://db:5432/bollwerk
- BOLLWERK_DB_USER=bollwerk
- BOLLWERK_DB_PASSWORD=<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=<DB_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
```

110
inventar.md Normal file
View file

@ -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.