#!/usr/bin/env bash set -euo pipefail ARCHIVE_PATH=${1:-/tmp/telegram-management-system.tar.gz} APP_DIR=${2:-/opt/telegram-management-system} COMPOSE_FILE=${3:-docker-compose.yml} if [[ ! -f "$ARCHIVE_PATH" ]]; then echo "Archive not found: $ARCHIVE_PATH" >&2 exit 1 fi mkdir -p "$APP_DIR" echo "Extracting archive $ARCHIVE_PATH to $APP_DIR ..." tar -xzf "$ARCHIVE_PATH" -C "$APP_DIR" rm -f "$ARCHIVE_PATH" COMPOSE_FILE_PATH="$APP_DIR/$COMPOSE_FILE" if [[ ! -f "$COMPOSE_FILE_PATH" ]]; then echo "Compose file not found at $COMPOSE_FILE_PATH" >&2 exit 1 fi cd "$APP_DIR" if docker compose version >/dev/null 2>&1; then COMPOSE_CMD="docker compose" elif command -v docker-compose >/dev/null 2>&1; then COMPOSE_CMD="docker-compose" else echo "Neither docker compose nor docker-compose is available on the server." >&2 exit 1 fi echo "Stopping existing containers..." $COMPOSE_CMD -f "$COMPOSE_FILE_PATH" down --remove-orphans || true # Ensure any lingering containers are removed for container in tg-backend tg-frontend tg-mysql tg-mongodb tg-redis tg-rabbitmq; do if docker ps -a --format '{{.Names}}' | grep -w "$container" >/dev/null 2>&1; then echo "Removing leftover container: $container" docker rm -f "$container" || true # Wait until container is fully removed while docker ps -a --format '{{.Names}}' | grep -w "$container" >/dev/null 2>&1; do echo "Waiting for $container to terminate..." sleep 2 done fi done echo "Waiting for Docker resources to settle..." sleep 5 # Double-check critical stateful services are removed for container in tg-mysql tg-mongodb tg-rabbitmq; do if docker ps -a --format '{{.Names}}' | grep -w "$container" >/dev/null 2>&1; then docker rm -f "$container" >/dev/null 2>&1 || true fi done # Free up host ports if needed if command -v systemctl >/dev/null 2>&1; then echo "Attempting to stop host nginx service to free port 80..." systemctl stop nginx >/dev/null 2>&1 || true fi echo "Starting updated stack..." $COMPOSE_CMD -f "$COMPOSE_FILE_PATH" up -d --build --force-recreate echo "Deployment complete."