Skip to content

Commit 87ea68c

Browse files
committed
☠️ Battened the hatches: healthchecks aboard, Makefile sails with any docker-compose
1 parent 6ac0495 commit 87ea68c

File tree

4 files changed

+120
-30
lines changed

4 files changed

+120
-30
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"gitleaks",
3434
"Gluetun",
3535
"goin",
36+
"gsub",
3637
"guidin",
3738
"handlin",
3839
"healthcheck",

Makefile

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,19 @@ DOCKER_VPN_TEST_CMD ?= sh scripts/test_vpn.sh
5353
#
5454
# Build dependencies
5555
#
56-
DEPENDENCIES=docker docker-compose
56+
DEPENDENCIES=docker
57+
58+
#
59+
# Determine which Docker Compose command is available
60+
#
61+
ifeq (, $(shell which docker-compose 2> /dev/null))
62+
ifeq (, $(shell docker compose version 2> /dev/null))
63+
$(error "Neither 'docker-compose' nor 'docker compose' is available in PATH.")
64+
endif
65+
COMPOSE=docker compose
66+
else
67+
COMPOSE=docker-compose
68+
endif
5769

5870
#
5971
# Targets that are not files (i.e. never up-to-date); these will run every
@@ -79,21 +91,21 @@ $(BUILD_DEPENDS):
7991
#
8092
$(STOP): $(BUILD_DEPENDS)
8193
@echo "\nStopping compose service containers"
82-
docker-compose stop $(COMPOSE_STOP_OPTIONS)
94+
$(COMPOSE) stop $(COMPOSE_STOP_OPTIONS)
8395

8496
#
8597
# $(DOWN): Stops and removes containers.
8698
#
8799
$(DOWN): $(BUILD_DEPENDS)
88100
@echo "\nStopping compose services and removing containers"
89-
docker-compose down $(COMPOSE_DOWN_OPTIONS)
101+
$(COMPOSE) down $(COMPOSE_DOWN_OPTIONS)
90102

91103
#
92104
# $(CLEAN): Stops containers and removes containers, networks, volumes, and images created by up.
93105
#
94106
$(CLEAN): $(BUILD_DEPENDS)
95107
@echo "\nStopping compose services and removing containers, networks, volumes, and images"
96-
docker-compose down $(COMPOSE_CLEAN_OPTIONS)
108+
$(COMPOSE) down $(COMPOSE_CLEAN_OPTIONS)
97109

98110
@echo "\nRemoving images based on test image $(DOCKER_VPN_TEST_IMAGE)"
99111
docker images -q "$(DOCKER_VPN_TEST_IMAGE)" | xargs -r docker rmi -f || true
@@ -103,14 +115,14 @@ $(CLEAN): $(BUILD_DEPENDS)
103115
#
104116
$(BUILD): $(BUILD_DEPENDS)
105117
@echo "\nBuilding local image for compose service: $(COMPOSE_PRIVATEERR_SERVICE)"
106-
docker-compose -f $(COMPOSE_FILE) -f $(COMPOSE_BUILD_FILE) build $(COMPOSE_BUILD_OPTIONS) $(COMPOSE_PRIVATEERR_SERVICE)
118+
$(COMPOSE) -f $(COMPOSE_FILE) -f $(COMPOSE_BUILD_FILE) build $(COMPOSE_BUILD_OPTIONS) $(COMPOSE_PRIVATEERR_SERVICE)
107119

108120
#
109121
# $(UP): (Re)creates and starts containers for services.
110122
#
111123
$(UP): $(BUILD_DEPENDS)
112124
@echo "\nStarting compose services"
113-
docker-compose -f $(COMPOSE_FILE) up $(COMPOSE_UP_OPTIONS)
125+
$(COMPOSE) -f $(COMPOSE_FILE) up $(COMPOSE_UP_OPTIONS)
114126

115127
#
116128
# $(BUILD_UP): Alias for build, up.
@@ -122,7 +134,7 @@ $(BUILD_UP): $(BUILD)
122134
# $(START): Starts existing containers for a service.
123135
#
124136
$(START): $(BUILD_DEPENDS)
125-
docker-compose start
137+
$(COMPOSE) start
126138

127139
#
128140
# $(TEST_VPN): Obtains the VPN IP address and ensure the connection is working.
@@ -135,7 +147,7 @@ $(TEST_VPN):
135147
# Resolves variables in the Compose file and expands short-notation into the canonical format.
136148
#
137149
$(CONFIG):
138-
docker-compose config
150+
$(COMPOSE) config
139151

140152
#
141153
# $(ENV): Prints the evaluated docker compose default env configuration.
@@ -180,22 +192,22 @@ $(PRINT_ENV):
180192
#
181193
$(LOGS):
182194
@echo "\nGetting logs for services"
183-
docker-compose logs $(COMPOSE_LOGS_OPTIONS)
195+
$(COMPOSE) logs $(COMPOSE_LOGS_OPTIONS)
184196

185197
#
186198
# $(OPEN): Opens the compose services in the default web browser.
187199
#
188200
$(OPEN):
189201
@echo "\nOpening compose services in default browser"
190-
open "http://localhost:`docker-compose port $(COMPOSE_GLUETUN_SERVICE) 8080 | cut -d: -f2`" \
191-
"http://localhost:`docker-compose port $(COMPOSE_GLUETUN_SERVICE) 9696 | cut -d: -f2`" \
192-
"http://localhost:`docker-compose port $(COMPOSE_GLUETUN_SERVICE) 7878 | cut -d: -f2`" \
193-
"http://localhost:`docker-compose port $(COMPOSE_GLUETUN_SERVICE) 8989 | cut -d: -f2`" \
194-
"http://localhost:`docker-compose port $(COMPOSE_GLUETUN_SERVICE) 6767 | cut -d: -f2`" \
195-
"http://localhost:`docker-compose port $(COMPOSE_GLUETUN_SERVICE) 8787 | cut -d: -f2`" \
196-
"http://localhost:`docker-compose port $(COMPOSE_DUPLICATI_SERVICE) 8200 | cut -d: -f2`" \
197-
"http://localhost:`docker-compose port $(COMPOSE_OVERSEERR_SERVICE) 5055 | cut -d: -f2`" \
198-
"http://localhost:`docker-compose port $(COMPOSE_HOMEPAGE_SERVICE) 3000 | cut -d: -f2`"
202+
open "http://localhost:`$(COMPOSE) port $(COMPOSE_GLUETUN_SERVICE) 8080 | cut -d: -f2`" \
203+
"http://localhost:`$(COMPOSE) port $(COMPOSE_GLUETUN_SERVICE) 9696 | cut -d: -f2`" \
204+
"http://localhost:`$(COMPOSE) port $(COMPOSE_GLUETUN_SERVICE) 7878 | cut -d: -f2`" \
205+
"http://localhost:`$(COMPOSE) port $(COMPOSE_GLUETUN_SERVICE) 8989 | cut -d: -f2`" \
206+
"http://localhost:`$(COMPOSE) port $(COMPOSE_GLUETUN_SERVICE) 6767 | cut -d: -f2`" \
207+
"http://localhost:`$(COMPOSE) port $(COMPOSE_GLUETUN_SERVICE) 8787 | cut -d: -f2`" \
208+
"http://localhost:`$(COMPOSE) port $(COMPOSE_DUPLICATI_SERVICE) 8200 | cut -d: -f2`" \
209+
"http://localhost:`$(COMPOSE) port $(COMPOSE_OVERSEERR_SERVICE) 5055 | cut -d: -f2`" \
210+
"http://localhost:`$(COMPOSE) port $(COMPOSE_HOMEPAGE_SERVICE) 3000 | cut -d: -f2`"
199211

200212
#
201213
# $(HELP): Print help information.

docker-compose.yml

Lines changed: 68 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ services:
186186
LOG_HTML: ${FLARESOLVERR_LOG_HTML} # Toggle HTML logging
187187
CAPTCHA_SOLVER: ${FLARESOLVERR_CAPTCHA_SOLVER} # Specify captcha solver
188188

189+
# Define container healthcheck to verify FlareSolverr connectivity
190+
healthcheck:
191+
test: ["CMD-SHELL", "wget -qO- http://localhost:8191 | grep -q 'FlareSolverr'"] # Check if FlareSolverr UI is reachable
192+
interval: ${FLARESOLVERR_HEALTHCHECK_INTERVAL} # Run the check at this interval
193+
timeout: ${FLARESOLVERR_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
194+
start_period: ${FLARESOLVERR_HEALTHCHECK_START_PERIOD} # Grace period before checks start
195+
retries: 5 # Mark as unhealthy after 5 failures
196+
189197
#
190198
# Define the 'prowlarr' service for managing indexers
191199
#
@@ -200,12 +208,20 @@ services:
200208
volumes:
201209
- ${PROWLARR_CONFIG_PATH}:/config:rw # Database and Prowlarr configs
202210

211+
# Define container healthcheck to verify Prowlarr connectivity
212+
healthcheck:
213+
test: ["CMD-SHELL", "wget -qO- http://localhost:9696 | grep -q '<title>Prowlarr</title>'"] # Check if Prowlarr web UI is up
214+
interval: ${PROWLARR_HEALTHCHECK_INTERVAL} # Run the check at this interval
215+
timeout: ${PROWLARR_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
216+
start_period: ${PROWLARR_HEALTHCHECK_START_PERIOD} # Grace period before checks start
217+
retries: 5 # Mark as unhealthy after 5 failures
218+
203219
# Specify container service dependencies
204220
depends_on:
205221
gluetun:
206222
condition: service_healthy # Wait until Gluetun reports healthy VPN connection
207223
flaresolverr:
208-
condition: service_started # Ensure FlareSolverr is started
224+
condition: service_healthy # Wait until FlareSolverr is healthy
209225

210226
#
211227
# Define the 'qbittorrent' service for managing torrents
@@ -222,6 +238,14 @@ services:
222238
- ${QBITTORRENT_CONFIG_PATH}:/config:rw # Configuration files
223239
- ${HOST_DOWNLOADS_PATH}:/downloads:rw # Location of download managers output directory
224240

241+
# Define container healthcheck to verify qBittorrent connectivity
242+
healthcheck:
243+
test: ["CMD-SHELL", "wget -qO- http://localhost:8080 | grep -q '<title>qBittorrent</title>'"] # Check if qBittorrent web UI is reachable
244+
interval: ${QBITTORRENT_HEALTHCHECK_INTERVAL} # Run the check at this interval
245+
timeout: ${QBITTORRENT_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
246+
start_period: ${QBITTORRENT_HEALTHCHECK_START_PERIOD} # Grace period before checks start
247+
retries: 5 # Mark as unhealthy after 5 failures
248+
225249
# Specify container service dependencies
226250
depends_on:
227251
gluetun:
@@ -243,14 +267,22 @@ services:
243267
- ${HOST_DOWNLOADS_PATH}:/downloads:rw # Location of download managers output directory
244268
- ${HOST_MOVIES_PATH}:/movies:rw # Location of movie library on disk
245269

270+
# Define container healthcheck to verify Radarr connectivity
271+
healthcheck:
272+
test: ["CMD-SHELL", "wget -qO- http://localhost:7878 | grep -q '<title>Radarr</title>'"] # Check if Radarr web UI is reachable
273+
interval: ${RADARR_HEALTHCHECK_INTERVAL} # Run the check at this interval
274+
timeout: ${RADARR_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
275+
start_period: ${RADARR_HEALTHCHECK_START_PERIOD} # Grace period before checks start
276+
retries: 5 # Mark as unhealthy after 5 failures
277+
246278
# Specify container service dependencies
247279
depends_on:
248280
gluetun:
249281
condition: service_healthy # Wait until Gluetun reports healthy VPN connection
250282
prowlarr:
251-
condition: service_started # Ensure Prowlarr is started
283+
condition: service_healthy # Wait until Prowlarr is healthy
252284
qbittorrent:
253-
condition: service_started # Ensure qBittorrent is started
285+
condition: service_healthy # Wait until qBittorrent is healthy
254286

255287
#
256288
# Define the 'sonarr' service for managing tv shows
@@ -268,14 +300,22 @@ services:
268300
- ${HOST_DOWNLOADS_PATH}:/downloads:rw # Location of download managers output directory
269301
- ${HOST_TV_PATH}:/tv:rw # Location of TV library on disk
270302

303+
# Define container healthcheck to verify Sonarr connectivity
304+
healthcheck:
305+
test: ["CMD-SHELL", "wget -qO- http://localhost:8989 | grep -q '<title>Sonarr</title>'"] # Check if Sonarr web UI is reachable
306+
interval: ${SONARR_HEALTHCHECK_INTERVAL} # Run the check at this interval
307+
timeout: ${SONARR_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
308+
start_period: ${SONARR_HEALTHCHECK_START_PERIOD} # Grace period before checks start
309+
retries: 5 # Mark as unhealthy after 5 failures
310+
271311
# Specify container service dependencies
272312
depends_on:
273313
gluetun:
274314
condition: service_healthy # Wait until Gluetun reports healthy VPN connection
275315
prowlarr:
276-
condition: service_started # Ensure Prowlarr is started
316+
condition: service_healthy # Wait until Prowlarr is healthy
277317
qbittorrent:
278-
condition: service_started # Ensure qBittorrent is started
318+
condition: service_healthy # Wait until qBittorrent is healthy
279319

280320
#
281321
# Define the 'bazarr' service for managing subtitles
@@ -293,14 +333,22 @@ services:
293333
- ${HOST_MOVIES_PATH}:/movies:rw # Location of movies library on disk
294334
- ${HOST_TV_PATH}:/tv:rw # Location of TV library on disk
295335

336+
# Define container healthcheck to verify Bazarr connectivity
337+
healthcheck:
338+
test: ["CMD-SHELL", "wget -qO- http://localhost:6767 | grep -q '<title>Bazarr</title>'"] # Check if Bazarr web UI is reachable
339+
interval: ${BAZARR_HEALTHCHECK_INTERVAL} # Run the check at this interval
340+
timeout: ${BAZARR_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
341+
start_period: ${BAZARR_HEALTHCHECK_START_PERIOD} # Grace period before checks start
342+
retries: 5 # Mark as unhealthy after 5 failures
343+
296344
# Specify container service dependencies
297345
depends_on:
298346
gluetun:
299347
condition: service_healthy # Wait until Gluetun reports healthy VPN connection
300348
sonarr:
301-
condition: service_started # Ensure Sonarr is started
349+
condition: service_healthy # Wait until Sonarr is healthy
302350
radarr:
303-
condition: service_started # Ensure Radarr is started
351+
condition: service_healthy # Wait until Radarr is healthy
304352

305353
#
306354
# Define the 'readarr' service for managing ebooks
@@ -318,14 +366,22 @@ services:
318366
- ${HOST_DOWNLOADS_PATH}:/downloads:rw # Location of download managers output directory
319367
- ${HOST_BOOKS_PATH}:/books:rw # Location of book library on disk
320368

369+
# Define container healthcheck to verify Readarr connectivity
370+
healthcheck:
371+
test: ["CMD-SHELL", "wget -qO- http://localhost:8787 | grep -q '<title>Readarr</title>'"] # Check if Readarr web UI is reachable
372+
interval: ${READARR_HEALTHCHECK_INTERVAL} # Run the check at this interval
373+
timeout: ${READARR_HEALTHCHECK_TIMEOUT} # Fail if it exceeds this duration
374+
start_period: ${READARR_HEALTHCHECK_START_PERIOD} # Grace period before checks start
375+
retries: 5 # Mark as unhealthy after 5 failures
376+
321377
# Specify container service dependencies
322378
depends_on:
323379
gluetun:
324380
condition: service_healthy # Wait until Gluetun reports healthy VPN connection
325381
prowlarr:
326-
condition: service_started # Ensure Prowlarr is started
382+
condition: service_healthy # Wait until Prowlarr is healthy
327383
qbittorrent:
328-
condition: service_started # Ensure qBittorrent is started
384+
condition: service_healthy # Wait until qBittorrent is healthy
329385

330386
#
331387
# Define the 'overseerr' service for managing media library requests
@@ -453,11 +509,11 @@ services:
453509
gluetun:
454510
condition: service_healthy # Wait until Gluetun reports healthy VPN connection
455511
sonarr:
456-
condition: service_started # Ensure Sonarr is started
512+
condition: service_healthy # Wait until Sonarr is healthy
457513
radarr:
458-
condition: service_started # Ensure Radarr is started
514+
condition: service_healthy # Wait until Radarr is healthy
459515
qbittorrent:
460-
condition: service_started # Ensure qBittorrent is started
516+
condition: service_healthy # Wait until qBittorrent is healthy
461517

462518
#
463519
# Define the 'speedtest-tracker' service for tracking internet speeds

example.env

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,19 @@ FLARESOLVERR_LOG_LEVEL="${FLARESOLVERR_LOG_LEVEL:-info}"
8383
FLARESOLVERR_LOG_HTML="${FLARESOLVERR_LOG_HTML:-false}"
8484
FLARESOLVERR_CAPTCHA_SOLVER="${FLARESOLVERR_CAPTCHA_SOLVER:-none}"
8585
FLARESOLVERR_PORT="${FLARESOLVERR_PORT:-8191}"
86+
FLARESOLVERR_HEALTHCHECK_INTERVAL="${FLARESOLVERR_HEALTHCHECK_INTERVAL:-10s}"
87+
FLARESOLVERR_HEALTHCHECK_TIMEOUT="${FLARESOLVERR_HEALTHCHECK_TIMEOUT:-10s}"
88+
FLARESOLVERR_HEALTHCHECK_START_PERIOD="${FLARESOLVERR_HEALTHCHECK_START_PERIOD:-10s}"
8689

8790
#
8891
# Prowlarr environment variables
8992
#
9093
PROWLARR_TAG="${PROWLARR_TAG:-latest}"
9194
PROWLARR_WEBUI_PORT="${PROWLARR_WEBUI_PORT:-9696}"
9295
PROWLARR_CONFIG_PATH="${PROWLARR_CONFIG_PATH:-./config/prowlarr}"
96+
PROWLARR_HEALTHCHECK_INTERVAL="${PROWLARR_HEALTHCHECK_INTERVAL:-10s}"
97+
PROWLARR_HEALTHCHECK_TIMEOUT="${PROWLARR_HEALTHCHECK_TIMEOUT:-10s}"
98+
PROWLARR_HEALTHCHECK_START_PERIOD="${PROWLARR_HEALTHCHECK_START_PERIOD:-10s}"
9399

94100
#
95101
# qBittorrent environment variables
@@ -99,34 +105,49 @@ QBITTORRENT_TCP_PORT="${QBITTORRENT_TCP_PORT:-6881}"
99105
QBITTORRENT_UDP_PORT="${QBITTORRENT_UDP_PORT:-6881}"
100106
QBITTORRENT_WEBUI_PORT="${QBITTORRENT_WEBUI_PORT:-8080}"
101107
QBITTORRENT_CONFIG_PATH="${QBITTORRENT_CONFIG_PATH:-./config/qbittorrent}"
108+
QBITTORRENT_HEALTHCHECK_INTERVAL="${QBITTORRENT_HEALTHCHECK_INTERVAL:-10s}"
109+
QBITTORRENT_HEALTHCHECK_TIMEOUT="${QBITTORRENT_HEALTHCHECK_TIMEOUT:-10s}"
110+
QBITTORRENT_HEALTHCHECK_START_PERIOD="${QBITTORRENT_HEALTHCHECK_START_PERIOD:-10s}"
102111

103112
#
104113
# Radarr environment variables
105114
#
106115
RADARR_TAG="${RADARR_TAG:-latest}"
107116
RADARR_WEBUI_PORT="${RADARR_WEBUI_PORT:-7878}"
108117
RADARR_CONFIG_PATH="${RADARR_CONFIG_PATH:-./config/radarr}"
118+
RADARR_HEALTHCHECK_INTERVAL="${RADARR_HEALTHCHECK_INTERVAL:-10s}"
119+
RADARR_HEALTHCHECK_TIMEOUT="${RADARR_HEALTHCHECK_TIMEOUT:-10s}"
120+
RADARR_HEALTHCHECK_START_PERIOD="${RADARR_HEALTHCHECK_START_PERIOD:-10s}"
109121

110122
#
111123
# Sonarr environment variables
112124
#
113125
SONARR_TAG="${SONARR_TAG:-latest}"
114126
SONARR_WEBUI_PORT="${SONARR_WEBUI_PORT:-8989}"
115127
SONARR_CONFIG_PATH="${SONARR_CONFIG_PATH:-./config/sonarr}"
128+
SONARR_HEALTHCHECK_INTERVAL="${SONARR_HEALTHCHECK_INTERVAL:-10s}"
129+
SONARR_HEALTHCHECK_TIMEOUT="${SONARR_HEALTHCHECK_TIMEOUT:-10s}"
130+
SONARR_HEALTHCHECK_START_PERIOD="${SONARR_HEALTHCHECK_START_PERIOD:-10s}"
116131

117132
#
118133
# Bazarr environment variables
119134
#
120135
BAZARR_TAG="${BAZARR_TAG:-latest}"
121136
BAZARR_WEBUI_PORT="${BAZARR_WEBUI_PORT:-6767}"
122137
BAZARR_CONFIG_PATH="${BAZARR_CONFIG_PATH:-./config/bazarr}"
138+
BAZARR_HEALTHCHECK_INTERVAL="${BAZARR_HEALTHCHECK_INTERVAL:-10s}"
139+
BAZARR_HEALTHCHECK_TIMEOUT="${BAZARR_HEALTHCHECK_TIMEOUT:-10s}"
140+
BAZARR_HEALTHCHECK_START_PERIOD="${BAZARR_HEALTHCHECK_START_PERIOD:-10s}"
123141

124142
#
125143
# Readarr environment variables
126144
#
127145
READARR_TAG="${READARR_TAG:-develop}"
128146
READARR_WEBUI_PORT="${READARR_WEBUI_PORT:-8787}"
129147
READARR_CONFIG_PATH="${READARR_CONFIG_PATH:-./config/readarr}"
148+
READARR_HEALTHCHECK_INTERVAL="${READARR_HEALTHCHECK_INTERVAL:-10s}"
149+
READARR_HEALTHCHECK_TIMEOUT="${READARR_HEALTHCHECK_TIMEOUT:-10s}"
150+
READARR_HEALTHCHECK_START_PERIOD="${READARR_HEALTHCHECK_START_PERIOD:-10s}"
130151

131152
#
132153
# Overseerr environment variables

0 commit comments

Comments
 (0)