bollwerk/docs/server.md

367 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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` |
| Forgejo | latest | Docker (codeberg.org/forgejo/forgejo) | (Docker) |
| 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/
├── bollwerk/ # Bollwerk App-Stack
│ ├── Dockerfile # Bollwerk-Server Image
│ ├── docker-compose.yml # App + DB + Backup + Forgejo
│ ├── server.jar # Aktuelles Server-JAR
│ ├── data/ # App-Datendateien (persistent)
│ ├── forgejo/ # Forgejo-Daten (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/bollwerk/`
### 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
forgejo:
image: codeberg.org/forgejo/forgejo:latest
container_name: bollwerk-forgejo
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__server__DOMAIN=git.bollwerk.online
- FORGEJO__server__ROOT_URL=https://git.bollwerk.online/
- FORGEJO__server__SSH_PORT=2222
- FORGEJO__server__SSH_LISTEN_PORT=22
- FORGEJO__service__DISABLE_REGISTRATION=true
volumes:
- ./forgejo:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
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/`
### Forgejo (Git-Server)
- **Image:** `codeberg.org/forgejo/forgejo:latest`
- **Domain:** `git.bollwerk.online`
- **Web-UI:** Port 3000 (nur lokal, Caddy reverse-proxied auf HTTPS)
- **SSH-Git:** Port 2222 (extern erreichbar)
- **Daten:** `/opt/bollwerk/forgejo/` (bind-mount)
- **Datenbank:** SQLite (in `/data/forgejo/forgejo.db` innerhalb des Containers)
- **Registrierung:** Deaktiviert (`DISABLE_REGISTRATION=true`)
#### Ersteinrichtung nach Start
1. `https://git.bollwerk.online/` aufrufen Forgejo zeigt den Setup-Wizard
2. Einstellungen im Wizard:
- **Site Title:** Bollwerk Git
- **Admin-User:** Benutzername und Passwort setzen
- **E-Mail:** SMTP über `mail.bollwerk.online:587` (optional, kann später)
3. Nach Ersteinrichtung: Repo anlegen, Test-Push via HTTPS und SSH
#### Git-Clone-URLs
```bash
# HTTPS
git clone https://git.bollwerk.online/<user>/<repo>.git
# SSH (Port 2222)
git clone ssh://git@git.bollwerk.online:2222/<user>/<repo>.git
# oder in ~/.ssh/config:
# Host git.bollwerk.online
# Port 2222
# User git
```
---
## 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}
}
}
git.bollwerk.online {
reverse_proxy localhost:3000 {
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`, `git.bollwerk.online` und `mail.bollwerk.online`
- Der Bollwerk-Server ist nur lokal auf Port 8080 gebunden (nicht direkt von außen erreichbar)
- Forgejo ist nur lokal auf Port 3000 gebunden (HTTPS via Caddy, SSH-Git direkt auf Port 2222)
- 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 |
| 2222 | TCP | Forgejo SSH (Git) | 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) |
| 3000 | TCP | Forgejo (Web UI) | 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/bollwerk/backup /opt/bollwerk/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/bollwerk && 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
```