#!/usr/bin/env bash set -euo pipefail script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" repo_root="${script_dir}" env_file="${repo_root}/.env.devprod" if [[ ! -f "${env_file}" ]]; then echo "Missing ${env_file}. Run ./start-devprod.sh first." exit 1 fi read_kv() { local key="$1" local line line="$(grep -m1 -E "^${key}=" "${env_file}" || true)" if [[ -z "${line}" ]]; then return 1 fi echo "${line#*=}" } mode="ssl" extauth="0" recreate_qortal="0" for arg in "$@"; do case "${arg}" in --nossl) mode="nossl" ;; --ssl) mode="ssl" ;; --extauth) extauth="1" ;; --qortal) recreate_qortal="1" ;; esac done if [[ "${mode}" != "nossl" && "${mode}" != "ssl" ]]; then mode="ssl" fi if [[ "${mode}" == "ssl" && ! "$*" =~ --ssl && ! "$*" =~ --nossl ]]; then read -r -p "Use no-SSL compose (external proxy)? (y/N): " use_nossl if [[ "${use_nossl}" == "y" || "${use_nossl}" == "Y" ]]; then mode="nossl" fi fi compose_file="${repo_root}/docker-compose.devprod.yml" if [[ "${mode}" == "nossl" ]]; then compose_file="${repo_root}/docker-compose.devprod.nossl.yml" fi qortal_context="$(grep -E '^QORTAL_NODE_CONTEXT=' "${env_file}" | tail -n1 | cut -d= -f2- || true)" qortal_dockerfile="$(grep -E '^QORTAL_NODE_DOCKERFILE=' "${env_file}" | tail -n1 | cut -d= -f2- || true)" echo "Qortal build source: context=${qortal_context:-../qortal} dockerfile=${qortal_dockerfile:-Dockerfile}" mkdir -p "${repo_root}/qortal/data" if [[ -x "${repo_root}/scripts/ensure-qortal-settings.sh" ]]; then "${repo_root}/scripts/ensure-qortal-settings.sh" fi if [[ -x "${repo_root}/scripts/ensure-qortal-start-args.sh" ]]; then "${repo_root}/scripts/ensure-qortal-start-args.sh" "${env_file}" fi if [[ -x "${repo_root}/scripts/select-qortal-p2p-port.sh" ]]; then "${repo_root}/scripts/select-qortal-p2p-port.sh" "${env_file}" fi if [[ -f "${repo_root}/scripts/ensure-broker-internal-token.sh" ]]; then bash "${repo_root}/scripts/ensure-broker-internal-token.sh" "${env_file}" fi broker_internal_api_token="$(read_kv "BROKER_INTERNAL_API_TOKEN" || true)" if [[ -z "${broker_internal_api_token}" ]]; then echo "BROKER_INTERNAL_API_TOKEN is missing in ${env_file}" echo "Run: bash scripts/ensure-broker-internal-token.sh ${env_file}" exit 1 fi export BROKER_INTERNAL_API_TOKEN="${broker_internal_api_token}" broker_cors_allowed_origins="$(read_kv "BROKER_CORS_ALLOWED_ORIGINS" || true)" if [[ -n "${broker_cors_allowed_origins}" ]]; then export BROKER_CORS_ALLOWED_ORIGINS="${broker_cors_allowed_origins}" fi echo "Broker auth env loaded from ${env_file}: token_set=yes cors_origins=${broker_cors_allowed_origins:-}" if command -v rg >/dev/null 2>&1; then profiles_line="$(rg -m1 '^COMPOSE_PROFILES=' "${env_file}" || true)" if [[ -n "${profiles_line}" ]]; then export COMPOSE_PROFILES="${profiles_line#COMPOSE_PROFILES=}" fi fi if [[ "${extauth}" == "1" ]]; then if [[ -z "${COMPOSE_PROFILES:-}" ]]; then export COMPOSE_PROFILES="external-auth" elif [[ ",${COMPOSE_PROFILES}," != *",external-auth,"* ]]; then export COMPOSE_PROFILES="${COMPOSE_PROFILES},external-auth" fi fi echo "Recreating containers using ${compose_file}..." mapfile -t services < <(docker compose -f "${compose_file}" --env-file "${env_file}" config --services) target_services=() for svc in "${services[@]}"; do if [[ "${recreate_qortal}" != "1" && "${svc}" == "qortal_node" ]]; then continue fi if [[ "${extauth}" == "1" && "${svc}" == "external_auth" ]]; then # Handle external_auth in a separate pass so --force-recreate does not # implicitly recreate qortal_node through depends_on. continue fi target_services+=("${svc}") done if [[ "${#target_services[@]}" -eq 0 ]]; then echo "No services selected for recreation." exit 1 fi if [[ "${recreate_qortal}" == "1" ]]; then echo "Including qortal_node in force-recreate." echo "Building qortal_node with --no-cache to ensure Dockerfile/entrypoint changes are applied..." docker compose -f "${compose_file}" --env-file "${env_file}" build --no-cache qortal_node else echo "Excluding qortal_node from force-recreate (use --qortal to include it)." fi docker compose -f "${compose_file}" --env-file "${env_file}" up -d --build --force-recreate "${target_services[@]}" if [[ "${extauth}" == "1" ]]; then echo "Rebuilding and recreating external_auth..." docker compose -f "${compose_file}" --env-file "${env_file}" build external_auth if [[ "${recreate_qortal}" == "1" ]]; then docker compose -f "${compose_file}" --env-file "${env_file}" up -d --build --force-recreate external_auth else docker compose -f "${compose_file}" --env-file "${env_file}" up -d --build --force-recreate --no-deps external_auth fi fi docker compose -f "${compose_file}" --env-file "${env_file}" ps echo "Refreshing Nextcloud app registration..." docker compose -f "${compose_file}" --env-file "${env_file}" exec -T app php occ app:disable qortal_integration docker compose -f "${compose_file}" --env-file "${env_file}" exec -T app php occ app:enable qortal_integration echo "Rebuilding Nextcloud app cache..." docker compose -f "${compose_file}" --env-file "${env_file}" exec -T app php occ maintenance:repair echo "Done."