-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathrun-seedbox.sh
executable file
·506 lines (434 loc) · 21.5 KB
/
run-seedbox.sh
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
#!/bin/bash
set -e
# Load common functions
source tools/tools.sh
# Check that required tools are installed
check_utilities
SKIP_PULL=0
DEBUG=0
for i in "$@"; do
case $i in
--no-pull)
SKIP_PULL=1
;;
--debug)
DEBUG=1
;;
*)
echo "[$0] ❌ ERROR: unknown parameter \"$i\""
exit 1
;;
esac
done
cleanup_on_exit() {
rm -f rules.props *-vpn.props *-envfile.props config.json
[[ -d env ]] && rm -f env/*.tmp
}
trap cleanup_on_exit EXIT
echo-debug() {
if [[ ${DEBUG} == "1" ]]; then echo "$@"; fi
}
###############################################################################################
####################################### Load variables ########################################
###############################################################################################
echo "[$0] ***** Checking environment variables and files... *****"
if [[ ! -f .env ]]; then
echo "[$0] ERROR. \".env\" file not found. Please copy \".env.sample\" and edit its values. Then, re-run this script."
exit 1
fi
if [[ ! -f .env.custom ]]; then
echo "[$0] ERROR. \".env.custom\" file not found. Please copy \".env.custom.sample\" and edit its values. Be aware that since v2.2 update, some variables from .env must be moved to .env.custom. When done, re-run this script."
exit 1
fi
if [[ ! -f docker-compose.yaml ]]; then
echo "[$0] ERROR. \"docker-compose.yaml\" file not found. Please copy \"docker-compose.sample.yaml\" and edit its values if you need customization. Then, re-run this script."
exit 1
fi
# Check if there are obsolete config still in .env but should be moved to .env.custom
if [[ $(grep "^MYSQL_.*" .env | wc -l) != 0 || $(grep "^WIREGUARD_.*" .env | wc -l) != 0 || $(grep "^NEXTCLOUD_.*" .env | wc -l) != 0 || $(grep "^PORTAINER_.*" .env | wc -l) != 0 || $(grep "^FLOOD_PASSWORD.*" .env | wc -l) != 0 || $(grep "^CALIBRE_PASSWORD.*" .env | wc -l) != 0 || $(grep "^PAPERLESS_.*" .env | wc -l) != 0 ]]; then
echo "/!\ Some obsolete config has been detected in your .env."
echo "It should be moved in .env.custom as they apply to specific app (this is new since v2.2 update - see documentation)."
echo ""
echo "Please refer to the .env.custom file to see which variables should be ported to the new file."
echo "Exiting now as bad configuration for your services may break your config."
echo ""
echo "Run this script again when variables has been moved to the correct file."
read -r -p "Do you want more explanation (Y/n) ? " help_wanted
if [[ "$help_wanted" =~ ^([yY][eE][sS]|[yY])$ ]]
then
echo "These are the variables you must move to .env.custom:"
echo ""
echo " Variables starting by \"MYSQL_\" (if there are some) ==> Add prefix MARIADB_ in .env.custom"
echo " Variables starting by \"NEXTCLOUD_\" (if there are some) ==> Add another NEXTCLOUD_ prefix in .env.custom"
echo " Variables starting by \"PAPERLESS_\" (if there are some) => Add another PAPERLESS_ prefix in .env.custom"
echo " Variables starting by \"PORTAINER_\" (if there are some) ==> Add another PORTAINER_ prefix in .env.custom"
echo " Variable named \"FLOOD_PASSWORD\" (if existing) ==> Add another FLOOD_ prefix in .env.custom"
echo " Variable named \"CALIBRE_PASSWORD\" (if existing) ==> Add another CALIBRE_ prefix in .env.custom"
echo " Variable named \"WIREGUARD_ENDPOINT\" (if existing) ==> Replace by GLUETUN_VPN_ENDPOINT_IP in .env.custom"
echo " Variable named \"WIREGUARD_PORT\" (if existing) ==> Replace by GLUETUN_VPN_ENDPOINT_PORT in .env.custom"
echo " Variable named \"WIREGUARD_PUBLIC_KEY\" (if existing) ==> Replace by GLUETUN_WIREGUARD_PUBLIC_KEY in .env.custom"
echo " Variable named \"WIREGUARD_PRIVATE_KEY\" (if existing) ==> Replace by GLUETUN_WIREGUARD_PRIVATE_KEY in .env.custom"
echo " Variable named \"WIREGUARD_PRESHARED_KEY\" (if existing) ==> Replace by GLUETUN_WIREGUARD_PRESHARED_KEY in .env.custom"
echo " Variable named \"WIREGUARD_ADDRESS\" (if existing) ==> Replace by GLUETUN_WIREGUARD_ADDRESSES (**plural!**) in .env.custom"
else
echo "Ok bye."
fi
exit 1
fi
# Create/update http_auth file according to values in .env file
source .env
echo "${HTTP_USER}:${HTTP_PASSWORD}" > traefik/http_auth
if [[ ! -d env ]]; then
mkdir -p env
fi
# Sanitize and extract variable (without prefixes) from .env.custom file
# Input => $1 = app name (exemple traefik)
# Output => env/app_name.env written with correct variables (exemple: env/traefik.env)
extract_custom_env_file() {
# sed explanation:
# 1 => Remove all lines starting with a comment (#)
# 2 => Remove all empty lines
# 3 => Remove all lines *NOT* starting by [uppercase_app_name + "_"] (exemple TRAEFIK_)
# 4 => Remove the pattern [uppercase_app_name + "_"]
sed '/^#/d' .env.custom | sed '/^$/d' | sed -n "/^${1^^}_/p" | sed "s/^${1^^}_//g" > env/$1.env
}
## Traefik Certificate Resolver tweaks
if [[ ! -z ${TRAEFIK_CUSTOM_ACME_RESOLVER} ]]; then
if [[ ! -f .env.custom ]]; then
echo "[$0] Error. You need to have a .env.custom in order to use TRAEFIK_CUSTOM_ACME_RESOLVER variable."
exit 1
fi
if [[ ${TRAEFIK_CUSTOM_ACME_RESOLVER} == "changeme" ]]; then
echo "[$0] Error. Wrong value for TRAEFIK_CUSTOM_ACME_RESOLVER variable."
exit 1
fi
yq 'del(.certificatesResolvers.le.acme.httpChallenge)' -i traefik/traefik.yaml
yq '(.certificatesResolvers.le.acme.dnsChallenge.provider="'${TRAEFIK_CUSTOM_ACME_RESOLVER}'")' -i traefik/traefik.yaml
extract_custom_env_file traefik
fi
# Docker-compose settings
export COMPOSE_HTTP_TIMEOUT=240
# Retro-compatibility
[[ -z $HOST_CONFIG_PATH ]] && export HOST_CONFIG_PATH="/data/config"
[[ -z $HOST_MEDIA_PATH ]] && export HOST_MEDIA_PATH="/data/torrents"
[[ -z $DOWNLOAD_SUBFOLDER ]] && export DOWNLOAD_SUBFOLDER="deluge"
[[ -z $DOCKER_COMPOSE_BINARY ]] && export DOCKER_COMPOSE_BINARY="docker-compose"
if [[ ! -f config.yaml ]]; then
echo "[$0] No config.yaml file found. Copying from sample file..."
cp config.sample.yaml config.yaml
fi
###############################################################################################
###################################### Pre-flight checks ######################################
###############################################################################################
echo "[$0] ***** Checking configuration... *****"
yq eval -o json config.yaml > config.json
if [[ "${CHECK_FOR_OUTDATED_CONFIG}" == true ]]; then
nb_services=$(cat config.json | jq '.services | length')
nb_services_sample=$(yq eval -o json config.sample.yaml | jq '.services | length')
if [[ $nb_services_sample -gt $nb_services ]]; then
echo "[$0] There are more services in the config.sample.yaml than in your config.yaml"
echo "[$0] You should check config.sample.yaml because it seems there are new services available for you:"
diff -u config.yaml config.sample.yaml | grep "name:" | grep -E "^\+" | sed "s/+ - name:/-/g" || true
fi
fi
# Internal function which checks another function's number ($2) and return a boolean instead
check_result_service() {
#$1 => service
#$2 => nb to check
if [[ $2 == 0 ]]; then
false; return
elif [[ $2 == 1 ]]; then
true; return
else
echo "[$0] Error. Service \"$1\" is enabled more than once. Check your config.yaml file."
exit 1
fi
}
# Check if a service ($1) has been enabled in the config file
is_service_enabled() {
local nb=$(cat config.json | jq --arg service $1 '[.services[] | select(.name==$service and .enabled==true)] | length')
check_result_service $1 $nb
}
# Check if a service ($1) has been enabled AND has vpn enabled in the config file
has_vpn_enabled() {
local nb=$(cat config.json | jq --arg service $1 '[.services[] | select(.name==$service and .enabled==true and .vpn==true)] | length')
check_result_service $1 $nb
}
# Check if some services have vpn enabled, that gluetun itself is enabled
nb_vpn=$(cat config.json | jq '[.services[] | select(.enabled==true and .vpn==true)] | length')
if [[ ${nb_vpn} -gt 0 ]] && ! is_service_enabled gluetun; then
echo "[$0] ERROR. ${nb_vpn} VPN-enabled services have been enabled BUT gluetun has not been enabled. Please check your config.yaml file."
exit 1
fi
# Determine what host Flood should connect to
# => If deluge vpn is enabled => gluetun
# => If deluge vpn is disabled => deluge
if is_service_enabled flood; then
# Check that if flood is enabled, deluge should also be enabled
if ! is_service_enabled deluge; then
echo "[$0] ERROR. Flood is enabled but Deluge is not. Please either enable Deluge or disable Flood as Flood depends on Deluge."
exit 1
fi
# Determine deluge hostname (for flood) based on the VPN status (enabled or not) of deluge
if has_vpn_enabled deluge; then
export DELUGE_HOST="gluetun"
else
export DELUGE_HOST="deluge"
fi
fi
# Check that if calibre-web is enabled, calibre should also be enabled
if is_service_enabled calibre-web && ! is_service_enabled calibre; then
echo "[$0] ERROR. Calibre-web is enabled but Calibre is not. Please either enable Calibre or disable Calibre-web as Calibre-web depends on Calibre."
exit 1
fi
# Check that if nextcloud is enabled, mariadb should also be enabled
if is_service_enabled nextcloud && ! is_service_enabled mariadb; then
echo "[$0] ERROR. Nextcloud is enabled but MariaDB is not. Please either enable MariaDB or disable Nextcloud as Nextcloud depends on MariaDB."
exit 1
fi
# Apply other arbitrary custom Traefik config files
rm -f $f traefik/custom/custom-*
for f in `find samples/custom-traefik -maxdepth 1 -mindepth 1 -type f | grep -E "\.yml$|\.yaml$" | sort`; do
echo "[$0] Applying custom Traefik config $f..."
cp $f traefik/custom/custom-$(basename $f)
done
# Detect Synology devices for Netdata compatibility
if is_service_enabled netdata; then
if [[ $(uname -a | { grep synology || true; } | wc -l) -eq 1 ]]; then
export OS_RELEASE_FILEPATH="/etc/VERSION"
else
export OS_RELEASE_FILEPATH="/etc/os-release"
fi
fi
###############################################################################################
####################################### SERVICES PARSING ######################################
###############################################################################################
echo "[$0] ***** Generating configuration... *****"
# Cleanup files before start, in case there was a change we start from scratch at every script execution
rm -f services/generated/*-vpn.yaml
rm -f services/generated/*-envfile.yaml
ALL_SERVICES="-f docker-compose.yaml"
GLOBAL_ENV_FILE=".env"
# Parse the config.yaml master configuration file
for json in $(yq eval -o json config.yaml | jq -c ".services[]"); do
name=$(echo $json | jq -r .name)
enabled=$(echo $json | jq -r .enabled)
vpn=$(echo $json | jq -r .vpn)
# Skip disabled services
if [[ ${enabled} == "false" ]]; then
echo-debug "[$0] Service $name is disabled. Skipping it."
continue
fi
echo-debug "[$0] ➡️ Parsing service: \"$name\"..."
# Default docker-compose filename is the service name + .yaml.
# Take into account explicit filename if specified in config
customFile=$(echo $json | jq -r .customFile)
file="$name.yaml"
if [[ ${customFile} != "null" ]]; then
file=${customFile}
fi
echo-debug "[$0] File: \"$file\"..."
# Append $file to global list of files which will be passed to docker commands
ALL_SERVICES="${ALL_SERVICES} -f services/${file}"
# For services with VPN enabled, add a docker-compose "override" file specifying that the service network should
# go through gluetun (main vpn client service).
if [[ ${vpn} == "true" ]]; then
echo "services.${name}.network_mode: service:gluetun" > ${name}-vpn.props
yq -p=props ${name}-vpn.props -o yaml > services/generated/${name}-vpn.yaml
rm -f ${name}-vpn.props
# Append config/${name}-vpn.yaml to global list of files which will be passed to docker commands
ALL_SERVICES="${ALL_SERVICES} -f services/generated/${name}-vpn.yaml"
fi
# For services with existing custom environment variables in .env.custom,
# Extract those variables and add a docker-compose override file in order to load them
if [[ -f .env.custom ]]; then
if grep -q "^${name^^}_.*" .env.custom; then
extract_custom_env_file ${name}
echo "services.${name}.env_file.0: ./env/${name}.env" > ${name}-envfile.props
yq -p=props ${name}-envfile.props -o yaml > services/generated/${name}-envfile.yaml
rm -f ${name}-envfile.props
# Append config/${name}-envfile.yaml to global list of files which will be passed to docker commands
ALL_SERVICES="${ALL_SERVICES} -f services/generated/${name}-envfile.yaml"
fi
fi
# If we are on flood service AND autoconfig for flood password is set to true:
# Check that .env.custom exists and variable defined
# Do the deluge autoconfig - we already checked that deluge is enabled at this point
if [[ ${name} == "flood" && ${FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON} == true ]]; then
# Specific instructions for Flood
if [[ ! -f env/${name}.env ]]; then
echo "ERROR. You set variable \"FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON\" to true but you did not specify key \"FLOOD_FLOOD_PASSWORD\" in your .env.custom."
exit 1
fi
set -a
source env/${name}.env
set +a
# User for Deluge daemon RPC has to be created in deluge auth config file
if [[ ! -z ${FLOOD_PASSWORD} ]]; then
DELUGE_CONFIG_FILE="$HOST_CONFIG_PATH/deluge/auth"
if [[ -r $DELUGE_CONFIG_FILE && -w $DELUGE_CONFIG_FILE ]]; then
if ! grep -q "flood" ${DELUGE_CONFIG_FILE}; then
echo "flood:${FLOOD_PASSWORD}:10" >> ${DELUGE_CONFIG_FILE}
else
echo "[$0] No need to add user/password for flood as it has already been created."
echo "[$0] Consider setting FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON variable to false in .env file."
fi
else
echo "[$0] It seems you do not have permission to read or write to ${DELUGE_CONFIG_FILE} ."
echo "[$0] Prompting for sudo password..."
sudo bash <<EOF
if ! grep -q "flood" ${DELUGE_CONFIG_FILE}; then
echo "flood:${FLOOD_PASSWORD}:10" >> ${DELUGE_CONFIG_FILE}
else
echo "[$0] No need to add user/password for flood as it has already been created."
echo "[$0] Consider setting FLOOD_AUTOCREATE_USER_IN_DELUGE_DAEMON variable to false in .env file."
fi
EOF
fi
else
echo "ERROR. \"FLOOD_FLOOD_PASSWORD\" variable seems not defined but flood service still has variables defined. Please add the missing variable."
exit 1
fi
fi
###### For services which have "command" field with environment variables ######
var_in_cmd_detected="0"
if [[ $(yq ".services.${name}.command[]" services/${file} | { grep "\\$.*\}" || true; } | wc -l) -gt 0 ]]; then
var_in_cmd_detected="1"
echo-debug "[$0] Service ${name} has a command with environment variables..."
# Extract variable names to test them
yq ".services.${name}.command[]" services/${file} | { grep "\\$.*\}" || true; } | sed -n -e 's/.*${\(\w\+\)}.*/\1/p' > env/${name}-cmd.env.1.tmp
(
# Check if these variables are defined in generated .env files (global or custom)
set -a
# Only source custom envfile if it exists
if [[ -f ./env/${name}.env ]]; then
source ./env/${name}.env
fi
source .env
set +a
while read p; do
# If the command references a variable which is not known, throw an error
if [[ -z ${!p+x} ]]; then
echo "ERROR. Variable \"$p\" is referenced in \"command\" for service ${name} (file $file) but this variable is not defined in .env (or in .env.custom with prefix \"${name^^}_\" if existing). Please correct it or add a variable which will be used."
exit 1
fi
done < env/${name}-cmd.env.1.tmp
# Does not work for now because of how docker handles merges for arrays. Original values with variables stay.
# Disabled for now
if [[ "0" == "1" ]]; then
# Extract command block from original service yaml file
yq ".services.${name}.command[]" services/${file} > env/${name}-cmd.env.2.tmp
# Envsubst this file
envsubst < env/${name}-cmd.env.2.tmp > env/${name}-cmd.env.3.tmp
# Convert this file to a props file, used to source a new proper YAML file
i=0
while read line; do
echo "services.${name}.command.$i: $line" >> env/${name}-cmd.env.4.tmp
i=$((i+1))
done < env/${name}-cmd.env.3.tmp
# Generate a proper override file with substituted variables
yq -p=props env/${name}-cmd.env.4.tmp -o yaml > services/generated/${name}-command.yaml
fi
)
rm -f env/*.tmp
# echo-debug "[$0] Adding override file for service ${name} / command with subsituted environment variables..."
# ALL_SERVICES="${ALL_SERVICES} -f services/generated/${name}-command.yaml"
fi
# Handle case for command in a single line, not in array
if [[ $(yq ".services.${name}.command" services/${file} | { grep "\\$.*\}" || true; } | wc -l) -gt 0 ]]; then
var_in_cmd_detected="1"
fi
# Workaround for now
if [[ "${var_in_cmd_detected}" == "1" ]]; then
# Only concat .env.concat with env/${name}.env if it exists
if [[ -f ./env/${name}.env ]]; then
cat ${GLOBAL_ENV_FILE} ./env/${name}.env >> .env.concat.tmp
rm -f .env.concat
mv .env.concat.tmp .env.concat
export GLOBAL_ENV_FILE=".env.concat"
fi
var_in_cmd_detected="0"
fi
###################################### TRAEFIK RULES ######################################
# Skip this part for services which have Traefik rules disabled in config
traefikEnabled=$(echo $json | jq -r .traefik.enabled)
if [[ ${traefikEnabled} == "false" ]]; then
echo-debug "[$0] Traefik is disabled. Skipping rules creation..."
continue
fi
# Loop over all Traefik rules and create the corresponding entries in the generated rules.yaml
echo-debug "[$0] Generating Traefik rules..."
i=0
for rule in $(echo $json | jq -c .traefik.rules[]); do
((i=i+1))
host=$(echo $rule | jq -r .host)
internalPort=$(echo $rule | jq -r .internalPort)
httpAuth=$(echo $rule | jq -r .httpAuth)
echo-debug "[$0] Host => ${host}"
echo-debug "[$0] Internal Port => ${internalPort}"
echo-debug "[$0] Http Authentication => ${httpAuth}"
# If VPN => Traefik rule should redirect to gluetun container
backendHost=${name}
[[ ${vpn} == "true" ]] && backendHost="gluetun"
# Handle custom scheme (default if non-specified is http)
internalScheme="http"
customInternalScheme=$(echo $rule | jq -r .internalScheme)
[[ ${customInternalScheme} != "null" ]] && internalScheme=${customInternalScheme}
# Transform the bash syntax into Traefik/go one => anything.${TRAEFIK_DOMAIN} to anything.{{ env "TRAEFIK_DOMAIN" }}
hostTraefik=$(echo ${host} | sed --regexp-extended 's/^(.*)(\$\{(.*)\})/\1\{\{ env "\3" \}\}/')
ruleId="${name}-${i}"
echo 'http.routers.'"${ruleId}"'.rule: Host(`'${hostTraefik}'`)' >> rules.props
middlewareCount=0
if [[ ${httpAuth} == "true" ]]; then
echo "http.routers.${ruleId}.middlewares.${middlewareCount}: common-auth@file" >> rules.props
((middlewareCount=middlewareCount+1))
fi
traefikService=$(echo $rule | jq -r .service)
if [[ ${traefikService} != "null" ]]; then
echo "http.routers.${ruleId}.service: ${traefikService}" >> rules.props
else
echo "http.routers.${ruleId}.service: ${ruleId}" >> rules.props
fi
# Check if httpOnly flag is enabled
# If enabled => Specify to use only "insecure" (port 80) entrypoint
# If not => use all entryPoints (by not specifying any) but force redirection to https
httpOnly=$(echo $rule | jq -r .httpOnly)
if [[ ${httpOnly} == true ]]; then
echo "http.routers.${ruleId}.entryPoints.0: insecure" >> rules.props
else
echo "http.routers.${ruleId}.middlewares.${middlewareCount}: redirect-to-https" >> rules.props
((middlewareCount=middlewareCount+1))
fi
# If the specified service does not contain a "@" => we create it
# If the service has a @, it means it is defined elsewhere so we do not create it (custom file, @internal...)
if echo ${traefikService} | grep -vq "@"; then
echo "http.services.${ruleId}.loadBalancer.servers.0.url: ${internalScheme}://${backendHost}:${internalPort}" >> rules.props
fi
done
done
# Convert properties files into Traefik-ready YAML and place it in the correct folder loaded by Traefik
mv traefik/custom/dynamic-rules.yaml traefik/custom/dynamic-rules-old.yaml || true
yq -p=props rules.props -o yaml > traefik/custom/dynamic-rules.yaml
rm -f rules.props
# Post-transformations on the rules file
# sed -i "s/EMPTYMAP/{}/g" traefik/custom/dynamic-rules.yaml
# Add simple quotes around Host rule
sed -i --regexp-extended "s/^(.*: )(Host.*$)/\1'\2'/g" traefik/custom/dynamic-rules.yaml
# Add double quotes around the backend traefik service
sed -i --regexp-extended "s/^(.*url: )(.*$)/\1\"\2\"/g" traefik/custom/dynamic-rules.yaml
rm -f traefik/custom/dynamic-rules-old.yaml
echo-debug "[$0] Here is the list of all files which are going to be processed: ${ALL_SERVICES}"
echo "[$0] ***** Config OK. Launching services... *****"
if [[ "${SKIP_PULL}" != "1" ]]; then
echo "[$0] ***** Pulling all images... *****"
${DOCKER_COMPOSE_BINARY} ${ALL_SERVICES} pull
fi
echo "[$0] ***** Recreating containers if required... *****"
${DOCKER_COMPOSE_BINARY} --env-file ${GLOBAL_ENV_FILE} ${ALL_SERVICES} up -d --remove-orphans
echo "[$0] ***** Done updating containers *****"
rm -f .env.concat
echo "[$0] ***** Clean unused images and volumes... *****"
docker image prune -af
docker volume prune -f
echo "[$0] ***** Done! *****"
exit 0