-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
143 lines (138 loc) · 4.39 KB
/
Copy pathdocker-compose.yml
File metadata and controls
143 lines (138 loc) · 4.39 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
# Bound container log size on SD cards: the `local` driver compresses rotated
# files and writes fewer bytes than json-file. App INFO logs live in
# ./data/logs/ (RotatingFileHandler); container logs only carry warnings/errors.
x-logging: &default-logging
driver: local
options:
max-size: 5m
max-file: "2"
services:
model-server:
image: ghcr.io/suncuss/birdnet-pipy-backend:${BIRDNET_CHANNEL:-main}
build:
context: ./backend
dockerfile: Dockerfile
args:
UID: ${UID:-1000}
GID: ${GID:-1000}
command: python -m model_service.inference_server
restart: unless-stopped
logging: *default-logging
volumes:
- ./backend:/app
- ./data:/app/data
- ./data/flags:/app/data/flags
environment:
- PYTHONPATH=/app
- BIRDNET_SERVICE_PORT=5001
- LOG_FORMAT=human
- LOG_LEVEL=INFO
- CONSOLE_LOG_LEVEL=${CONSOLE_LOG_LEVEL:-WARNING}
ports:
- "127.0.0.1:5001:5001"
api:
image: ghcr.io/suncuss/birdnet-pipy-backend:${BIRDNET_CHANNEL:-main}
# No build: — shares image built by model-server service
# Single gevent worker is mandatory: detections fan out via an in-process
# socketio.emit (no Redis message_queue), so multiple workers would
# silently drop broadcasts to clients on other workers.
command: >
gunicorn wsgi:application
--worker-class geventwebsocket.gunicorn.workers.GeventWebSocketWorker
--workers 1
--bind 0.0.0.0:5002
--timeout 120
--graceful-timeout 30
--keep-alive 65
--error-logfile -
restart: unless-stopped
logging: *default-logging
healthcheck:
test: ["CMD", "curl", "-fsS", "http://127.0.0.1:5002/api/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
volumes:
- ./backend:/app
- ./data:/app/data
- ./data/flags:/app/data/flags
environment:
- PYTHONPATH=/app
- API_PORT=5002
- LOG_FORMAT=human
- LOG_LEVEL=INFO
- CONSOLE_LOG_LEVEL=${CONSOLE_LOG_LEVEL:-WARNING}
ports:
# Bind to localhost only - nginx proxies external requests via docker network
# This prevents direct access to internal endpoints like /api/broadcast/detection
- "127.0.0.1:5002:5002"
main:
image: ghcr.io/suncuss/birdnet-pipy-backend:${BIRDNET_CHANNEL:-main}
# No build: — shares image built by model-server service
command: python -m core.main
restart: unless-stopped
logging: *default-logging
ulimits:
nofile:
soft: 8192
hard: 16384
volumes:
- ./backend:/app
- ./data:/app/data
- ./data/flags:/app/data/flags
# PulseAudio socket for audio access
# birdnet-service.sh ensures /run/pulse/native exists (system-wide or symlink to user socket)
- /run/pulse:/run/pulse:ro
environment:
- PYTHONPATH=/app
- PULSE_SERVER=unix:/run/pulse/native
- LOG_FORMAT=human
- LOG_LEVEL=INFO
- CONSOLE_LOG_LEVEL=${CONSOLE_LOG_LEVEL:-WARNING}
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
model-server:
condition: service_started
api:
condition: service_healthy
icecast:
image: ghcr.io/suncuss/birdnet-pipy-icecast:${BIRDNET_CHANNEL:-main}
build:
context: ./deployment/audio
dockerfile: Dockerfile
args:
UID: ${UID:-1000}
GID: ${GID:-1000}
restart: unless-stopped
logging: *default-logging
volumes:
# PulseAudio socket for audio access
# birdnet-service.sh ensures /run/pulse/native exists (system-wide or symlink to user socket)
- /run/pulse:/run/pulse:ro
# User settings for RTSP URL configuration; needs write for data/logs/
- ./data:/app/data
environment:
- PULSE_SERVER=unix:/run/pulse/native
- ICECAST_PASSWORD=${ICECAST_PASSWORD:-}
- STREAM_BITRATE=${STREAM_BITRATE:-320k}
- TZ=UTC
ports:
# Bind to localhost only - nginx proxies /stream/ requests via docker network
# This enforces authentication via nginx auth_request
- "127.0.0.1:8888:8888"
frontend:
image: ghcr.io/suncuss/birdnet-pipy-frontend:${BIRDNET_CHANNEL:-main}
build:
context: ./frontend
dockerfile: Dockerfile
restart: unless-stopped
logging: *default-logging
ports:
- "80:80"
environment:
- TZ=UTC
depends_on:
api:
condition: service_healthy