#!/bin/bash # ========================================== # AegisOne Engineering — Full Deployment Script # ========================================== # Usage: bash deploy.sh [--skip-ssl] # Run on VPS as angel user set -e RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m' log() { echo -e "${CYAN}[$(date +%H:%M:%S)]${NC} $1"; } ok() { echo -e " ${GREEN}✅ $1${NC}"; } info() { echo -e " ${YELLOW}ℹ️ $1${NC}"; } fail() { echo -e " ${RED}❌ $1${NC}"; exit 1; } SKIP_SSL=false for arg in "$@"; do [ "$arg" = "--skip-ssl" ] && SKIP_SSL=true; done cd "$(dirname "$0")" echo -e "${CYAN}" echo "==========================================" echo " AegisOne Engineering — Deploy v2.0" echo "==========================================" echo -e "${NC}" # ========================================== # PART 1: Server Preparation # ========================================== log "PART 1: Server preparation" if ! command -v docker &>/dev/null; then log "Installing Docker..." curl -fsSL https://get.docker.com | sh sudo usermod -aG docker "$USER" ok "Docker installed. Re-login required for docker group" newgrp docker else ok "Docker already installed: $(docker --version)" fi # Create project structure log "Creating /opt/projects/ structure..." sudo mkdir -p /opt/projects/{nginx-proxy,gitea,aegisone-php,aegisone-py,portainer,project2,backups,certs,data} sudo chown -R "$USER":"$USER" /opt/projects ok "Structure created" # Create Docker networks log "Creating Docker networks..." docker network inspect proxy-net &>/dev/null || docker network create proxy-net && ok "proxy-net" docker network inspect aegisone-net &>/dev/null || docker network create aegisone-net && ok "aegisone-net" docker network inspect gitea-net &>/dev/null || docker network create gitea-net && ok "gitea-net" # ========================================== # PART 2: Deploy nginx-proxy # ========================================== log "PART 2: Deploy nginx-proxy" NGX="/opt/projects/nginx-proxy" cp nginx/nginx.conf "$NGX/" cp -r nginx/conf.d/* "$NGX/conf.d/" # Generate self-signed cert as placeholder mkdir -p "$NGX/certs/live/aegisone.ru" "$NGX/html/.well-known/acme-challenge" cat > "$NGX/html/index.html" <<< "AegisOne

AegisOne Engineering

" if [ ! -f "$NGX/certs/live/aegisone.ru/fullchain.pem" ]; then log "Generating self-signed SSL cert..." openssl req -x509 -nodes -days 30 -newkey rsa:2048 \ -keyout "$NGX/certs/live/aegisone.ru/privkey.pem" \ -out "$NGX/certs/live/aegisone.ru/fullchain.pem" \ -subj "/CN=aegisone.ru" 2>/dev/null || { docker run --rm -v "$NGX/certs:/certs" alpine:latest sh -c " apk add openssl >/dev/null 2>&1 mkdir -p /certs/live/aegisone.ru openssl req -x509 -nodes -days 30 -newkey rsa:2048 \ -keyout /certs/live/aegisone.ru/privkey.pem \ -out /certs/live/aegisone.ru/fullchain.pem \ -subj '/CN=aegisone.ru' " } ok "Self-signed cert created" fi cp nginx/docker-compose.yml "$NGX/" cd "$NGX" && docker compose up -d ok "nginx-proxy started" # ========================================== # PART 3: Deploy aegisone-py (FastAPI + PostgreSQL) # ========================================== log "PART 3: Deploy aegisone-py (FastAPI + PostgreSQL)" PY="/opt/projects/aegisone-py" # Copy all py_service files rsync -a --delete py_service/ "$PY/" 2>/dev/null || cp -r py_service/* "$PY/" # Override docker-compose.yml with updated network config cp py_service/docker-compose.yml "$PY/" cd "$PY" && docker compose up -d --build ok "aegisone-py started" # ========================================== # PART 3B: Deploy max_bot (MAX messenger bot) # ========================================== log "PART 3B: Deploy max_bot (MAX messenger bot on port 8002)" BOT="/opt/projects/aegisone-py/max_bot" mkdir -p "$BOT" rsync -a --delete max_bot/ "$BOT/" 2>/dev/null || cp -r max_bot/* "$BOT/" # Copy nginx config for max.aegisone.ru cp max_bot/nginx/max-aegisone.conf "$NGX/conf.d/max-aegisone.conf" docker compose -f "$NGX/docker-compose.yml" exec nginx nginx -s reload 2>/dev/null || true ok "max_bot nginx config deployed" cd "$BOT" && docker compose up -d --build ok "max_bot started on port 8002" # ========================================== # PART 4: Deploy aegisone-php (Public site) # ========================================== log "PART 4: Deploy aegisone-php (Public site)" PHP="/opt/projects/aegisone-php" # Copy PHP source files from repo root (excluding certain dirs) mkdir -p "$PHP/src" rsync -a --delete \ --exclude='.git' --exclude='node_modules' --exclude='*.zip' \ --exclude='py_service' --exclude='aegisone-php' --exclude='nginx' \ --exclude='gitea' --exclude='portainer' --exclude='opencode.json' \ --exclude='site_aegisone.zip' \ ./ "$PHP/src/" # Copy Docker infrastructure cp aegisone-php/Dockerfile "$PHP/" cp aegisone-php/nginx.conf "$PHP/" cp aegisone-php/docker-compose.yml "$PHP/" cd "$PHP" && docker compose up -d --build ok "aegisone-php started" # ========================================== # PART 5: Deploy Gitea # ========================================== log "PART 5: Deploy Gitea" GITEA="/opt/projects/gitea" cp gitea/docker-compose.yml "$GITEA/" cd "$GITEA" && docker compose up -d ok "Gitea started" # ========================================== # PART 6: Deploy Portainer (port 9000) # ========================================== log "PART 6: Deploy Portainer" P="/opt/projects/portainer" cp portainer/docker-compose.yml "$P/" cd "$P" && docker compose up -d ok "Portainer started on port 9000" # ========================================== # PART 7: Configure UFW # ========================================== log "PART 7: Configure UFW" if ! sudo ufw status | grep -q "Status: active"; then sudo ufw --force disable 2>/dev/null || true sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow 22/tcp comment 'SSH' sudo ufw allow 80/tcp comment 'HTTP' sudo ufw allow 443/tcp comment 'HTTPS' sudo ufw allow 9000/tcp comment 'Portainer' sudo ufw --force enable ok "UFW configured" else ok "UFW already active" fi # ========================================== # PART 8: Get SSL certificates # ========================================== if [ "$SKIP_SSL" = false ]; then log "PART 8: Obtaining Let's Encrypt SSL certificates" cd "$NGX" docker compose run --rm certbot certonly --webroot \ --webroot-path=/var/www/certbot \ -d aegisone.ru -d www.aegisone.ru \ -d service.aegisone.ru \ -d max.aegisone.ru \ -d git.aegisone.ru \ --email admin@aegisone.ru \ --agree-tos --non-interactive 2>/dev/null && { ok "SSL certificates obtained" docker compose exec nginx nginx -s reload ok "Nginx reloaded with real certs" } || info "Certbot failed — run manually after DNS propagation" else info "SSL step skipped (--skip-ssl)" fi # ========================================== # Done # ========================================== echo "" echo -e "${GREEN}==========================================" echo " Deploy complete!" echo "==========================================${NC}" echo "" echo " nginx-proxy: http://81.177.141.34 → aegisone.ru" echo " Portainer: http://81.177.141.34:9000" echo " FastAPI (direct): http://81.177.141.34:8000" echo " Gitea (direct): http://81.177.141.34:3000" echo "" echo " After DNS propagation, run certbot:" echo " cd /opt/projects/nginx-proxy" echo " docker compose run --rm certbot certonly --webroot \\" echo " --webroot-path=/var/www/certbot \\" echo " -d aegisone.ru -d www.aegisone.ru \\" echo " -d service.aegisone.ru -d max.aegisone.ru \\" echo " -d git.aegisone.ru \\" echo " --email admin@aegisone.ru --agree-tos --non-interactive" echo " docker compose exec nginx nginx -s reload" echo ""