-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompose.yml
More file actions
137 lines (132 loc) · 4.65 KB
/
compose.yml
File metadata and controls
137 lines (132 loc) · 4.65 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
# Docker Compose stack for the RPi camera plugin.
#
# Paired mode (default — captures push to the RElab backend):
# docker compose up -d
#
# Standalone mode (no RElab backend — captures land in a local RustFS bucket):
# Set APP_BUILD_TARGET=runtime-standalone and COMPOSE_PROFILES=standalone in
# .env, then ``docker compose up -d``. The standalone build target adds
# aioboto3; configure IMAGE_SINK=s3 and S3_* vars alongside it.
#
# With remote observability (Loki logs + optional Prometheus metrics):
# Add ``observability-ship`` to COMPOSE_PROFILES, e.g.
# ``COMPOSE_PROFILES=standalone,observability-ship``.
services:
app:
image: relab-rpi-cam-plugin
build:
context: .
# Override to ``runtime-standalone`` in .env for standalone mode.
target: ${APP_BUILD_TARGET:-runtime}
restart: unless-stopped
depends_on:
mediamtx:
condition: service_healthy
volumes:
- /run/udev:/run/udev:ro
- app_logs:/app/logs
- relay_credentials:/home/rpicam/.config/relab
env_file:
- .env
group_add:
- video
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
# Host networking lets the app reach MediaMTX (RTSP :8554, HLS :8888,
# control API :9997) over loopback, keeping those listeners localhost-only
# without any ``host.docker.internal`` bridge gymnastics. Port 8018 is bound
# directly on the host — equivalent to the previous ports mapping.
network_mode: host
mediamtx:
# MediaMTX sidecar: the single media seam for the plugin.
#
# - Ingest: RTSP on :8554 (lores cam-preview always, main cam-hires while
# a YouTube stream is active).
# - Browser/native preview: LL-HLS on :8888.
# - Runtime control: HTTP API on localhost:9997. The plugin's
# ``mediamtx_client`` patches the ``cam-hires`` path at runtime with a
# ``runOnReady`` command that forks ffmpeg inside this container to
# re-publish the stream to YouTube RTMPS.
#
# ``-ffmpeg`` variant is required because ``runOnReady`` shells out to
# ffmpeg and the default image doesn't ship it. Runs on the host network so
# all three listeners (8554/8888/9997) are reachable from the app container.
image: relab-rpi-cam-plugin-mediamtx
build:
context: .
dockerfile: docker/mediamtx.Dockerfile
restart: unless-stopped
volumes:
- ./mediamtx.yml:/mediamtx.yml:ro
# Hit the control API on localhost:9997. Our wrapper image adds wget since
# the upstream image intentionally stays minimal.
healthcheck:
test: [ "CMD-SHELL", "wget -q -O /dev/null http://localhost:9997/v3/config/global/get || exit 1" ]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
network_mode: host
alloy:
image: grafana/alloy:v1.12.0
restart: unless-stopped
volumes:
- ./config.alloy:/etc/alloy/config.alloy:ro
- alloy_data:/var/lib/alloy/data
- app_logs:/var/log/app:ro
environment:
LOKI_PUSH_URL: ${LOKI_PUSH_URL:-}
PROMETHEUS_REMOTE_WRITE_URL: ${PROMETHEUS_REMOTE_WRITE_URL:-}
OBSERVABILITY_INSTANCE: ${OBSERVABILITY_INSTANCE:-rpi-cam-plugin}
command:
- run
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
profiles:
- observability-ship
rustfs:
# S3-compatible object storage for standalone mode. When this sidecar is
# running the plugin's S3CompatibleSink writes captures directly into the
# bucket over the docker host network — no Relab backend needed.
# See the ``standalone`` section of ``.env.example`` for the required vars.
image: rustfs/rustfs:latest
restart: unless-stopped
ports:
- "9000:9000" # S3 API
- "9001:9001" # Web console
volumes:
- rustfs_data:/data
environment:
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY:-rustfsadmin}
# RustFS refuses to start with an unset / short secret key, so the
# empty default here fails loudly only when the standalone profile is
# actually activated — paired-mode users don't need to set it.
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY:-}
RUSTFS_ADDRESS: 0.0.0.0:9000
RUSTFS_CONSOLE_ADDRESS: 0.0.0.0:9001
healthcheck:
test: [ "CMD-SHELL", "curl -sf http://localhost:9000/health || exit 1" ]
interval: 5s
timeout: 3s
retries: 5
start_period: 10s
logging:
driver: local
options:
max-size: "10m"
max-file: "3"
profiles:
- standalone
volumes:
app_logs:
relay_credentials:
alloy_data:
rustfs_data: