From 32136ac6fd87e3093c71ac46e1c99077442c49f6 Mon Sep 17 00:00:00 2001 From: RocketQuack <202538874+Rocket-Quack@users.noreply.github.com> Date: Sun, 1 Mar 2026 20:16:39 +0100 Subject: [PATCH] feat(easy-docker): add stack-level compose start with topology guard --- .../lib/app/wizard/common/compose.sh | 113 ++++++++++++++++++ .../easy-docker/lib/app/wizard/common/core.sh | 19 +++ .../lib/app/wizard/flows/manage.sh | 38 ++++++ .../easy-docker/lib/ui/screens/production.sh | 3 +- 4 files changed, 172 insertions(+), 1 deletion(-) diff --git a/scripts/easy-docker/lib/app/wizard/common/compose.sh b/scripts/easy-docker/lib/app/wizard/common/compose.sh index ec5def28..abe50ee0 100755 --- a/scripts/easy-docker/lib/app/wizard/common/compose.sh +++ b/scripts/easy-docker/lib/app/wizard/common/compose.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash EASY_DOCKER_BUILD_ERROR_DETAIL="" +# shellcheck disable=SC2034 # Read by manage flow after start_stack_with_compose_from_metadata fails. +EASY_DOCKER_COMPOSE_ERROR_DETAIL="" render_stack_compose_from_metadata() { local stack_dir="${1}" @@ -77,6 +79,117 @@ EOF return 0 } +start_stack_with_compose_from_metadata() { + local stack_dir="${1}" + local metadata_path="" + local env_path="" + local compose_files_lines="" + local compose_file="" + local source_compose_path="" + local env_erpnext_version="" + local fallback_erpnext_version="" + local configured_pull_policy="" + local runtime_pull_policy="" + local custom_image="" + local custom_tag="" + local image_ref="" + local stack_topology="" + local repo_root="" + local -a compose_args=() + + # shellcheck disable=SC2034 # Read by manage flow after start_stack_with_compose_from_metadata fails. + EASY_DOCKER_COMPOSE_ERROR_DETAIL="" + + metadata_path="${stack_dir}/metadata.json" + env_path="$(get_stack_env_path "${stack_dir}")" + + if [ ! -f "${metadata_path}" ]; then + return 31 + fi + + if [ ! -f "${env_path}" ]; then + return 32 + fi + + stack_topology="$(get_stack_topology "${stack_dir}" || true)" + if [ -z "${stack_topology}" ]; then + # shellcheck disable=SC2034 # Read by manage flow after start_stack_with_compose_from_metadata returns 33. + EASY_DOCKER_COMPOSE_ERROR_DETAIL="metadata.json missing topology" + return 33 + fi + + case "${stack_topology}" in + "single-host") ;; + *) + # shellcheck disable=SC2034 # Read by manage flow after start_stack_with_compose_from_metadata returns 34. + EASY_DOCKER_COMPOSE_ERROR_DETAIL="${stack_topology}" + return 34 + ;; + esac + + env_erpnext_version="$(get_env_file_key_value "${env_path}" "ERPNEXT_VERSION" || true)" + if [ -z "${env_erpnext_version}" ]; then + fallback_erpnext_version="$(get_default_erpnext_version || true)" + fi + + configured_pull_policy="$(get_env_file_key_value "${env_path}" "PULL_POLICY" || true)" + if [ -z "${configured_pull_policy}" ]; then + custom_image="$(get_env_file_key_value "${env_path}" "CUSTOM_IMAGE" || true)" + custom_tag="$(get_env_file_key_value "${env_path}" "CUSTOM_TAG" || true)" + if [ -n "${custom_image}" ] && [ -n "${custom_tag}" ]; then + image_ref="${custom_image}:${custom_tag}" + if docker image inspect "${image_ref}" >/dev/null 2>&1; then + runtime_pull_policy="if_not_present" + fi + fi + fi + + compose_files_lines="$(get_metadata_compose_files_lines "${metadata_path}" || true)" + if [ -z "${compose_files_lines}" ]; then + return 35 + fi + + repo_root="$(get_easy_docker_repo_root)" + while IFS= read -r compose_file; do + if [ -z "${compose_file}" ]; then + continue + fi + + source_compose_path="${repo_root}/${compose_file}" + if [ ! -f "${source_compose_path}" ]; then + # shellcheck disable=SC2034 # Read by manage flow after start_stack_with_compose_from_metadata returns 36. + EASY_DOCKER_COMPOSE_ERROR_DETAIL="${source_compose_path}" + return 36 + fi + + compose_args+=(-f "${source_compose_path}") + done < ${EASY_DOCKER_COMPOSE_ERROR_DETAIL}" 4 + ;; + 37) + show_warning_and_wait "docker compose up failed. Check the output above for details." 4 + ;; + *) + show_warning_and_wait "Cannot start stack with docker compose (${compose_start_status})." 4 + ;; + esac + continue + fi + + show_warning_and_wait "Stack started successfully with docker compose: ${stack_name}" 3 + ;; "Docker") while true; do docker_action="$(show_manage_stack_docker_menu "${stack_name}" "${stack_dir}" || true)" diff --git a/scripts/easy-docker/lib/ui/screens/production.sh b/scripts/easy-docker/lib/ui/screens/production.sh index a2721f7c..b99d9284 100755 --- a/scripts/easy-docker/lib/ui/screens/production.sh +++ b/scripts/easy-docker/lib/ui/screens/production.sh @@ -365,12 +365,13 @@ show_manage_stack_actions_menu() { render_box_message "${status_text}" "0 2" >&2 gum choose \ - --height 7 \ + --height 8 \ --header "Stack actions" \ --cursor.foreground 63 \ --selected.foreground 45 \ "Apps" \ "Docker" \ + "Start stack in Docker Compose" \ "Back" \ "Exit and close easy-docker" }