#!/usr/bin/env bash set -euo pipefail INSTALL_DIR="${ONYXIO_INSTALL_DIR:-/opt/onyxio}" VERSION="${ONYXIO_VERSION:-latest}" SERVER_IMAGE="${ONYXIO_SERVER_IMAGE:-ghcr.io/onyxio-pty-ltd/server:${VERSION}}" POSTGRES_IMAGE="${ONYXIO_POSTGRES_IMAGE:-postgres:15}" REGISTRY="${ONYXIO_REGISTRY:-ghcr.io}" REGISTRY_USERNAME="${ONYXIO_REGISTRY_USERNAME:-}" REGISTRY_TOKEN="${ONYXIO_REGISTRY_TOKEN:-}" prompt() { local message="$1" local default_value="${2:-}" local value="" if [ -r /dev/tty ]; then if [ -n "$default_value" ]; then read -r -p "${message} [${default_value}]: " value &2 return 1 } prompt_secret() { local message="$1" local value="" if [ -r /dev/tty ]; then read -r -s -p "${message}: " value &2 echo "$value" return fi echo "Cannot prompt for ${message}; provide it as an environment variable." >&2 return 1 } compose() { if docker compose version >/dev/null 2>&1; then docker compose "$@" elif command -v docker-compose >/dev/null 2>&1; then docker-compose "$@" else echo "Docker Compose is required." >&2 exit 1 fi } random_secret() { if command -v openssl >/dev/null 2>&1; then openssl rand -hex 32 else date +%s%N | sha256sum | awk '{print $1}' fi } detect_ips() { hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | grep -v '^127\.' || true } require_root() { if [ "$(id -u)" -ne 0 ]; then echo "Run this installer with sudo:" >&2 echo " curl -fsSL https://install.onyxio.com.au | sudo bash" >&2 exit 1 fi } require_docker() { if ! command -v docker >/dev/null 2>&1; then echo "Docker is required on this server before installing Onyxio." >&2 echo "Install Docker Engine and the Docker Compose plugin, then run this installer again." >&2 exit 1 fi } prompt_server_ip() { if [ -n "${SERVER_IP:-}" ]; then echo "$SERVER_IP" return fi echo "Choose the IP address TVs and phones should use to reach this server." >&2 detected_ips="$(detect_ips)" if [ -n "$detected_ips" ]; then i=1 while IFS= read -r ip; do [ -z "$ip" ] && continue if [ "$i" -eq 1 ]; then default_ip="$ip" fi printf " [%s] %s\n" "$i" "$ip" >&2 i=$((i + 1)) done < "$INSTALL_DIR/docker-compose.yml" <<'EOF' services: postgres: image: ${POSTGRES_IMAGE:-postgres:15} restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB:-onyxio} ports: - "127.0.0.1:${POSTGRES_PORT:-5432}:5432" volumes: - ./data/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-onyxio}"] interval: 10s timeout: 5s retries: 12 onyxio: image: ${ONYXIO_SERVER_IMAGE} restart: unless-stopped network_mode: host depends_on: postgres: condition: service_healthy env_file: - .env environment: DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@127.0.0.1:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-onyxio} PORT: ${PORT:-4000} WEB_SOCKET_PORT: ${WEB_SOCKET_PORT:-8081} PHILIPS_WEBSERVICES_PORT: ${PHILIPS_WEBSERVICES_PORT:-8080} PHILIPS_WEBSERVICES_BOOTSTRAP_PORT: ${PHILIPS_WEBSERVICES_BOOTSTRAP_PORT:-80} volumes: - ./data/uploads:/app/backend/uploads EOF } write_env_file() { local server_ip="$1" if [ -f "$INSTALL_DIR/.env" ]; then echo "Existing ${INSTALL_DIR}/.env found; keeping existing configuration." return fi local postgres_password jwt_secret postgres_password="$(random_secret)" jwt_secret="$(random_secret)" cat > "$INSTALL_DIR/.env" <