LibrePortal/variables.sh
librelad e25c69e2a1 Make multi-instance work without a domain
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>
2026-08-19 02:53:43 +01:00

87 lines
3.2 KiB
Bash
Executable File

#!/bin/bash
trap exitScript SIGINT
# Directories are contained in init.sh
# Define text colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
BLUE='\033[1;34m'
PINK='\033[0;35m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m' # No Color
# Date/Time
backupDate=$(date +'%F')
backupFolder="backup_$(date +"%Y%m%d%H%M%S")"
current_date=$(date +%Y-%m-%d)
current_time=$(date +%H:%M:%S)
# Domain/Network
# Try to get public IP, fallback to local IP if all fail
if command -v dig >/dev/null 2>&1; then
public_ip_v4=$(dig +short myip.opendns.com @resolver1.opendns.com 2>/dev/null)
fi
# Fallback to local IP if dig failed or returned empty
if [[ -z "$public_ip_v4" ]]; then
public_ip_v4=$(hostname -I | awk '{print $1}' 2>/dev/null)
fi
# Final fallback to localhost
if [[ -z "$public_ip_v4" ]]; then
public_ip_v4="localhost"
fi
# This host's LAN address — the source IP the kernel picks for the default route.
# Deliberately separate from $public_ip_v4 above, which prefers the WAN address an
# external resolver sees. Anything advertising a *directly published host port*
# (APP_URL, printed logins, the WebUI's service URLs) must use this one: LibrePortal
# never port-forwards, so the WAN address only ever resolves for someone who set up
# forwarding by hand, while the LAN/VPN address is what clients actually dial.
local_ip_v4="$(ip -4 route get 1.1.1.1 2>/dev/null | grep -Po '(?<=src )(\S+)' | head -1)"
if [[ -z "$local_ip_v4" ]]; then
local_ip_v4=$(hostname -I | awk '{print $1}' 2>/dev/null)
fi
if [[ -z "$local_ip_v4" ]]; then
local_ip_v4="localhost"
fi
server_nic="$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)"
default_subnet="10.100.0"
# Files
docker_rooted_socket="/var/run/docker.sock"
swap_file=/swapfile
# Rootless sysctl settings + the "rootless configured" marker. MUST live under
# /etc/sysctl.d/ — `sysctl --system` only reads there (+ /etc/sysctl.conf), NOT
# the old non-standard /etc/sysctl/ path, so settings written elsewhere never
# persist across reboot.
sysctl="/etc/sysctl.d/99-libreportal-rootless.conf"
# Rootless Docker's installer aborts outright when the legacy ip_tables modules
# aren't loaded. Ubuntu 24.04/26.04 don't autoload them on a fresh box, so we
# both modprobe them now and persist them here for subsequent boots.
modules_load="/etc/modules-load.d/libreportal-rootless.conf"
# Env vars that must survive the privilege drop into $docker_install_user for the
# backup engines to open their repository (repo URI + passphrase + ssh transport).
# Named explicitly rather than relying on `sudo -E`: sudo-rs, the default on
# Ubuntu 25.10+ (incl. 26.04), does not implement bare -E — it warns and runs the
# command with the environment dropped. Keep in sync with the fallback list in
# scripts/docker/command/run_privileged.sh (init.sh sources that file directly,
# without this one).
backup_env_preserve="BORG_PASSPHRASE,BORG_REPO,BORG_RSH,KOPIA_CHECK_FOR_UPDATES,KOPIA_CONFIG_PATH,KOPIA_PASSWORD,RESTIC_PASSWORD,RESTIC_REPOSITORY,RESTIC_SFTP_COMMAND"
docker_log_file=libreportal.log
backup_log_file=backup.log
db_file=database.db
migrate_file=migrate.txt
run_file=run.txt
# Configs
update_done=false
config_file_wireguard=config_wireguard
# Menu
menu_number=0