fix(cli, compose): optimize startup speed, clean progress output, and show dashboard on start

This commit is contained in:
soulis-1256 2026-08-20 22:50:12 +03:00
parent dc45fe8db6
commit 2ca21c6b01
No known key found for this signature in database
7 changed files with 79 additions and 58 deletions

View file

@ -244,7 +244,7 @@ wait_for_services() {
fi
if [ "$total" -gt 0 ] && [ "$ready" -eq "$total" ]; then
echo >&2
printf '\r\033[K' >&2
log_success "All $total services are ready."
return 0
fi
@ -258,7 +258,7 @@ wait_for_services() {
wait_time=$((wait_time + 1))
done
echo >&2
printf '\r\033[K' >&2
log_error "Not all services became ready within ${timeout}s ($ready/$total ready${waiting[*]:+: ${waiting[*]}})"
}
@ -542,10 +542,12 @@ start_app() {
fi
if [ "$#" -eq 0 ]; then
"${DC[@]}" up -d --remove-orphans || log_error "Failed to start services"
compose_up_stack "${MEDIA_SERVICE:-jellyfin}" || log_error "Failed to start services"
wait_for_services
echo
check_status || true
else
"${DC[@]}" up -d --remove-orphans "$@" || log_error "Failed to start services"
compose_up_stack "${MEDIA_SERVICE:-jellyfin}" "$@" || log_error "Failed to start services"
fi
}
@ -554,12 +556,14 @@ restart_app() {
prepare_install_dirs "$INSTALL_DIR" "$_HOST_UID" "$_HOST_GID"
if [ "$#" -eq 0 ]; then
"${DC[@]}" stop || log_warning "Some services failed to stop"
"${DC[@]}" up -d --remove-orphans || log_error "Failed to start services"
wait_while "Stopping services" "${DC[@]}" stop || log_warning "Some services failed to stop"
compose_up_stack "${MEDIA_SERVICE:-jellyfin}" || log_error "Failed to start services"
wait_for_services
echo
check_status || true
else
"${DC[@]}" stop "$@" || log_warning "Some services failed to stop"
"${DC[@]}" up -d --remove-orphans "$@" || log_error "Failed to start services"
compose_up_stack "${MEDIA_SERVICE:-jellyfin}" "$@" || log_error "Failed to start services"
fi
}

View file

@ -16,11 +16,12 @@ services:
ports:
- 8096:8096
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8096/health"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8096/health"]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
start_period: 30s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:
@ -43,11 +44,12 @@ services:
ports:
- 8096:8096
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8096/emby/System/Ping"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8096/emby/System/Ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
start_period: 30s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:
@ -70,11 +72,12 @@ services:
- ${INSTALL_DIRECTORY}/config/plex:/config
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:32400/identity"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:32400/identity"]
interval: 10s
timeout: 5s
retries: 3
start_period: 90s
start_period: 30s
start_interval: 2s
# qBittorrent — torrent client (ports added by overlay)
qbittorrent:
@ -91,11 +94,12 @@ services:
- ${INSTALL_DIRECTORY}/config/qbittorrent:/config
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8081"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8081"]
interval: 5s
timeout: 3s
retries: 3
start_period: 30s
start_period: 20s
start_interval: 2s
# Sonarr — TV show management and automation
sonarr:
@ -114,11 +118,12 @@ services:
ports:
- 8989:8989
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8989/ping"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:8989/ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
start_period: 60s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:
@ -141,11 +146,12 @@ services:
ports:
- 7878:7878
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:7878/ping"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:7878/ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
start_period: 60s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:
@ -165,11 +171,12 @@ services:
ports:
- 9696:9696
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:9696/ping"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:9696/ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
start_period: 60s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:
@ -191,11 +198,12 @@ services:
expose:
- "5055"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5055/api/v1/settings/public"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:5055/api/v1/settings/public"]
interval: 10s
timeout: 5s
retries: 5
start_period: 60s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:
@ -236,10 +244,11 @@ services:
"-c",
"import urllib.request; urllib.request.urlopen('http://127.0.0.1:5055/_assemblrr/ready', timeout=5)",
]
interval: 30s
timeout: 10s
interval: 10s
timeout: 5s
retries: 3
start_period: 20s
start_period: 30s
start_interval: 2s
command: ["python3", "/scripts/seerr-gateway.py"]
restart: unless-stopped
networks:
@ -307,11 +316,12 @@ services:
ports:
- 6767:6767
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:6767/api/system/ping"]
interval: 30s
timeout: 10s
test: ["CMD", "curl", "-sf", "http://127.0.0.1:6767/api/system/ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 60s
start_period: 30s
start_interval: 2s
restart: unless-stopped
networks:
assemblrr_network:

View file

@ -36,10 +36,11 @@ services:
"CMD-SHELL",
"wget -qO /dev/null http://127.0.0.1:9999/v1/healthcheck || exit 1",
]
interval: 15s
interval: 10s
timeout: 5s
retries: 3
start_period: 15s
start_period: 10s
start_interval: 2s
volumes:
- ${INSTALL_DIRECTORY}/config/gluetun:/gluetun
restart: unless-stopped
@ -60,6 +61,7 @@ services:
timeout: 3s
retries: 2
start_period: 10s
start_interval: 2s
restart: unless-stopped
deunhealth:

View file

@ -34,7 +34,7 @@ log_debug() { _log_to_file "DEBUG: $1"; return 0; }
wait_inline() {
local label="$1"
local secs="${2:-0}"
printf '\r%s (%ss) ' "$label" "$secs" >&2
printf '\r\033[K%s (%ss)' "$label" "$secs" >&2
}
# Run a command while updating wait_inline every second.
@ -62,7 +62,7 @@ wait_while() {
[ "$had_errexit" = 1 ] && set -e
kill "$ticker" 2>/dev/null || true
wait "$ticker" 2>/dev/null || true
echo >&2
printf '\r\033[K' >&2
WAIT_WHILE_OUTPUT=$(cat "$out" 2>/dev/null || true)
rm -f "$out"
return "$rc"

View file

@ -16,7 +16,7 @@ test_vpn_connection_shared() {
log_info "Testing VPN connection by starting Gluetun first..."
# Force recreate so updated secrets/.env from a credential retry always apply.
if ! "${docker_cmd[@]}" up -d --force-recreate gluetun 2>/dev/null; then
if ! "${docker_cmd[@]}" up -d --force-recreate gluetun >/dev/null 2>&1; then
log_warning "Failed to start Gluetun container. VPN configuration may be incorrect."
log_info "Check secrets/ (credentials) and .env (VPN_SERVICE, VPN_TYPE, WIREGUARD_ADDRESSES)."
return 1
@ -29,16 +29,16 @@ test_vpn_connection_shared() {
health=$(docker inspect --format='{{.State.Health.Status}}' gluetun 2>/dev/null || echo "unknown")
if [ "$health" = "healthy" ]; then
echo >&2
printf '\r\033[K' >&2
log_success "VPN connection established successfully!"
return 0
elif [ "$health" = "unhealthy" ]; then
echo >&2
printf '\r\033[K' >&2
log_warning "VPN connection failed. Gluetun logs:"
"${docker_cmd[@]}" logs gluetun --tail=20 2>/dev/null
echo
log_info "Fix VPN credentials in secrets/ (and WIREGUARD_ADDRESSES in .env if using WireGuard), then try again."
"${docker_cmd[@]}" stop gluetun 2>/dev/null
"${docker_cmd[@]}" stop gluetun >/dev/null 2>&1 || true
return 1
fi
@ -47,12 +47,12 @@ test_vpn_connection_shared() {
wait_time=$((wait_time + 3))
done
echo >&2
printf '\r\033[K' >&2
log_warning "VPN connection timed out after ${max_wait}s. Gluetun logs:"
"${docker_cmd[@]}" logs gluetun --tail=20 2>/dev/null
echo
log_info "The VPN may need more time, or credentials may be incorrect (see secrets/ and .env)."
"${docker_cmd[@]}" stop gluetun 2>/dev/null
"${docker_cmd[@]}" stop gluetun >/dev/null 2>&1 || true
return 1
}

View file

@ -4,7 +4,7 @@
migration_id="003_standardize_quality_profiles"
migration_description="Remove superseded Recyclarr include packs from prior versions"
readonly LEGACY_RECYCLARR_INCLUDES=(
LEGACY_RECYCLARR_INCLUDES=(
"radarr-hd.yml"
"radarr-uhd.yml"
"radarr-web-1080.yml"

View file

@ -74,7 +74,12 @@ assert_contains "$up" "Starting services" "friendly wait label"
assert_contains "$up" "tail -n 40" "prints a log tail on failure"
assert_true "setup uses compose_up_stack" "grep -q 'compose_up_stack' \"$REPO_ROOT/bin/setup.sh\""
assert_true "upgrade uses compose_up_stack" "grep -q 'compose_up_stack' \"$REPO_ROOT/lib/upgrade.sh\""
assert_true "cli uses compose_up_stack" "grep -q 'compose_up_stack' \"$REPO_ROOT/bin/cli.sh\""
assert_not_contains "$(sed -n '/compose_up_stack/,/exit 1/p' "$REPO_ROOT/bin/setup.sh")" \
"run_docker compose" "setup no longer streams compose up"
test_suite "healthcheck fast-start intervals"
assert_contains "$(grep start_interval "$REPO_ROOT/compose/base.yaml")" "start_interval: 2s" "base.yaml has fast healthcheck start_interval"
assert_contains "$(grep start_interval "$REPO_ROOT/compose/vpn.yaml")" "start_interval: 2s" "vpn.yaml has fast healthcheck start_interval"
test_summary