Skip to content

Commit a8c567d

Browse files
felipecrsNickM-27
andauthored
Add healthcheck for go2rtc service (blakeblackshear#5545)
* Upgrade s6-overlay from 3.1.3.0 to 3.1.4.0 * Add go2rtc healthcheck service Also don't make go2rtc exits cause the container to fail. * Reword healthcheck message Co-authored-by: Nicolas Mowen <[email protected]> * Add timeout to go2rtc healthcheck * Update healthcheck message Co-authored-by: Nicolas Mowen <[email protected]> * Give additional time for go2rtc start/restart * Fix typo * Avoid creating go2rtc config multiple times * Fix healthcheck not starting * Fix sleep * Fix more hidden logs * Decrease time window and use curl's timeout flag --------- Co-authored-by: Nicolas Mowen <[email protected]>
1 parent 8013534 commit a8c567d

File tree

17 files changed

+82
-59
lines changed

17 files changed

+82
-59
lines changed

Dockerfile

+4
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ FROM deps AS devcontainer
207207
# But start a fake service for simulating the logs
208208
COPY docker/fake_frigate_run /etc/s6-overlay/s6-rc.d/frigate/run
209209

210+
# Create symbolic link to the frigate source code, as go2rtc's create_config.sh uses it
211+
RUN mkdir -p /opt/frigate \
212+
&& ln -svf /workspace/frigate/frigate /opt/frigate/frigate
213+
210214
# Install Node 16
211215
RUN apt-get update \
212216
&& apt-get install wget -y \

docker/install_s6_overlay.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
set -euxo pipefail
44

5-
s6_version="3.1.3.0"
5+
s6_version="3.1.4.0"
66

77
if [[ "${TARGETARCH}" == "amd64" ]]; then
88
s6_arch="x86_64"

docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/finish

+5-7
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,25 @@
44

55
set -o errexit -o nounset -o pipefail
66

7+
# Logs should be sent to stdout so that s6 can collect them
8+
79
declare exit_code_container
810
exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode)
911
readonly exit_code_container
1012
readonly exit_code_service="${1}"
1113
readonly exit_code_signal="${2}"
1214
readonly service="Frigate"
1315

14-
echo "Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})" >&2
16+
echo "[INFO] Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})"
1517

1618
if [[ "${exit_code_service}" -eq 256 ]]; then
1719
if [[ "${exit_code_container}" -eq 0 ]]; then
18-
echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode
20+
echo $((128 + exit_code_signal)) >/run/s6-linux-init-container-results/exitcode
1921
fi
2022
elif [[ "${exit_code_service}" -ne 0 ]]; then
2123
if [[ "${exit_code_container}" -eq 0 ]]; then
22-
echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode
24+
echo "${exit_code_service}" >/run/s6-linux-init-container-results/exitcode
2325
fi
24-
else
25-
# Exit code 0 is expected when Frigate is restarted by the user. In this case,
26-
# we create a signal for the go2rtc finish script to tolerate the restart.
27-
touch /dev/shm/restarting-frigate
2826
fi
2927

3028
exec /run/s6/basedir/bin/halt

docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
set -o errexit -o nounset -o pipefail
66

7+
# Logs should be sent to stdout so that s6 can collect them
8+
79
# Tell S6-Overlay not to restart this service
810
s6-svc -O .
911

10-
echo "[INFO] Starting Frigate..." >&2
12+
echo "[INFO] Starting Frigate..."
1113

12-
cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate" >&2
14+
cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate"
1315

1416
# Replace the bash process with the Frigate process, redirecting stderr to stdout
1517
exec 2>&1

docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-healthcheck/dependencies.d/go2rtc

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/command/with-contenv bash
2+
# shellcheck shell=bash
3+
4+
set -o errexit -o nounset -o pipefail
5+
6+
# Logs should be sent to stdout so that s6 can collect them
7+
8+
readonly exit_code_service="${1}"
9+
readonly exit_code_signal="${2}"
10+
readonly service="go2rtc-healthcheck"
11+
12+
echo "[INFO] The ${service} service exited with code ${exit_code_service} (by signal ${exit_code_signal})"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
go2rtc-log
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/command/with-contenv bash
2+
# shellcheck shell=bash
3+
# Start the go2rtc-healthcheck service
4+
5+
set -o errexit -o nounset -o pipefail
6+
7+
# Logs should be sent to stdout so that s6 can collect them
8+
9+
# Give some additional time for go2rtc to start before start pinging
10+
sleep 10s
11+
echo "[INFO] Starting go2rtc healthcheck service..."
12+
13+
while sleep 30s; do
14+
# Check if the service is running
15+
if ! curl --connect-timeout 10 --fail --silent --show-error --output /dev/null http://127.0.0.1:1984/api/streams 2>&1; then
16+
echo "[ERROR] The go2rtc service is not responding to ping, restarting..."
17+
# We can also use -r instead of -t to send kill signal rather than term
18+
s6-svc -t /var/run/service/go2rtc 2>&1
19+
# Give some additional time to go2rtc to restart before start pinging again
20+
sleep 10s
21+
fi
22+
done
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
5000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
longrun
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
go2rtc
2+
go2rtc-healthcheck
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
11
#!/command/with-contenv bash
22
# shellcheck shell=bash
3-
# Take down the S6 supervision tree when the service exits
43

54
set -o errexit -o nounset -o pipefail
65

7-
declare exit_code_container
8-
exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode)
9-
readonly exit_code_container
6+
# Logs should be sent to stdout so that s6 can collect them
7+
108
readonly exit_code_service="${1}"
119
readonly exit_code_signal="${2}"
1210
readonly service="go2rtc"
1311

14-
echo "Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})" >&2
15-
16-
if [[ "${exit_code_service}" -eq 256 ]]; then
17-
if [[ "${exit_code_container}" -eq 0 ]]; then
18-
echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode
19-
fi
20-
elif [[ "${exit_code_service}" -ne 0 ]]; then
21-
if [[ "${exit_code_container}" -eq 0 ]]; then
22-
echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode
23-
fi
24-
else
25-
# go2rtc is not supposed to exit, so even when it exits with 0 we make the
26-
# container with 1. We only tolerate it when Frigate is restarting.
27-
if [[ "${exit_code_container}" -eq 0 && ! -f /dev/shm/restarting-frigate ]]; then
28-
echo "1" > /run/s6-linux-init-container-results/exitcode
29-
fi
30-
fi
31-
32-
exec /run/s6/basedir/bin/halt
12+
echo "[INFO] The ${service} service exited with code ${exit_code_service} (by signal ${exit_code_signal})"

docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run

+15-14
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44

55
set -o errexit -o nounset -o pipefail
66

7-
# Tell S6-Overlay not to restart this service
8-
s6-svc -O .
7+
# Logs should be sent to stdout so that s6 can collect them
98

109
function get_ip_and_port_from_supervisor() {
1110
local ip_address
@@ -19,9 +18,9 @@ function get_ip_and_port_from_supervisor() {
1918
jq --exit-status --raw-output '.data.ipv4.address[0]'
2019
) && [[ "${ip_address}" =~ ${ip_regex} ]]; then
2120
ip_address="${BASH_REMATCH[1]}"
22-
echo "[INFO] Got IP address from supervisor: ${ip_address}" >&2
21+
echo "[INFO] Got IP address from supervisor: ${ip_address}"
2322
else
24-
echo "[WARN] Failed to get IP address from supervisor" >&2
23+
echo "[WARN] Failed to get IP address from supervisor"
2524
return 0
2625
fi
2726

@@ -35,26 +34,28 @@ function get_ip_and_port_from_supervisor() {
3534
jq --exit-status --raw-output '.data.network["8555/tcp"]'
3635
) && [[ "${webrtc_port}" =~ ${port_regex} ]]; then
3736
webrtc_port="${BASH_REMATCH[1]}"
38-
echo "[INFO] Got WebRTC port from supervisor: ${webrtc_port}" >&2
37+
echo "[INFO] Got WebRTC port from supervisor: ${webrtc_port}"
3938
else
40-
echo "[WARN] Failed to get WebRTC port from supervisor" >&2
39+
echo "[WARN] Failed to get WebRTC port from supervisor"
4140
return 0
4241
fi
4342

4443
export FRIGATE_GO2RTC_WEBRTC_CANDIDATE_INTERNAL="${ip_address}:${webrtc_port}"
4544
}
4645

47-
echo "[INFO] Preparing go2rtc config..." >&2
46+
if [[ ! -f "/dev/shm/go2rtc.yaml" ]]; then
47+
echo "[INFO] Preparing go2rtc config..."
4848

49-
if [[ -n "${SUPERVISOR_TOKEN:-}" ]]; then
50-
# Running as a Home Assistant add-on, infer the IP address and port
51-
get_ip_and_port_from_supervisor
52-
fi
49+
if [[ -n "${SUPERVISOR_TOKEN:-}" ]]; then
50+
# Running as a Home Assistant add-on, infer the IP address and port
51+
get_ip_and_port_from_supervisor
52+
fi
5353

54-
raw_config=$(python3 /usr/local/go2rtc/create_config.py)
54+
python3 /usr/local/go2rtc/create_config.py
55+
fi
5556

56-
echo "[INFO] Starting go2rtc..." >&2
57+
echo "[INFO] Starting go2rtc..."
5758

5859
# Replace the bash process with the go2rtc process, redirecting stderr to stdout
5960
exec 2>&1
60-
exec go2rtc -config="${raw_config}"
61+
exec go2rtc -config=/dev/shm/go2rtc.yaml

docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/finish

+5-3
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,27 @@
44

55
set -o errexit -o nounset -o pipefail
66

7+
# Logs should be sent to stdout so that s6 can collect them
8+
79
declare exit_code_container
810
exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode)
911
readonly exit_code_container
1012
readonly exit_code_service="${1}"
1113
readonly exit_code_signal="${2}"
1214
readonly service="NGINX"
1315

14-
echo "Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})" >&2
16+
echo "[INFO] Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})"
1517

1618
if [[ "${exit_code_service}" -eq 256 ]]; then
1719
if [[ "${exit_code_container}" -eq 0 ]]; then
18-
echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode
20+
echo $((128 + exit_code_signal)) >/run/s6-linux-init-container-results/exitcode
1921
fi
2022
if [[ "${exit_code_signal}" -eq 15 ]]; then
2123
exec /run/s6/basedir/bin/halt
2224
fi
2325
elif [[ "${exit_code_service}" -ne 0 ]]; then
2426
if [[ "${exit_code_container}" -eq 0 ]]; then
25-
echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode
27+
echo "${exit_code_service}" >/run/s6-linux-init-container-results/exitcode
2628
fi
2729
exec /run/s6/basedir/bin/halt
2830
fi

docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
set -o errexit -o nounset -o pipefail
66

7-
echo "[INFO] Starting NGINX..." >&2
7+
# Logs should be sent to stdout so that s6 can collect them
8+
9+
echo "[INFO] Starting NGINX..."
810

911
# Replace the bash process with the NGINX process, redirecting stderr to stdout
1012
exec 2>&1

docker/rootfs/usr/local/bin/frigate

-5
This file was deleted.

docker/rootfs/usr/local/go2rtc/create_config.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
sys.path.insert(0, "/opt/frigate")
99
from frigate.const import BIRDSEYE_PIPE, BTBN_PATH
1010
from frigate.ffmpeg_presets import parse_preset_hardware_acceleration_encode
11+
1112
sys.path.remove("/opt/frigate")
1213

1314

@@ -50,7 +51,6 @@
5051
else:
5152
print(
5253
"[INFO] Not injecting WebRTC candidates into go2rtc config as it has been set manually",
53-
file=sys.stderr,
5454
)
5555

5656
# sets default RTSP response to be equivalent to ?video=h264,h265&audio=aac
@@ -95,5 +95,6 @@
9595
else:
9696
go2rtc_config["streams"] = {"birdseye": ffmpeg_cmd}
9797

98-
99-
print(json.dumps(go2rtc_config))
98+
# Write go2rtc_config to /dev/shm/go2rtc.yaml
99+
with open("/dev/shm/go2rtc.yaml", "w") as f:
100+
yaml.dump(go2rtc_config, f)

0 commit comments

Comments
 (0)