#!/usr/bin/env bash # # install.sh — ReceiptNext installer # # Copies the binary and assets to /opt/rx/, prompts for configuration, # and sets up a systemd service. # # Usage: sudo ./install.sh # set -euo pipefail INSTALL_DIR="/opt/rx" BIN_PATH="/opt/rx/receiptnext" SERVICE_NAME="receiptnext" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' info() { echo -e "${GREEN}[✓]${NC} $1"; } warn() { echo -e "${YELLOW}[!]${NC} $1"; } prompt() { echo -en "${CYAN}→${NC} $1"; } if [ "$EUID" -ne 0 ]; then echo -e "${RED}Please run as root: sudo ./install.sh${NC}" exit 1 fi echo "" echo " ╔═══════════════════════════════════════╗" echo " ║ ReceiptNext Installer ║" echo " ╚═══════════════════════════════════════╝" echo "" # ── Detect binary ──────────────────────────────────────────────── SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" BINARY="" for f in "$SCRIPT_DIR/receiptnext" "$SCRIPT_DIR/dist/receiptnext-linux-amd64" "$SCRIPT_DIR/dist/receiptnext-linux-arm64"; do if [ -f "$f" ] && [ -x "$f" ]; then BINARY="$f" break fi done if [ -z "$BINARY" ]; then echo -e "${RED}No binary found. Build it first: go build -o receiptnext .${NC}" exit 1 fi BINARY_NAME=$(basename "$BINARY") info "Using binary: $BINARY" # ── Create install directory ───────────────────────────────────── mkdir -p "$INSTALL_DIR"/{templates,static/css,static/icons,storage} info "Created $INSTALL_DIR" # ── Copy binary and assets ─────────────────────────────────────── cp "$BINARY" "$BIN_PATH" chmod +x "$BIN_PATH" cp -r "$SCRIPT_DIR/templates/." "$INSTALL_DIR/templates/" cp -r "$SCRIPT_DIR/static/." "$INSTALL_DIR/static/" info "Copied binary + assets to $INSTALL_DIR" # ── Prompt for configuration ───────────────────────────────────── echo "" echo " ── Configuration ──" echo " (Press Enter to skip any field)" echo "" read -p " SMTP host [$SMTP_HOST]: " SMTP_HOST_IN SMTP_HOST="${SMTP_HOST_IN:-$SMTP_HOST}" read -p " SMTP port [${SMTP_PORT:-587}]: " SMTP_PORT_IN SMTP_PORT="${SMTP_PORT_IN:-${SMTP_PORT:-587}}" read -p " SMTP user [$SMTP_USER]: " SMTP_USER_IN SMTP_USER="${SMTP_USER_IN:-$SMTP_USER}" read -p " SMTP password [$SMTP_PASS]: " SMTP_PASS_IN SMTP_PASS="${SMTP_PASS_IN:-$SMTP_PASS}" read -p " Gemini API key [$GEMINI_API_KEY]: " GEMINI_IN GEMINI_API_KEY="${GEMINI_IN:-$GEMINI_API_KEY}" read -p " Public server URL [${BASE_URL:-http://localhost:8080}]: " BASE_URL_IN BASE_URL="${BASE_URL_IN:-${BASE_URL:-http://localhost:8080}}" read -p " Port for web server [${PORT:-8080}]: " PORT_IN PORT="${PORT_IN:-${PORT:-8080}}" # ── Write .env ─────────────────────────────────────────────────── cat > "$INSTALL_DIR/.env" << ENVEOF # ReceiptNext Configuration # Created by install.sh on $(date) SMTP_HOST=${SMTP_HOST} SMTP_PORT=${SMTP_PORT} SMTP_USER=${SMTP_USER} SMTP_PASS=${SMTP_PASS} GEMINI_API_KEY=${GEMINI_API_KEY} BASE_URL=${BASE_URL} PORT=${PORT} ENVEOF chmod 600 "$INSTALL_DIR/.env" info "Created $INSTALL_DIR/.env" # ── Create systemd service ─────────────────────────────────────── cat > "/etc/systemd/system/${SERVICE_NAME}.service" << SERVEOF [Unit] Description=ReceiptNext — AI-Powered Expense Tracker Documentation=https://git.lohmar.co.uk/cclohmar/ReceiptNext After=network.target [Service] Type=simple User=root WorkingDirectory=${INSTALL_DIR} ExecStart=${BIN_PATH} Restart=always RestartSec=5 EnvironmentFile=${INSTALL_DIR}/.env StandardOutput=append:/var/log/receiptnext.log StandardError=append:/var/log/receiptnext.log [Install] WantedBy=multi-user.target SERVEOF systemctl daemon-reload systemctl enable "${SERVICE_NAME}" info "Systemd service created: ${SERVICE_NAME}" # ── Start service ──────────────────────────────────────────────── systemctl start "${SERVICE_NAME}" 2>/dev/null || true sleep 2 echo "" echo " ╔═══════════════════════════════════════╗" echo " ║ Installation Complete! ║" echo " ╚═══════════════════════════════════════╝" echo "" echo " Install dir: $INSTALL_DIR" echo " Config: $INSTALL_DIR/.env" echo " Binary: $BIN_PATH" echo " Service: systemctl status $SERVICE_NAME" echo " Logs: journalctl -u $SERVICE_NAME -f" echo "" if systemctl is-active --quiet "${SERVICE_NAME}"; then info "ReceiptNext is running on port ${PORT}" echo " Open http://localhost:${PORT} (or your server IP)" else warn "Service did not start. Check: systemctl status ${SERVICE_NAME}" echo " Logs: journalctl -u ${SERVICE_NAME} -n 50 --no-pager" fi