#!/bin/bash # ============================================================================= # deploy.sh — idempotent deploy for loreal-spec-tool # Usage: bash /opt/loreal-spec-tool/deploy.sh # ============================================================================= set -euo pipefail APP_NAME="loreal-spec-tool" REPO_DIR="/opt/${APP_NAME}" WEB_DIR="/var/www/html/${APP_NAME}" COMPOSE_FILE="${REPO_DIR}/docker-compose.yml" STATIC_FILES=(index.html script.js specs.json) GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; BOLD='\033[1m'; NC='\033[0m' log() { echo -e "${GREEN}[deploy]${NC} $1"; } warn() { echo -e "${YELLOW}[warn]${NC} $1"; } error() { echo -e "${RED}[error]${NC} $1"; exit 1; } step() { echo -e "\n${BOLD}▶ $1${NC}"; } compose() { docker compose -f "$COMPOSE_FILE" "$@"; } step "Checking prerequisites" command -v git >/dev/null 2>&1 || error "git is not installed" command -v docker >/dev/null 2>&1 || error "docker is not installed" docker compose version >/dev/null 2>&1 || error "docker compose v2 not found" step "Pulling latest code" cd "$REPO_DIR" git pull origin main log "Code: $(git log -1 --format='%h %s')" step "Building Docker image" compose build --pull log "Build complete" step "Starting application" compose up -d app log "Container started" step "Deploying static files to ${WEB_DIR}" rm -rf "${WEB_DIR}" mkdir -p "${WEB_DIR}" for f in "${STATIC_FILES[@]}"; do if [ -f "${REPO_DIR}/${f}" ]; then cp "${REPO_DIR}/${f}" "${WEB_DIR}/${f}" log " copied ${f}" else warn " ${f} not found — skipped" fi done step "Health check" sleep 2 HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3101/api/health || echo "000") [ "$HTTP_STATUS" = "200" ] && log "API OK (HTTP 200)" || error "Health check failed (HTTP ${HTTP_STATUS})" FIRST_RUN_FLAG="${REPO_DIR}/.deployed" if [ ! -f "$FIRST_RUN_FLAG" ]; then touch "$FIRST_RUN_FLAG" echo "" echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BOLD} First deploy. Add this to your Apache VirtualHost:${NC}" echo "" echo " Alias /loreal-spec-tool /var/www/html/loreal-spec-tool" echo " " echo " Options -Indexes" echo " AllowOverride None" echo " Require all granted" echo " " echo " ProxyPass /loreal-spec-tool/api http://localhost:3101/api" echo " ProxyPassReverse /loreal-spec-tool/api http://localhost:3101/api" echo "" echo " Then: sudo a2enmod proxy proxy_http && sudo systemctl reload apache2" echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" fi echo "" echo -e "${GREEN}${BOLD}Deploy complete${NC} — $(date '+%Y-%m-%d %H:%M:%S')" echo -e " App: http://localhost:3101 | API: http://localhost:3101/api/health" echo ""