#!/bin/bash # Webhook deployment script # This script is triggered by the webhook receiver when a push event is received set -e # Configuration APP_DIR="/app" # Application directory REPO_URL="https://git.d-popov.com/popov/mwitnessing.git" # Git repository URL GIT_USERNAME="${GIT_USERNAME:-deploy}" # Git username GIT_PASSWORD="${GIT_PASSWORD:-}" # Git password DOCKER_COMPOSE_FILE="${DOCKER_COMPOSE_FILE:-_deploy/standard-docker-compose.yml}" # Docker Compose file LOG_FILE="${LOG_FILE:-/app/logs/webhook-deploy.log}" # Log file # Create log directory if it doesn't exist mkdir -p "$(dirname "$LOG_FILE")" # Function to log messages log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # Get the branch name from the first argument or use main as default BRANCH="${1:-main}" log "Starting deployment for branch: $BRANCH" # Create a temporary directory for the Git clone TEMP_DIR=$(mktemp -d) log "Using temporary directory: $TEMP_DIR" # Clean up function to remove the temporary directory on exit cleanup() { log "Cleaning up temporary directory" rm -rf "$TEMP_DIR" } trap cleanup EXIT # Clone the repository log "Cloning repository: $REPO_URL (branch: $BRANCH)" if [ -n "$GIT_PASSWORD" ]; then # Use authentication with username and password AUTH_URL="${REPO_URL/https:\/\//https:\/\/$GIT_USERNAME:$GIT_PASSWORD@}" git clone -b "$BRANCH" --depth 1 "$AUTH_URL" "$TEMP_DIR" else # Use authentication with SSH keys git clone -b "$BRANCH" --depth 1 "$REPO_URL" "$TEMP_DIR" fi # Navigate to the cloned repository cd "$TEMP_DIR" # Backup important directories log "Backing up important directories" mkdir -p "/tmp/webhook_backup/permits" "/tmp/webhook_backup/uploads" if [ -d "$APP_DIR/public/content/permits" ]; then cp -r "$APP_DIR/public/content/permits/." "/tmp/webhook_backup/permits/" log "Permits directory backed up" fi if [ -d "$APP_DIR/public/content/uploads" ]; then cp -r "$APP_DIR/public/content/uploads/." "/tmp/webhook_backup/uploads/" log "Uploads directory backed up" fi # Check if we should rebuild the Docker image REBUILD=0 if [ -f "$TEMP_DIR/package.json" ] && [ -f "$APP_DIR/package.json" ]; then if ! cmp -s "$TEMP_DIR/package.json" "$APP_DIR/package.json"; then log "package.json has changed, triggering full rebuild" REBUILD=1 elif [ -f "$TEMP_DIR/package-lock.json" ] && [ -f "$APP_DIR/package-lock.json" ]; then if ! cmp -s "$TEMP_DIR/package-lock.json" "$APP_DIR/package-lock.json"; then log "package-lock.json has changed, triggering full rebuild" REBUILD=1 fi fi fi # Check if the Dockerfile or docker-compose file has changed if [ -f "$TEMP_DIR/_deploy/standard.Dockerfile" ] && [ -f "$APP_DIR/_deploy/standard.Dockerfile" ]; then if ! cmp -s "$TEMP_DIR/_deploy/standard.Dockerfile" "$APP_DIR/_deploy/standard.Dockerfile"; then log "Dockerfile has changed, triggering full rebuild" REBUILD=1 fi fi if [ -f "$TEMP_DIR/$DOCKER_COMPOSE_FILE" ] && [ -f "$APP_DIR/$DOCKER_COMPOSE_FILE" ]; then if ! cmp -s "$TEMP_DIR/$DOCKER_COMPOSE_FILE" "$APP_DIR/$DOCKER_COMPOSE_FILE"; then log "Docker Compose file has changed, triggering full rebuild" REBUILD=1 fi fi # Deploy the application if [ "$REBUILD" -eq 1 ]; then log "Performing full rebuild and restart" # Copy new code to application directory rsync -av --exclude 'node_modules' --exclude '.git' --exclude 'public/content/permits' --exclude 'public/content/uploads' "$TEMP_DIR/" "$APP_DIR/" # Rebuild and restart using Docker Compose cd "$APP_DIR" docker-compose -f "$DOCKER_COMPOSE_FILE" up -d --build else log "Performing code update without rebuild" # Copy new code to application directory, preserving special directories rsync -av --exclude 'node_modules' --exclude '.git' --exclude 'public/content/permits' --exclude 'public/content/uploads' "$TEMP_DIR/" "$APP_DIR/" # Find container ID for the Next.js app CONTAINER_ID=$(docker ps -qf "name=nextjs-app") if [ -n "$CONTAINER_ID" ]; then log "Restarting Next.js container: $CONTAINER_ID" docker restart "$CONTAINER_ID" else log "Next.js container not found, starting with Docker Compose" cd "$APP_DIR" docker-compose -f "$DOCKER_COMPOSE_FILE" up -d fi fi # Restore backed up directories and merge with new content from Git log "Restoring and merging backed up directories" # Create permits directory if it doesn't exist mkdir -p "$APP_DIR/public/content/permits" # Merge Git permits (if any) with backed up permits if [ -d "$TEMP_DIR/public/content/permits" ] && [ "$(ls -A "$TEMP_DIR/public/content/permits")" ]; then log "Copying permits from Git repository" cp -r "$TEMP_DIR/public/content/permits/." "$APP_DIR/public/content/permits/" fi # Restore backed up permits (these will take precedence over Git permits) if [ -d "/tmp/webhook_backup/permits" ] && [ "$(ls -A "/tmp/webhook_backup/permits")" ]; then log "Restoring backed up permits" cp -r "/tmp/webhook_backup/permits/." "$APP_DIR/public/content/permits/" fi # Restore uploads (these should only come from the backup, not Git) if [ -d "/tmp/webhook_backup/uploads" ] && [ "$(ls -A "/tmp/webhook_backup/uploads")" ]; then log "Restoring backed up uploads" mkdir -p "$APP_DIR/public/content/uploads" cp -r "/tmp/webhook_backup/uploads/." "$APP_DIR/public/content/uploads/" fi # Clean up backup rm -rf "/tmp/webhook_backup" log "Deployment completed successfully"