#!/usr/bin/env bash set -Eeuo pipefail APP_NAME="corp-address-book" CONTAINER_NAME="corporate-address-book" INSTALL_DIR="/opt/corp-address-book" IMAGE_NAME="corp-address-book:latest" HOST_PORT="8180" CONTAINER_PORT="3000" log() { printf '\n[%s] %s\n' "$(date +'%H:%M:%S')" "$*" } die() { printf '\nERROR: %s\n' "$*" >&2 exit 1 } # 1. Require root if [ "${EUID:-$(id -u)}" -ne 0 ]; then die "Run this update script as root, for example: curl -fsSL ... | sudo bash" fi # 2. Go to installation directory log "Navigating to ${INSTALL_DIR}" cd "$INSTALL_DIR" || die "Directory ${INSTALL_DIR} does not exist. Run install.sh first." # 3. Configure git safe directory log "Configuring git safe directory" git config --global --add safe.directory "$INSTALL_DIR" || true # 4. Pull changes using the deploy key log "Pulling latest changes from Gitea" SSH_KEY="/home/fabritsky/.ssh/gitea_corp_address_book_ed25519" if [ ! -f "$SSH_KEY" ]; then # Fallback: search for any deploy/private key in fabritsky's .ssh directory SSH_KEY_FOUND=$(find /home/fabritsky/.ssh/ -type f \( -name "*gitea*" -o -name "*ed25519*" -o -name "*rsa*" \) ! -name "*.pub" | head -n 1) if [ -n "$SSH_KEY_FOUND" ]; then SSH_KEY="$SSH_KEY_FOUND" fi fi log "Using SSH key: ${SSH_KEY}" GIT_SSH_COMMAND="ssh -i ${SSH_KEY} -o StrictHostKeyChecking=no -o BatchMode=yes" git pull # 5. Build Docker Image (Re-compile frontend and backend inside container) log "Building updated Docker image ${IMAGE_NAME}" docker build -t "$IMAGE_NAME" "$INSTALL_DIR" # 6. Safely replace container log "Replacing container ${CONTAINER_NAME}" old_name="" if docker container inspect "$CONTAINER_NAME" >/dev/null 2>&1; then old_name="${CONTAINER_NAME}-old-$(date +%Y%m%d-%H%M%S)" docker stop "$CONTAINER_NAME" >/dev/null docker rename "$CONTAINER_NAME" "$old_name" log "Previous container renamed to ${old_name}" fi log "Starting new container on port ${HOST_PORT}" if ! docker run -d \ --name "$CONTAINER_NAME" \ --restart unless-stopped \ --env-file "${INSTALL_DIR}/.env" \ -p "${HOST_PORT}:${CONTAINER_PORT}" \ -v "${INSTALL_DIR}/data:/app/data" \ "$IMAGE_NAME" >/dev/null; then if [ -n "$old_name" ]; then log "New container failed to start; rolling back to ${old_name}" docker rename "$old_name" "$CONTAINER_NAME" || true docker start "$CONTAINER_NAME" || true fi die "Failed to start new container." fi # 7. Health Check / Status log "Running health check..." sleep 5 if curl -fsSI "http://127.0.0.1:${HOST_PORT}/" >/dev/null; then log "Update completed successfully!" log "Container Status:" docker ps --filter "name=${CONTAINER_NAME}" # Remove the backup old container since deployment succeeded if [ -n "$old_name" ]; then log "Cleaning up old backup container ${old_name}" docker rm "$old_name" >/dev/null || true fi else docker logs --tail=80 "$CONTAINER_NAME" || true if [ -n "$old_name" ]; then log "Health check failed; rolling back to ${old_name}" docker stop "$CONTAINER_NAME" >/dev/null || true docker rm "$CONTAINER_NAME" || true docker rename "$old_name" "$CONTAINER_NAME" || true docker start "$CONTAINER_NAME" || true fi die "Health check failed. Rolled back to the previous container version." fi