#!/bin/bash # deploy.sh — Deploy main branch to production (217.154.84.225) # # Usage: # ./deploy.sh # Deploy current main to production # ./deploy.sh --dry-run # Show what would happen without deploying # # Prerequisites: # - SSH access to the production server (key-based auth) # - Production .env file at /opt/stiftung/.env on the server # - Git remote 'origin' configured on the server pointing to Gitea set -euo pipefail SERVER="${DEPLOY_SERVER:-deployment@217.154.84.225}" PROD_DIR="${DEPLOY_DIR:-/opt/stiftung}" COMPOSE_FILE="compose.yml" DRY_RUN=false if [[ "${1:-}" == "--dry-run" ]]; then DRY_RUN=true echo "=== DRY RUN — no changes will be made ===" fi echo "=== Stiftung Production Deployment ===" echo "Server: $SERVER" echo "Path: $PROD_DIR" echo "Compose: $COMPOSE_FILE" echo "" # --- Pre-deploy checks --- CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown") echo "Aktueller Branch: $CURRENT_BRANCH" # Check if main branch exists if ! git rev-parse --verify main &>/dev/null; then echo "" echo "FEHLER: Branch 'main' existiert nicht lokal." echo "Bist du im richtigen Repository?" exit 1 fi LOCAL_MAIN=$(git rev-parse --short main 2>/dev/null) LOCAL_MAIN_FULL=$(git rev-parse main 2>/dev/null) echo "Local main: $LOCAL_MAIN ($(git log -1 --format='%s' main 2>/dev/null))" # Check if main is pushed to Gitea git fetch origin --quiet 2>/dev/null || true REMOTE_MAIN=$(git rev-parse --short origin/main 2>/dev/null || echo "unknown") echo "Remote main: $REMOTE_MAIN (origin = Gitea)" if [[ "$REMOTE_MAIN" != "unknown" && "$LOCAL_MAIN" != "$REMOTE_MAIN" ]]; then UNPUSHED=$(git log --oneline origin/main..main 2>/dev/null | wc -l | tr -d ' ') echo "" echo "WARNUNG: Local main ist $UNPUSHED Commit(s) vor origin/main!" echo "Du musst erst 'git push origin main' ausführen, sonst deployed der Server den alten Stand." if [[ "$DRY_RUN" != true ]]; then echo "" read -p "Trotzdem fortfahren? [y/N] " -n 1 -r echo "" [[ $REPLY =~ ^[Yy]$ ]] || exit 0 fi elif [[ "$REMOTE_MAIN" == "unknown" ]]; then echo "" echo "WARNUNG: Konnte Gitea-Remote nicht erreichen. Status unbekannt." fi # Show what the server will get echo "" echo "Der Server wird diesen Stand deployen:" echo " Commit: $LOCAL_MAIN" echo " $(git log -1 --format='%ai — %s' main 2>/dev/null)" RECENT_COMMITS=$(git log --oneline -5 main 2>/dev/null) if [[ -n "$RECENT_COMMITS" ]]; then echo "" echo "Letzte 5 Commits auf main:" echo "$RECENT_COMMITS" | sed 's/^/ /' fi if [[ "$DRY_RUN" == true ]]; then echo "" echo "Would SSH to $SERVER and:" echo " 1. git fetch origin main && git reset --hard origin/main" echo " 2. docker compose down" echo " 3. docker compose up -d --build" echo " 4. Run migrations and collectstatic" echo "" echo "=== Dry run complete ===" exit 0 fi echo "" read -p "Deploy main ($LOCAL_MAIN) auf Produktion? [y/N] " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Abgebrochen." exit 0 fi echo "" echo "=== Deploying to $SERVER:$PROD_DIR ===" ssh "$SERVER" bash -s "$PROD_DIR" "$COMPOSE_FILE" << 'DEPLOY_SCRIPT' set -euo pipefail PROD_DIR="$1" COMPOSE_FILE="$2" cd "$PROD_DIR" echo "--- Fetching latest main ---" git fetch origin main git checkout main git reset --hard origin/main echo "" echo "--- Pulling standard images ---" docker compose -f "$COMPOSE_FILE" pull db redis grampsweb || echo "Some pulls failed, using cached" echo "" echo "--- Stopping containers ---" docker compose -f "$COMPOSE_FILE" down echo "" echo "--- Building and starting ---" docker compose -f "$COMPOSE_FILE" up -d --build echo "" echo "--- Waiting for services to start ---" sleep 20 echo "" echo "--- Running migrations ---" docker compose -f "$COMPOSE_FILE" exec -T web python manage.py migrate echo "" echo "--- Collecting static files ---" docker compose -f "$COMPOSE_FILE" exec -T web python manage.py collectstatic --noinput echo "" echo "--- Service status ---" docker compose -f "$COMPOSE_FILE" ps echo "" echo "=== Deployment complete ===" DEPLOY_SCRIPT echo "" echo "=== Done! Production updated to main ($LOCAL_MAIN) ===" echo "Site: https://vhtv-stiftung.de"