-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
216 lines (193 loc) · 9.17 KB
/
docker-compose.yml
File metadata and controls
216 lines (193 loc) · 9.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# Airglow - AirPlay ➜ LedFX Stack
#
# This stack provides AirPlay 2 audio streaming to LedFX for real-time LED visualization.
# Audio flows: AirPlay Device → Shairport-Sync → PulseAudio → LedFX → LED Devices
#
# Network Architecture:
# - airglow-web: Bridge networking (port 8080 exposed)
# - ledfx: Bridge networking (ports 8888, 5568, 6454, 21324, 4048, 8889, 4002, 4003 exposed)
# Note: Philips Hue uses outbound HTTP/HTTPS (80/443) - no ports exposed
# - shairport-sync: Macvlan networking (real IP 192.168.2.202 on physical network)
# Uses built-in Avahi daemon (included in mikebrady/shairport-sync image) for mDNS advertisement
# Also connected to bridge network to reach LedFX container
# Note: All services use bridge networking except shairport-sync, which uses macvlan to get
# a real IP on the physical network. This allows it to advertise correctly via its built-in Avahi.
# NQPTP and shairport-sync communicate via shared memory (/dev/shm) for AirPlay 2 timing
# synchronization (provided by shairport-sync's internal nqptp).
networks:
airglow-network:
driver: bridge
shairport-macvlan:
name: shairport-macvlan
driver: macvlan
driver_opts:
parent: ${NETWORK_INTERFACE:-eth0}
ipam:
config:
- subnet: ${NETWORK_SUBNET:-192.168.2.0/24}
gateway: ${NETWORK_GATEWAY:-192.168.2.1}
services:
ledfx:
# LedFX - Real-time LED visualization from audio input
# Web UI: http://localhost:8888
# NOTE: Using :latest tag for automatic updates. For production, pin to specific version:
# 1. Check available versions: https://github.com/LedFx/LedFx/releases
# 2. Update image tag: image: ghcr.io/ledfx/ledfx:2.1.2
# 3. Test thoroughly before deploying to production
image: ghcr.io/ledfx/ledfx:latest
container_name: ledfx
# Bridge networking - port mappings for web UI and LED protocols
networks:
- airglow-network
ports:
- "8888:8888" # Web UI and API (HTTP)
- "5568:5568/udp" # E1.31/sACN protocol (multicast)
- "6454:6454/udp" # ArtNet protocol (DMX over Ethernet)
- "21324:21324/udp" # WLED UDP protocol (unicast)
- "4048:4048/udp" # DDP protocol (unicast)
- "8889:8889/udp" # WLED device discovery (optional but recommended)
- "4002:4002/udp" # Govee device responses (receive port)
- "4003:4003/udp" # Govee device control (send commands to device)
# Note: Philips Hue uses outbound HTTP/HTTPS (ports 80/443) to Hue Bridge
# No ports need to be exposed - LEDFX makes outbound connections to the bridge
# Note: LIFX uses outbound UDP (port 56700) for device communication
# No ports need to be exposed - LEDFX sends commands and receives responses automatically
# Note: Nanoleaf uses outbound HTTP (port 16021) and UDP (port 60222/60221) for device communication
# No ports need to be exposed - LEDFX makes outbound connections to the device
# Note: OpenPixelControl uses outbound UDP (port 7890) for device communication
# No ports need to be exposed - LEDFX sends pixel data to OPC devices
# Note: OpenRGB uses outbound TCP (port 6742 default) to OpenRGB SDK server
# No ports need to be exposed - LEDFX connects to OpenRGB server on host/network
# Note: OSC (Open Sound Control) uses outbound UDP (port 9000 default, configurable)
# No ports need to be exposed - LEDFX sends OSC messages to OSC servers
# Note: Novation Launchpad uses USB MIDI (via rtmidi library)
# No network ports needed - requires USB device passthrough if used
# Note: RPi WS281X uses Raspberry Pi GPIO pins (local hardware interface)
# No network ports needed - requires GPIO access and /dev/mem if used in Docker
# Note: Twinkly Squares uses outbound HTTP/HTTPS and UDP (port 7777) for real-time frames
# No ports need to be exposed - LEDFX connects to Twinkly devices
# Note: Zengge/MagicHome/FluxLED uses outbound UDP (port 5577) for device control
# No ports need to be exposed - LEDFX sends commands to FluxLED devices
# Note: UDP Realtime Device uses configurable UDP ports (default 21324, same as WLED UDP)
# No additional ports needed - uses same ports as WLED UDP protocol
volumes:
# PulseAudio configuration and socket for inter-container audio
- ./pulse:/home/ledfx/.config/pulse
# Persistent LedFX configuration (devices, effects, presets)
# Using bind mount to avoid permission issues with named volumes
- ./ledfx-data:/home/ledfx/ledfx-config
environment:
# Enable real-time Python output (useful for debugging)
- PYTHONUNBUFFERED=1
# Restart policy: unless-stopped means containers will:
# - Auto-start on host boot
# - Restart on failure
# - NOT restart if manually stopped
restart: unless-stopped
# Health check to verify LedFX API is responding
# Note: LedFX container doesn't have curl or pgrep, so we use Python to check the port
healthcheck:
test: ["CMD", "python3", "-c", "import socket; s=socket.socket(); s.settimeout(2); s.connect(('127.0.0.1', 8888)); s.close()"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
shairport-sync:
# Shairport-Sync - AirPlay 2 receiver
# Receives AirPlay audio and outputs to PulseAudio
# Custom image includes jq for JSON parsing in hook scripts
# Uses macvlan networking to get real IP (192.168.2.202) on physical network
# This ensures it advertises the correct IP instead of bridge IP
build:
context: .
dockerfile: Dockerfile.shairport-sync
container_name: shairport-sync
# Macvlan networking - gives container real IP on physical network
# This allows shairport-sync to advertise the correct IP (192.168.2.202)
# and clients can connect directly without Docker port mapping
networks:
shairport-macvlan:
ipv4_address: ${SHAIRPORT_IP:-192.168.2.202}
# Also connect to bridge network to reach LedFX container
airglow-network:
aliases:
- shairport-sync
# No port mappings needed - macvlan gives direct network access
# Ports 7000 (RTSP), 5000 (RAOP), 319/320 (NQPTP) are directly accessible
environment:
# Connect to LedFX's PulseAudio server via shared Unix socket
- PULSE_SERVER=unix:/pulse/pulseaudio.socket
- PULSE_COOKIE=/pulse/cookie
# LedFX API connection - use container name for service discovery
- LEDFX_HOST=ledfx
- LEDFX_PORT=8888
# Optional log location for the session hook prototype
- LEDFX_HOOK_LOG=/var/log/shairport-sync/ledfx-session-hook.log
volumes:
# Shairport configuration (AirPlay device name, audio settings)
- ./configs/shairport-sync.conf:/etc/shairport-sync.conf:ro
# LedFX hook configuration (YAML format, created dynamically by web app, read by hook scripts)
- ./configs:/configs:ro
# PulseAudio socket for audio output to LedFX
- ./pulse:/pulse
# Session hook scripts triggered on AirPlay start/stop
- ./scripts:/scripts:ro
# Shared memory for shairport-sync's internal nqptp process
- /dev/shm:/dev/shm
# Ensure LedFX starts first and is healthy before starting shairport-sync
# This prevents connection failures during startup
depends_on:
ledfx:
condition: service_healthy
# Restart policy: unless-stopped means containers will:
# - Auto-start on host boot
# - Restart on failure
# - NOT restart if manually stopped
restart: unless-stopped
# Health check to verify shairport-sync is running
healthcheck:
test: ["CMD", "pgrep", "-f", "shairport-sync"]
interval: 30s
timeout: 10s
retries: 3
airglow-web:
# Airglow Status Dashboard - Web interface for status and configuration
# Web UI: http://localhost:8080
build:
context: .
dockerfile: Dockerfile.web
container_name: airglow-web
# Bridge networking - uses container name 'ledfx' for API access
networks:
- airglow-network
ports:
- "8080:80"
environment:
# LedFX API connection - use container name for service discovery
- LEDFX_HOST=ledfx
- LEDFX_PORT=8888
volumes:
# Configuration files (read-write for config page)
- ./configs:/configs:rw
# Diagnostic scripts (read-only)
- ./scripts:/scripts:ro
# Docker socket for container status checks
# SECURITY NOTE: Read-only access still exposes container information for reconnaissance.
# This is necessary for the web interface to display container status and restart containers.
# In production, consider using Docker API proxy or restricting access further.
- /var/run/docker.sock:/var/run/docker.sock:ro
# Ensure LedFX is available and healthy before starting web interface
depends_on:
ledfx:
condition: service_healthy
# Restart policy: unless-stopped means containers will:
# - Auto-start on host boot
# - Restart on failure
# - NOT restart if manually stopped
restart: unless-stopped
# Health check to verify web interface is responding
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/api/status"]
interval: 30s
timeout: 10s
retries: 3