An instance's isolation never needed a domain — its own slug, dir, secrets, IP and randomly-allocated host port already make two copies independent. But the routing layer assumed one, so a LAN-only box got a broken instance rather than a port-served one. Four fixes: - instanceCreate now rewrites the parent-service column of the cloned config's PORT_ rows to match the service names it stamps into the compose. That value is stored as network_resources.parent_service and joined against the compose-derived service names, so an instance left carrying the TYPE's service name matched nothing: it rendered in the WebUI with no port, no URL and no login row despite being up and reachable. - `instance create --local` (plus a LAN-only toggle in the modal) forces every port to access=private, traefik=false, for a second copy that should stay off the domain even when one is configured. - initializeAppVariables forces the traefik column false when no CFG_DOMAIN_n is set. Previously a traefik=true port with an empty domain stamped Host(`app.`) — a trailing-dot host matching nothing — and dragged APP_URL to https://app. with it, breaking every app that builds its links from APP_URL. host_setup is blanked for the same reason. The published host port is untouched; access type, not the traefik flag, gates allocation. - APP_URL's direct host-port branch now prefers a new $local_ip_v4 (the source IP for the default route) over $public_ip_v4, which is the WAN address from an external resolver. LibrePortal never forwards ports, so the WAN address was unreachable for exactly the LAN/VPN clients that branch serves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
76 lines
2.8 KiB
Bash
76 lines
2.8 KiB
Bash
#!/bin/bash
|
|
|
|
# Instance Commands Handler
|
|
# Multi-instance lifecycle for multi-instance-capable apps. Mutating verbs route
|
|
# through the task system (mirroring `app install`): the WebUI queues a task, the
|
|
# processor re-invokes the CLI with LIBREPORTAL_TASK_EXEC=1, and only then does
|
|
# the real work run. No new mutating backend API endpoint is introduced.
|
|
|
|
cliHandleInstanceCommands()
|
|
{
|
|
local action="$initial_command2"
|
|
|
|
# --local/--lan is pulled out of the positional list rather than given a fixed
|
|
# slot, so it can be written anywhere after the verb — `instance create
|
|
# bookstack home --local` reads naturally and still leaves domain#/subdomain
|
|
# in their documented positions for callers that pass them.
|
|
local local_only="false"
|
|
local -a _pos=()
|
|
local _a
|
|
for _a in "$initial_command3" "$initial_command4" "$initial_command5" \
|
|
"$initial_command6" "$initial_command7"; do
|
|
case "$_a" in
|
|
"--local"|"--lan") local_only="true" ;;
|
|
*) _pos+=("$_a") ;;
|
|
esac
|
|
done
|
|
|
|
local type="${_pos[0]}"
|
|
local name="${_pos[1]}"
|
|
local domain_idx="${_pos[2]}"
|
|
local subdomain="${_pos[3]}"
|
|
|
|
case "$action" in
|
|
"create")
|
|
if [[ -z "$type" || -z "$name" ]]; then
|
|
isNotice "Usage: libreportal instance create <type> <name> [domain_index] [subdomain] [--local]"
|
|
cliShowInstanceHelp
|
|
return 1
|
|
fi
|
|
if [[ "$LIBREPORTAL_TASK_EXEC" == "1" ]]; then
|
|
instanceCreate "$type" "$name" "$domain_idx" "$subdomain" "$local_only"
|
|
else
|
|
local _cmd="libreportal instance create $type $name"
|
|
[[ -n "$domain_idx" ]] && _cmd+=" $domain_idx"
|
|
[[ -n "$subdomain" ]] && _cmd+=" $subdomain"
|
|
# Re-invocation must carry the flag or the task-side run would
|
|
# silently build a Traefik-routed instance instead.
|
|
[[ "$local_only" == "true" ]] && _cmd+=" --local"
|
|
cliTaskRun "$_cmd" "install" "${type}_$(instanceIdPart "$name")"
|
|
fi
|
|
;;
|
|
|
|
"remove"|"delete")
|
|
# Here $type holds the instance slug (positional reuse).
|
|
local slug="$type"
|
|
if [[ -z "$slug" ]]; then
|
|
isNotice "Usage: libreportal instance remove <slug>"
|
|
return 1
|
|
fi
|
|
if [[ "$LIBREPORTAL_TASK_EXEC" == "1" ]]; then
|
|
instanceRemove "$slug"
|
|
else
|
|
cliTaskRun "libreportal instance remove $slug" "uninstall" "$slug"
|
|
fi
|
|
;;
|
|
|
|
"list")
|
|
instanceList "$type" # $type optional = filter by app type
|
|
;;
|
|
|
|
*)
|
|
cliShowInstanceHelp
|
|
;;
|
|
esac
|
|
}
|