1
0
Fork 0
Software für den Musikgully Hannover http://gullyman.eu/
  • Jinja 41.2%
  • Python 27.1%
  • JavaScript 12.9%
  • CSS 8.3%
  • HTML 6.1%
  • Other 4.4%
Find a file
2026-07-07 22:51:47 +02:00
files moved files 2026-07-07 22:41:30 +02:00
group_vars moved files 2026-07-07 22:41:30 +02:00
host_vars moved files 2026-07-07 22:41:30 +02:00
inventory moved files 2026-07-07 22:41:30 +02:00
publickeys moved files 2026-07-07 22:41:30 +02:00
templates moved files 2026-07-07 22:41:30 +02:00
.gitignore moved files 2026-07-07 22:41:30 +02:00
ansible.cfg moved files 2026-07-07 22:41:30 +02:00
coordinator_proxy.yml moved files 2026-07-07 22:41:30 +02:00
filebrowser.yml moved files 2026-07-07 22:41:30 +02:00
firewall.yml moved files 2026-07-07 22:41:30 +02:00
landing_page.yml moved files 2026-07-07 22:41:30 +02:00
LICENSE added license 2026-07-07 22:07:03 +02:00
monit.yml moved files 2026-07-07 22:41:30 +02:00
motd.yml moved files 2026-07-07 22:41:30 +02:00
mpd.yml moved files 2026-07-07 22:41:30 +02:00
musikgulli_web.yml moved files 2026-07-07 22:41:30 +02:00
nfs-setup.yml moved files 2026-07-07 22:41:30 +02:00
nginx.yml moved files 2026-07-07 22:41:30 +02:00
packages.yml moved files 2026-07-07 22:41:30 +02:00
README.md made readme nicer 2026-07-07 22:51:47 +02:00
requirements.yml moved files 2026-07-07 22:41:30 +02:00
site.yml moved files 2026-07-07 22:41:30 +02:00
speaker-volume.yml moved files 2026-07-07 22:41:30 +02:00
wireguard.yml moved files 2026-07-07 22:41:30 +02:00

Musikgulli Ansible Project

Dieses Repository enthält die Ansible-Konfiguration für die technische Infrastruktur des Musikgullys am Ernst-August-Platz vor dem Hauptbahnhof Hannover.

Der Musikgully, auch als „DJ Gullyman“ bekannt, ist eine Klanginstallation im öffentlichen Raum: Aus einem scheinbaren Gully vor dem Hauptbahnhof spielt tagsüber und nachts Musik aus dem Untergrund. Das Projekt geht auf die Umgestaltung des Ernst-August-Platzes um das Jahr 2000 zurück und ist als spielerische, bewusst leicht zu übersehende Kunst im Stadtraum gedacht. Weitere Informationen beschreibt Hannover.de im Artikel „Wo die Musik spielt und warum“.

Die Software in diesem Repository betreibt die Player-Systeme hinter der Installation. Sie installiert und konfiguriert MPD, verteilt die musikgulli-web Steuerung, richtet Netzwerkzugriff per WireGuard ein und überwacht die Player mit Monit. Im Betrieb schaltet der Web-Daemon automatisch zwischen Tag-, Nacht- und Sonder-Playlisten um und stellt eine einfache Web-Oberfläche für Status, Lautstärke und Zeitpläne bereit.

Lizenz und Public Code

Dieses Projekt wurde mit öffentlichen Geldern finanziert und wird deshalb im Einklang mit der Smart-City-Strategie der Landeshauptstadt Hannover als Open Source veröffentlicht. Damit folgt sie dem Grundsatz „Public Money, Public Code“: Software, die von der Allgemeinheit bezahlt wird, soll auch der Allgemeinheit zur Verfügung stehen.

Der Code steht unter der GNU General Public License v3.0. Details stehen in LICENSE.

Python-Hinweis: Für einige Ansible-Netzwerkfilter muss das Paket netaddr installiert sein.

Project Structure

ansible/
├── inventory/
│   └── hosts.yml          # Inventory file containing host definitions
├── group_vars/
│   └── players.yml        # Variables for all players
├── host_vars/
│   └── coordinator.yml    # Variables for coordinator
├── files/
│   ├── musikgulli-web/            # Web daemon (webplayers)
│   │   ├── app.py                 # Flask app + control loop
│   │   ├── requirements.txt       # Python dependencies
│   │   ├── templates/index.html   # Web UI
│   │   └── static/                # JS/CSS for the web UI
│   ├── monit-mpd-playing.sh       # Monit helper: MPD playing and queue check
│   └── monit-check-music-files.sh # Monit helper: Music files check
├── templates/
│   ├── mpd.conf.j2                # MPD configuration template
│   ├── filebrowser.service.j2     # Filebrowser systemd service
│   ├── musikgulli-web.service.j2  # musikgulli-web systemd service
│   ├── nginx-webplayers.conf.j2   # nginx location blocks (coordinator)
│   ├── nginx-monit.conf.j2        # nginx location blocks for Monit (coordinator)
│   └── monitrc-players.j2         # Monit configuration template
├── site.yml              # Main playbook
├── packages.yml          # Package management playbook
├── mpd.yml               # MPD installation and configuration
├── musikgulli_web.yml    # musikgulli-web daemon deployment (webplayers)
├── coordinator_proxy.yml # nginx reverse proxy config on the coordinator
├── monit.yml             # Monit monitoring setup
├── firewall.yml          # Firewall configuration
├── nfs-setup.yml         # NFS server/client setup
├── wireguard.yml         # Wireguard VPN configuration
└── README.md             # This file

Inventory

The inventory contains the following hosts and groups:

  • Host: coordinator

  • Group: players (parent group, targeted by mpd/firewall/monit/nfs playbooks)

    • Group: webplayers Player, gesteuert durch den dauerhaft laufenden musikgulli-web Daemon mit Web-UI

Player mit Web-Steuerung werden unter webplayers eingetragen.

Playbooks

site.yml

Main playbook for general system configuration. Includes:

  • packages.yml - Package management
  • wireguard.yml - WireGuard VPN setup (before firewall/UFW, since other playbooks open ports on wg0)
  • firewall.yml - Firewall configuration (before playbooks that open UFW ports)
  • mpd.yml - MPD installation and configuration
  • musikgulli_web.yml - musikgulli-web daemon (webplayers)
  • coordinator_proxy.yml - nginx reverse proxy config (coordinator)
  • monit.yml - Monit monitoring setup

musikgulli_web.yml

Deployt den musikgulli-web Daemon auf Hosts der Gruppe webplayers:

  • Installiert die Anwendung nach /opt/musikgulli-web (venv + App-Dateien)
  • Richtet den systemd-Service musikgulli-web.service ein (User player, Restart=always)
  • Öffnet Port 8080 auf dem Wireguard-Interface

coordinator_proxy.yml

Deployt nginx Location-Blöcke nach /etc/nginx/snippets/webplayers/ auf dem Coordinator (nginx ist dort bereits installiert, der bestehende server-Block inkludiert dieses Verzeichnis):

  • Web-UI der webplayers: erreichbar unter /players/<hostname>/
  • Monit Web-Interface aller players: erreichbar unter /monit/<hostname>/ (proxied auf die Wireguard-IP des Players, Port 2812)

packages.yml

Manages package installation:

  • Installs mpc package on all hosts
  • Installs mpd package on all hosts in the players group

monit.yml

Installs and configures Monit monitoring on players:

  • Monit package installation
  • Monitoring configuration deployment
  • Web interface setup (Port 2812, Wireguard only)
  • Helper scripts for complex checks

Abspiel-Logik

Der musikgulli-web Daemon läuft dauerhaft auf den webplayers und übernimmt die Steuerung des MPD-Players.

musikgulli-web (webplayers)

Der Daemon verbindet Web-UI und Steuerung in einem Prozess:

  • Control-Loop: prüft alle 10 Sekunden, welche Playlist laufen soll, und schaltet bei Bedarf um. Prioritäten:
    1. Für heute zugewiesene Sonder-Playlist (läuft ganztägig)
    2. Feiertag in Niedersachsen: aktuelle Playlist wird beibehalten
    3. Tag/Nacht anhand der konfigurierten Umschaltzeiten
  • Web-UI (Port 8080, HTTP, ohne Authentifizierung Zugriff nur über Wireguard bzw. den Reverse-Proxy auf dem Coordinator):
    • Anzeige des aktuellen Tracks und Play-Status
    • Lautstärke-Regler (eine globale Lautstärke, unabhängig von der Playlist)
    • Konfiguration der Umschaltzeiten Tag/Nacht (Default 08:00 / 20:00)
    • Sonder-Playlisten: Unterordner von /srv/music/Sonder können einem Datum zugewiesen werden (die Ordnernamen sind frei wählbar, das Datumsformat im Ordnernamen wird nicht mehr benötigt)
  • Konfiguration: /etc/musikgulli/config.json (wird vom Daemon über die Web-UI geschrieben)
  • Zustand: /var/lib/musikgulli/state.json (aktive Playlist; die Erkennung über die Lautstärke entfällt)
  • Logs: journald (journalctl -u musikgulli-web)

Usage

To run the main playbook:

ansible-playbook -i inventory/hosts.yml site.yml

To run against specific groups:

ansible-playbook -i inventory/hosts.yml site.yml --limit players

To manage packages:

ansible-playbook -i inventory/hosts.yml packages.yml

Monit Monitoring

Monit überwacht alle kritischen Komponenten auf den Playern und stellt ein Web-Interface zur Verfügung.

Überwachte Komponenten

System-Monitoring

  • CPU-Auslastung (Warnung > 80%, kritisch > 95%)
  • Memory-Auslastung (Warnung > 85%, kritisch > 95%)
  • Disk Space für / (Warnung < 20%, kritisch < 10%)
  • Disk Space für /srv/music (Warnung < 10%, kritisch < 5%)
  • System Load (Warnung > Anzahl CPUs * 1.5)

MPD Service

  • Prozess-Überwachung mit automatischem Restart
  • TCP Port 6600 Erreichbarkeit
  • MPD Playing Check (prüft ob Musik abgespielt wird und Titel in der Queue sind)

musikgulli-web

  • systemd Service musikgulli-web.service Status
  • HTTP-Erreichbarkeit auf Port 8080

Netzwerk & Services

  • Wireguard Interface wg0 Status
  • Verbindung zum Coordinator (Ping)
  • NFS Server (falls aktiv)

Musik-Ordner

  • Existenz von /srv/music/Tag und /srv/music/Nacht
  • Prüfung ob Dateien in den Ordnern vorhanden sind
  • Audio-Device Verfügbarkeit

Weitere Checks

  • Systemd Health (failed units)
  • Zeit-Synchronisation (NTP)

Web-Interface

Das Monit Web-Interface jedes Players ist auf zwei Wegen erreichbar:

  • Reverse Proxy (empfohlen): http://<coordinator>/monit/<hostname>/ der Coordinator proxied die Anfrage über Wireguard an den Player (siehe coordinator_proxy.yml)
  • Direkt: http://<player-wireguard-ip>:2812 (nur aus dem Wireguard-Netzwerk 10.199.0.0/24)
  • Authentifizierung: Keine Passwort-Authentifizierung erforderlich (Zugriff bereits durch Wireguard-Netzwerk beschränkt)

Inventory-Variablen

Player-Gruppe (group_vars/players.yml)

E-Mail-Alerts (optional):

monit_email_enabled: false                    # E-Mail-Alerts aktivieren/deaktivieren
monit_smtp_host: "localhost"                 # SMTP-Server
monit_smtp_port: 587                          # SMTP-Port
monit_smtp_username: "{{ vault_monit_smtp_username | default('') }}"
monit_smtp_password: "{{ vault_monit_smtp_password | default('') }}"
monit_smtp_tls: true                           # TLS verwenden
monit_email_recipient: "{{ vault_monit_email_recipient | default('admin@localhost') }}"

NFS-Konfiguration:

nfs_enabled: true                              # NFS-Server-Monitoring aktivieren/deaktivieren

Player-Hosts (inventory/hosts.yml)

Jeder Player benötigt folgende Variablen:

ansible_host: 10.199.0.101                     # IP-Adresse des Players
ansible_user: player                            # SSH-User
mpd_bind_address: 10.199.0.101                 # MPD Bind-Adresse
mpd_audio_output_type: alsa                     # Audio-Output-Typ
mpd_audio_output_device: hw:CARD=Device,DEV=0    # Audio-Device
wireguard_addresses:
  - "10.199.0.101/24"                           # Wireguard-IP-Adresse(n)

E-Mail-Alerts konfigurieren

  1. Variablen in group_vars/players.yml setzen:
monit_email_enabled: true
monit_smtp_host: "smtp.example.com"
monit_smtp_port: 587
monit_smtp_username: "{{ vault_monit_smtp_username }}"
monit_smtp_password: "{{ vault_monit_smtp_password }}"
monit_email_recipient: "alerts@example.com"
  1. Sensible Daten in Ansible Vault speichern:
ansible-vault encrypt_string 'your_password' --name 'vault_monit_smtp_password'
ansible-vault encrypt_string 'your_username' --name 'vault_monit_smtp_username'
  1. Playbook erneut ausführen:
ansible-playbook -i inventory/hosts.yml site.yml

Monit-Befehle

Auf dem Player direkt:

# Monit-Status anzeigen
monit status

# Alle Services überwachen
monit monitor all

# Service neu starten
monit restart <service-name>

# Konfiguration testen
monit -t

# Log anzeigen
tail -f /var/log/monit.log

Automatische Aktionen

Monit führt automatisch folgende Aktionen aus:

  • MPD down: Automatischer Restart (max. 3x pro Zyklus)
  • Disk Space kritisch: Alert
  • Systemressourcen kritisch: Alert
  • Netzwerk-Probleme: Alert