#!/usr/bin/env bash # Primora one-line installer. # # curl -fsSL https://raw.githubusercontent.com/Dvorinka/Primora/master/install.sh | bash # # Installs into ./primora (override with PRIMORA_DIR). On a fresh install, # interactive shells get one question — the URL the app will be opened on # (domain or IP, optional port). Non-interactive: # PUBLIC_URL=https://primora.example.com bash install.sh # DOMAIN=192.168.1.50 NGINX_PORT=8085 bash install.sh (legacy form) # # https URLs mean TLS terminates at your own proxy in front of Primora's # bundled nginx (which always speaks http on NGINX_PORT). # # Pulls prebuilt GHCR images when available; otherwise downloads the source # tarball and builds locally. Either way the result is the same compose stack. set -euo pipefail REPO="Dvorinka/Primora" REF="${PRIMORA_REF:-master}" DIR="${PRIMORA_DIR:-primora}" NGINX_PORT="${NGINX_PORT:-80}" PUBLIC_URL="${PUBLIC_URL:-}" info() { echo "==> $*"; } die() { echo "ERROR: $*" >&2; exit 1; } # '|' delimiter for sed: base64 output can contain '/', '+', '='. SED=(sed -i) [[ "$OSTYPE" == darwin* ]] && SED=(sed -i '') command -v docker >/dev/null 2>&1 || die "docker is not installed" docker compose version >/dev/null 2>&1 || die "docker compose plugin is not installed" command -v curl >/dev/null 2>&1 || die "curl is not installed" mkdir -p "$DIR/infra/nginx" cd "$DIR" # The compose stack needs exactly these three files from the repo. # Timeouts + retries: a stalled connection must fail loudly, not hang. info "Fetching compose files ($REF)" for f in docker-compose.yml .env.example infra/nginx/default.conf; do curl -fsSL --connect-timeout 10 --max-time 60 --retry 3 --retry-delay 1 --retry-all-errors \ "https://raw.githubusercontent.com/$REPO/$REF/$f" -o "$f" \ || die "could not fetch $f — check connectivity to raw.githubusercontent.com" done if [ -f .env ]; then info "Existing .env kept" # Display URL comes from the file — answers here would change nothing. PUBLIC_URL="$(grep -E '^VITE_APP_URL=' .env | tail -1 | cut -d= -f2- || true)" [ -z "$PUBLIC_URL" ] && PUBLIC_URL="http://localhost" else # Public URL — the single question. Env wins, then prompt, then default. if [ -z "$PUBLIC_URL" ] && [ -n "${DOMAIN:-}" ]; then PUBLIC_URL="http://${DOMAIN}" [ "$NGINX_PORT" != "80" ] && PUBLIC_URL="$PUBLIC_URL:$NGINX_PORT" fi if [ -z "$PUBLIC_URL" ]; then DEFAULT_URL="http://localhost" [ "$NGINX_PORT" != "80" ] && DEFAULT_URL="http://localhost:$NGINX_PORT" # Under `curl | bash` stdin is the script pipe — ask on the controlling # terminal instead. `true /dev/null` here — exec redirections persist and would # silence stderr, including the read prompt below, for the whole script. if true 2>/dev/null