175 lines
5.4 KiB
Bash
Executable File
175 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# =============================================================================
|
|
# prepare-app.sh — Deploy Task Manager to Azure VM
|
|
#
|
|
# This script:
|
|
# 1. Creates an Azure Resource Group
|
|
# 2. Creates a VM with Docker pre-installed (cloud-init)
|
|
# 3. Opens ports 80, 443 for HTTPS
|
|
# 4. Uploads all application files via SCP
|
|
# 5. Starts all containers with docker compose
|
|
#
|
|
# Prerequisites:
|
|
# - Azure CLI installed and logged in (az login)
|
|
# - Azure for Students subscription active
|
|
# - .env file configured (copy from env.example)
|
|
#
|
|
# Usage:
|
|
# ./prepare-app.sh
|
|
# =============================================================================
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
# ---- Load configuration -----------------------------------------------
|
|
if [ ! -f "$SCRIPT_DIR/.env" ]; then
|
|
echo "ERROR: .env file not found!"
|
|
echo " cp env.example .env && nano .env"
|
|
exit 1
|
|
fi
|
|
|
|
source "$SCRIPT_DIR/.env"
|
|
|
|
RG="${AZURE_RESOURCE_GROUP:-taskmanager-rg}"
|
|
LOC="${AZURE_LOCATION:-westeurope}"
|
|
VM="${AZURE_VM_NAME:-taskmanager-vm}"
|
|
SIZE="${AZURE_VM_SIZE:-Standard_B1s}"
|
|
DNS="${AZURE_DNS_LABEL:-taskmanager-gs699he}"
|
|
ADMIN="azureuser"
|
|
|
|
FQDN="${DNS}.${LOC}.cloudapp.azure.com"
|
|
SSH_KEY="$HOME/.ssh/sk1_taskmanager"
|
|
|
|
echo "============================================="
|
|
echo " Task Manager — Azure Cloud Deployment"
|
|
echo "============================================="
|
|
echo ""
|
|
echo " Resource Group: $RG"
|
|
echo " Location: $LOC"
|
|
echo " VM Name: $VM"
|
|
echo " VM Size: $SIZE"
|
|
echo " DNS: $FQDN"
|
|
echo ""
|
|
|
|
# ---- Step 1: Check Azure CLI ------------------------------------------
|
|
echo "[1/7] Checking Azure CLI..."
|
|
if ! az account show &>/dev/null; then
|
|
echo "ERROR: Not logged in. Run: az login"
|
|
exit 1
|
|
fi
|
|
SUB_NAME=$(az account show --query "name" -o tsv)
|
|
echo " ✓ Subscription: $SUB_NAME"
|
|
|
|
# ---- Step 2: Generate SSH key if needed --------------------------------
|
|
echo "[2/7] Checking SSH key..."
|
|
if [ ! -f "$SSH_KEY" ]; then
|
|
ssh-keygen -t ed25519 -f "$SSH_KEY" -N "" -q
|
|
echo " ✓ Created new SSH key: $SSH_KEY"
|
|
else
|
|
echo " ✓ Using existing key: $SSH_KEY"
|
|
fi
|
|
|
|
# ---- Step 3: Create Resource Group -------------------------------------
|
|
echo "[3/7] Creating Resource Group '$RG'..."
|
|
az group create --name "$RG" --location "$LOC" -o none
|
|
echo " ✓ Resource Group ready"
|
|
|
|
# ---- Step 4: Create VM ------------------------------------------------
|
|
echo "[4/7] Creating VM '$VM' (this takes ~2 minutes)..."
|
|
az vm create \
|
|
--resource-group "$RG" \
|
|
--name "$VM" \
|
|
--image Ubuntu2404 \
|
|
--size "$SIZE" \
|
|
--admin-username "$ADMIN" \
|
|
--ssh-key-values "$SSH_KEY.pub" \
|
|
--public-ip-address-dns-name "$DNS" \
|
|
--custom-data "$SCRIPT_DIR/cloud-init.yaml" \
|
|
--output none
|
|
|
|
echo " ✓ VM created: $FQDN"
|
|
|
|
# ---- Step 5: Open firewall ports --------------------------------------
|
|
echo "[5/7] Opening ports 80 and 443..."
|
|
az vm open-port --resource-group "$RG" --name "$VM" --port 80 --priority 1010 -o none
|
|
az vm open-port --resource-group "$RG" --name "$VM" --port 443 --priority 1020 -o none
|
|
echo " ✓ Ports 80, 443 open"
|
|
|
|
# ---- Step 6: Wait for Docker and upload files --------------------------
|
|
echo "[6/7] Waiting for Docker installation (cloud-init ~60s)..."
|
|
SSH_CMD="ssh -o StrictHostKeyChecking=no -i $SSH_KEY $ADMIN@$FQDN"
|
|
|
|
# Wait for cloud-init to finish
|
|
for i in $(seq 1 30); do
|
|
if $SSH_CMD "command -v docker" &>/dev/null; then
|
|
echo " ✓ Docker installed"
|
|
break
|
|
fi
|
|
echo " ... waiting ($i/30)"
|
|
sleep 10
|
|
done
|
|
|
|
# Verify Docker
|
|
if ! $SSH_CMD "docker --version" &>/dev/null; then
|
|
echo "ERROR: Docker not available after 5 minutes."
|
|
echo "SSH in and check: $SSH_CMD"
|
|
exit 1
|
|
fi
|
|
|
|
# Upload application files
|
|
echo " Uploading application files..."
|
|
cd "$SCRIPT_DIR"
|
|
tar czf /tmp/taskmanager-app.tar.gz \
|
|
--exclude='.git' \
|
|
--exclude='docs' \
|
|
--exclude='backups' \
|
|
--exclude='*.pdf' \
|
|
--exclude='*.tex' \
|
|
--exclude='*.aux' \
|
|
--exclude='*.log' \
|
|
--exclude='*.png' \
|
|
--exclude='node_modules' \
|
|
api/ frontend/ db/ caddy/ docker-compose.yaml .env
|
|
|
|
scp -o StrictHostKeyChecking=no -i "$SSH_KEY" \
|
|
/tmp/taskmanager-app.tar.gz "$ADMIN@$FQDN:/tmp/"
|
|
rm -f /tmp/taskmanager-app.tar.gz
|
|
|
|
$SSH_CMD bash -s <<'EXTRACT'
|
|
sudo mkdir -p /opt/taskmanager
|
|
sudo tar xzf /tmp/taskmanager-app.tar.gz -C /opt/taskmanager
|
|
sudo chown -R $USER:$USER /opt/taskmanager
|
|
rm -f /tmp/taskmanager-app.tar.gz
|
|
EXTRACT
|
|
echo " ✓ Files uploaded"
|
|
|
|
# ---- Step 7: Start containers -----------------------------------------
|
|
echo "[7/7] Starting application containers..."
|
|
$SSH_CMD bash -s "$FQDN" <<'START'
|
|
cd /opt/taskmanager
|
|
echo "DOMAIN_NAME=$1" | sudo tee -a .env > /dev/null
|
|
sudo docker compose down 2>/dev/null || true
|
|
sudo docker compose up -d --build
|
|
echo ""
|
|
echo "Waiting for containers to start (30s)..."
|
|
sleep 30
|
|
echo ""
|
|
sudo docker compose ps
|
|
START
|
|
echo " ✓ Application started"
|
|
|
|
# ---- Summary ----------------------------------------------------------
|
|
echo ""
|
|
echo "============================================="
|
|
echo " ✓ Deployment Complete!"
|
|
echo ""
|
|
echo " 🌐 URL: https://$FQDN"
|
|
echo " 📍 SSH: ssh -i $SSH_KEY $ADMIN@$FQDN"
|
|
echo ""
|
|
echo " HTTPS certificate may take 1-2 min to provision."
|
|
echo ""
|
|
echo " Logs: ./view-logs.sh"
|
|
echo " Backup: ./backup-db.sh"
|
|
echo " Remove: ./remove-app.sh"
|
|
echo "============================================="
|