Installation

Diese Anleitung beschreibt die Installation des Vogelschlagmelders auf einem Linux-Server – wahlweise mit Docker (empfohlen) oder als manuelle Installation ohne Docker.

Installation mit Docker

Voraussetzungen

  • Ein Linux-Server (z. B. Debian, Ubuntu) mit root- oder sudo-Zugang

  • Eine öffentliche IP-Adresse oder eine Domain, unter der der Dienst erreichbar sein soll

  • Docker und Docker Compose müssen installiert sein

Docker installieren

Falls Docker noch nicht installiert ist, sollte es über die offizielle Anleitung von Docker installiert werden. Die Installationsschritte unterscheiden sich je nach Linux-Distribution:

Nach der Installation den aktuellen Benutzer zur docker-Gruppe hinzufügen und prüfen, ob Docker läuft:

# Aktuellen Benutzer zur docker-Gruppe hinzufügen (Neuanmeldung nötig)
sudo usermod -aG docker $USER

Hinweis

Nach dem Hinzufügen zur docker-Gruppe muss man sich neu anmelden (oder newgrp docker ausführen), damit die Gruppenrechte greifen.

Anschließend prüfen, ob Docker korrekt installiert ist:

docker --version
docker compose version

DNS einrichten

Damit der Vogelschlagmelder unter einer eigenen Adresse erreichbar ist, muss ein A-Record beim DNS-Anbieter angelegt werden.

Beispiel: Der Melder soll unter vogelschlag.storchennest.test erreichbar sein und der Server hat die IP 203.0.113.42.

Beim DNS-Anbieter (z. B. Hetzner DNS, INWX, Cloudflare) wird folgender Eintrag angelegt:

Typ

Name

Wert

TTL

A

vogelschlag.storchennest.test

203.0.113.42

3600

Hinweis

Die DNS-Änderung kann je nach Anbieter einige Minuten bis Stunden dauern, bis sie weltweit verfügbar ist. Mit dig vogelschlag.storchennest.test oder nslookup vogelschlag.storchennest.test lässt sich der Eintrag prüfen.

Arbeitsordner anlegen

Der Vogelschlagmelder wird unter /srv/docker/ betrieben. Dort wird ein eigener Ordner angelegt:

sudo mkdir -p /srv/docker/vogelschlagmelder
sudo chown $USER:$USER /srv/docker/vogelschlagmelder
cd /srv/docker/vogelschlagmelder

Durch chown erhält der aktuelle Benutzer Schreibrechte auf den Ordner, sodass im weiteren Verlauf Dateien ohne sudo angelegt werden können.

Umgebungsvariablen konfigurieren (.env)

Die Zugangsdaten und Einstellungen werden über eine .env-Datei konfiguriert. Als Vorlage dient die Datei .env.example aus dem Repository:

# .env-Datei anlegen
nano .env

Inhalt der .env-Datei:

# ==================== Zugangsdaten ====================
# WICHTIG: Verwende sichere, einzigartige Passwörter!
# Passwörter müssen mindestens 8 Zeichen lang sein.

ADMIN_USER=admin
ADMIN_PASSWORD=CHANGEME_sicheres_passwort_hier
MELDEZENTRALE_USER=meldezentrale
MELDEZENTRALE_PASSWORD=CHANGEME_sicheres_passwort_hier

# ==================== SMTP (E-Mail) ====================
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=alerts@example.com
SMTP_STARTTLS=true

# Optionale Absender-Anpassung
FROM_EMAIL=
FROM_NAME=

# ==================== Sicherheit ====================
# Produktionsmodus: Aktiviert Secure-Cookies (erfordert HTTPS)
PRODUCTION_MODE=true

# CSRF-Secret: Zufälliger Wert, z. B. generiert mit:
#   python3 -c "import secrets; print(secrets.token_hex(32))"
CSRF_SECRET=CHANGEME_zufaelliger_wert_hier

# ==================== Let's Encrypt ====================
# E-Mail-Adresse für Let's Encrypt Zertifikatsbenachrichtigungen
LETSENCRYPT_EMAIL=admin@storchennest.test

Wichtig

Alle CHANGEME_-Werte müssen vor dem Produktiveinsatz durch sichere, einzigartige Werte ersetzt werden. Das CSRF_SECRET sollte ein langer, zufälliger Hex-String sein.

Docker Compose einrichten

Das Setup besteht aus zwei Diensten:

  • Traefik – ein Reverse-Proxy, der automatisch HTTPS-Zertifikate über Let’s Encrypt bezieht

  • Vogelschlagmelder – die eigentliche Anwendung

Traefik leitet eingehende Anfragen auf Port 80 (HTTP) und 443 (HTTPS) an den Vogelschlagmelder weiter und kümmert sich vollautomatisch um die Zertifikatsverlängerung.

Im Arbeitsordner wird die Datei docker-compose.yaml angelegt:

nano docker-compose.yaml

Inhalt:

services:
  # =========================================================================
  # Traefik – Reverse Proxy & Let's Encrypt
  # =========================================================================
  traefik:
    image: traefik:v3.6
    container_name: traefik
    restart: unless-stopped
    command:
      # Entrypoints
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # HTTP → HTTPS Redirect
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      # Let's Encrypt
      - "--certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL}"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
      # Docker Provider
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      # Logging
      - "--log.level=WARN"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./volumes/traefik/letsencrypt:/letsencrypt
    networks:
      - web

  # =========================================================================
  # Vogelschlagmelder
  # =========================================================================
  vogelschlagmelder:
    build:
      context: https://codeberg.org/nabu-jena/Vogelschlagmelder.git#main:app
      dockerfile: Dockerfile
    container_name: vogelschlagmelder
    restart: unless-stopped
    environment:
      # Credentials und Einstellungen aus der .env-Datei
      - ADMIN_USER=${ADMIN_USER:?ADMIN_USER muss gesetzt werden}
      - ADMIN_PASSWORD=${ADMIN_PASSWORD:?ADMIN_PASSWORD muss gesetzt werden}
      - MELDEZENTRALE_USER=${MELDEZENTRALE_USER:?MELDEZENTRALE_USER muss gesetzt werden}
      - MELDEZENTRALE_PASSWORD=${MELDEZENTRALE_PASSWORD:?MELDEZENTRALE_PASSWORD muss gesetzt werden}
      - SMTP_HOST=${SMTP_HOST:-smtp.example.com}
      - SMTP_PORT=${SMTP_PORT:-587}
      - SMTP_USER=${SMTP_USER:-}
      - SMTP_PASSWORD=${SMTP_PASSWORD:-}
      - SMTP_FROM=${SMTP_FROM:-}
      - SMTP_STARTTLS=${SMTP_STARTTLS:-true}
      - FROM_EMAIL=${FROM_EMAIL:-}
      - FROM_NAME=${FROM_NAME:-}
      # Sicherheitseinstellungen
      - PRODUCTION_MODE=${PRODUCTION_MODE:-true}
      - CSRF_SECRET=${CSRF_SECRET:?CSRF_SECRET muss gesetzt werden}
    volumes:
      - ./data:/app/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vogelschlagmelder.rule=Host(`vogelschlag.storchennest.test`)"
      - "traefik.http.routers.vogelschlagmelder.entrypoints=websecure"
      - "traefik.http.routers.vogelschlagmelder.tls.certresolver=letsencrypt"
      - "traefik.http.services.vogelschlagmelder.loadbalancer.server.port=8000"
    networks:
      - web

networks:
  web:
    name: web
    driver: bridge

Wichtig

Die Domain in der Zeile Host(\vogelschlag.storchennest.test`)` muss durch die eigene Domain ersetzt werden – also die, für die der DNS-A-Record angelegt wurde.

Erläuterungen:

Traefik (Reverse Proxy)

  • entrypoints – Traefik lauscht auf Port 80 (HTTP) und Port 443 (HTTPS). Alle HTTP-Anfragen werden automatisch auf HTTPS umgeleitet.

  • certificatesresolvers – Let’s Encrypt stellt automatisch ein gültiges TLS-Zertifikat für die konfigurierte Domain aus. Die HTTP-Challenge prüft dabei, ob die Domain auf diesen Server zeigt (daher muss der DNS-A-Record vorher gesetzt sein).

  • /var/run/docker.sock – Traefik erkennt über den Docker-Socket automatisch, welche Container als Webdienste erreichbar sein sollen (gesteuert über Labels).

  • ./volumes/traefik/letsencrypt – Hier werden die Zertifikate gespeichert, damit sie bei einem Neustart nicht erneut angefordert werden müssen.

Vogelschlagmelder

  • build.context – Das Docker-Image wird direkt aus dem Git-Repository auf Codeberg gebaut. Es wird kein manuelles Klonen benötigt.

  • labels – Über die Traefik-Labels wird festgelegt, unter welcher Domain der Melder erreichbar ist und dass Let’s Encrypt ein Zertifikat ausstellen soll.

  • volumes – Die Datenbank und hochgeladene Dateien werden im lokalen Ordner ./data gespeichert und bleiben bei Container-Neustarts erhalten.

  • Kein ports-Eintrag – Der Vogelschlagmelder wird nicht direkt exponiert, sondern ist nur über Traefik erreichbar. Das erhöht die Sicherheit.

Datenverzeichnis anlegen

Vor dem ersten Start muss das Datenverzeichnis manuell angelegt werden. Der Container läuft aus Sicherheitsgründen als Non-Root-User (UID 1001). Das gemountete Volume muss für diesen User beschreibbar sein:

mkdir -p data/uploads
chown -R 1001:1001 data

Warum ist das nötig?

Wird ./data per Volume in den Container gemountet, überschreibt das die im Docker-Image vorbereiteten Verzeichnisse. Existiert ./data auf dem Host noch nicht, wird es vom Docker-Daemon als root angelegt – der Container-User appuser (UID 1001) hat dann keine Schreibrechte.

Starten und Prüfen

# Image bauen und alle Container starten
docker compose up -d --build

# Logs prüfen
docker compose logs -f

Nach dem Start passiert Folgendes automatisch:

  1. Traefik startet und lauscht auf Port 80 und 443

  2. Let’s Encrypt stellt ein TLS-Zertifikat für die konfigurierte Domain aus

  3. Der Vogelschlagmelder wird gebaut und gestartet

Der Vogelschlagmelder ist anschließend unter https://vogelschlag.storchennest.test erreichbar.

Hinweis

Beim allerersten Start kann es 1–2 Minuten dauern, bis das Let’s Encrypt Zertifikat ausgestellt ist. In dieser Zeit zeigt der Browser ggf. eine Zertifikatswarnung.

Prüfen, ob alle Container laufen:

docker compose ps

Es sollten zwei Container mit dem Status Up angezeigt werden: traefik und vogelschlagmelder.

Aktualisieren

Um den Vogelschlagmelder auf die neueste Version zu aktualisieren:

cd /srv/docker/vogelschlagmelder

# Neues Image bauen und Container neu starten
docker compose up -d --build

Traefik muss dabei nicht neu gestartet werden – nur der Vogelschlagmelder-Container wird aktualisiert.

Datenbank-Migrationen werden automatisch beim Anwendungsstart durchgeführt.

Installation ohne Docker

Alternativ kann der Vogelschlagmelder auch direkt ohne Docker betrieben werden – z. B. für Entwicklungszwecke oder auf Systemen, auf denen Docker nicht verfügbar ist.

Voraussetzungen

  • Ein Linux-Server (z. B. Debian, Ubuntu) mit root- oder sudo-Zugang

  • Python 3.11 oder höher

  • Git zum Klonen des Repositories

Systempakete installieren

sudo apt update && sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip git

Repository klonen

Das Repository wird in ein Arbeitsverzeichnis geklont:

sudo mkdir -p /srv/vogelschlagmelder
sudo chown $USER:$USER /srv/vogelschlagmelder
cd /srv/vogelschlagmelder
git clone https://codeberg.org/nabu-jena/Vogelschlagmelder.git .

Durch chown erhält der aktuelle Benutzer Schreibrechte auf den Ordner, damit git clone und weitere Schritte ohne sudo funktionieren.

Python-Umgebung einrichten

Im Anwendungsverzeichnis wird eine virtuelle Python-Umgebung erstellt und die Abhängigkeiten installiert:

cd /srv/vogelschlagmelder/app
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

Datenverzeichnis anlegen

Die Anwendung speichert ihre SQLite-Datenbank und hochgeladene Dateien im Ordner data. Dieser muss eine Ebene über dem app-Verzeichnis liegen:

mkdir -p /srv/vogelschlagmelder/data/uploads

Umgebungsvariablen konfigurieren

Die Zugangsdaten und Einstellungen werden über Umgebungsvariablen gesetzt. Dafür wird eine .env-Datei im Anwendungsverzeichnis angelegt:

nano /srv/vogelschlagmelder/app/.env

Inhalt:

# ==================== Zugangsdaten ====================
ADMIN_USER=admin
ADMIN_PASSWORD=CHANGEME_sicheres_passwort_hier
MELDEZENTRALE_USER=meldezentrale
MELDEZENTRALE_PASSWORD=CHANGEME_sicheres_passwort_hier

# ==================== SMTP (E-Mail) ====================
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=alerts@example.com
SMTP_STARTTLS=true
FROM_EMAIL=
FROM_NAME=

# ==================== Sicherheit ====================
# Produktionsmodus: Aktiviert Secure-Cookies (erfordert HTTPS)
PRODUCTION_MODE=false

# CSRF-Secret: Zufälliger Wert, z. B. generiert mit:
#   python3 -c "import secrets; print(secrets.token_hex(32))"
CSRF_SECRET=CHANGEME_zufaelliger_wert_hier

# Domains, welcher erlaubt sind, iFrames einzubetten
# leer lassen für keine Einschränkung
WIDGET_ALLOWED_DOMAINS=storchennest.test

Die Umgebungsvariablen können dann geladen werden:

export $(grep -v '^#' /srv/vogelschlagmelder/app/.env | xargs)

Wichtig

Alle CHANGEME_-Werte müssen vor dem Produktiveinsatz durch sichere, einzigartige Werte ersetzt werden. Für den Produktivbetrieb mit HTTPS muss PRODUCTION_MODE auf true gesetzt werden.

Anwendung starten

Der Vogelschlagmelder wird über uvicorn gestartet:

cd /srv/vogelschlagmelder/app
source venv/bin/activate
export $(grep -v '^#' .env | xargs)
uvicorn main:app --host 0.0.0.0 --port 8000

Die Anwendung ist anschließend unter http://<Server-IP>:8000 erreichbar.

Beim ersten Start werden automatisch die Datenbank und alle benötigten Tabellen angelegt.

Hinweis

Für den Produktivbetrieb sollte ein Reverse-Proxy (z. B. Nginx oder Caddy) vorgeschaltet werden, der HTTPS terminiert. Außerdem empfiehlt es sich, die Anwendung über einen Prozessmanager wie systemd als Dienst einzurichten.

Als systemd-Dienst einrichten

Damit der Vogelschlagmelder automatisch beim Serverstart ausgeführt wird, kann eine systemd-Unit-Datei angelegt werden:

sudo nano /etc/systemd/system/vogelschlagmelder.service

Inhalt:

[Unit]
Description=Vogelschlagmelder
After=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/srv/vogelschlagmelder/app
EnvironmentFile=/srv/vogelschlagmelder/app/.env
ExecStart=/srv/vogelschlagmelder/app/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Anschließend den Dienst aktivieren und starten:

# Berechtigungen setzen
sudo chown -R www-data:www-data /srv/vogelschlagmelder

# Dienst aktivieren und starten
sudo systemctl daemon-reload
sudo systemctl enable --now vogelschlagmelder

# Status prüfen
sudo systemctl status vogelschlagmelder

Aktualisieren

Um den Vogelschlagmelder auf die neueste Version zu aktualisieren:

cd /srv/vogelschlagmelder
git pull

# Abhängigkeiten aktualisieren
source app/venv/bin/activate
pip install -r app/requirements.txt

# Dienst neu starten
sudo systemctl restart vogelschlagmelder

Datenbank-Migrationen werden automatisch beim Anwendungsstart durchgeführt.