bollwerk/docs/server.md

12 KiB
Raw Blame History

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)

# 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)

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

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)

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

# 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

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

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):
    apt-get install -y certbot
    systemctl stop caddy
    certbot certonly --standalone -d mail.bollwerk.online
    systemctl start caddy
    
  9. App-Verzeichnis anlegen:
    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):
    # .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