zkt26/sk1/prepare-app.sh

114 lines
5.0 KiB
Bash

#!/bin/bash
# prepare-app.sh — Deploy ShortLink to Google Cloud (Ubuntu 22.04 VM)
# Conditions: Run on a fresh GCP Compute Engine VM with Ubuntu 22.04.
# Port 80 and 443 must be open in firewall.
# DNS A record for DOMAIN must already point to this VM's external IP.
# The .env file must exist (copy from .env.example and fill in values).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "======================================================"
echo " ShortLink — Cloud Deployment Script"
echo "======================================================"
echo ""
# ── 1. Load and validate environment ─────────────────────────────────────────
if [ ! -f ".env" ]; then
echo "ERROR: .env file not found!"
echo " Run: cp .env.example .env"
echo " Then edit .env with your values."
exit 1
fi
set -a
# shellcheck disable=SC1091
source .env
set +a
: "${DOMAIN:?Set DOMAIN in .env (e.g. shortlink.example.com)}"
: "${EMAIL:?Set EMAIL in .env (used for SSL certificate)}"
: "${DB_NAME:?Set DB_NAME in .env}"
: "${DB_USER:?Set DB_USER in .env}"
: "${DB_PASSWORD:?Set DB_PASSWORD in .env}"
: "${BASE_URL:?Set BASE_URL in .env (e.g. https://shortlink.example.com)}"
echo "[ENV] Domain: $DOMAIN"
echo "[ENV] Base URL: $BASE_URL"
echo ""
# ── 2. Install Docker ─────────────────────────────────────────────────────────
if ! command -v docker &>/dev/null; then
echo "[1/5] Installing Docker..."
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker "$USER"
# Re-exec with docker group applied so the rest of the script can use docker
exec sg docker "$0" "$@"
else
echo "[1/5] Docker already installed: $(docker --version)"
fi
# ── 3. Install Docker Compose plugin ─────────────────────────────────────────
if ! docker compose version &>/dev/null 2>&1; then
echo "[2/5] Installing Docker Compose plugin..."
sudo apt-get update -qq
sudo apt-get install -y docker-compose-plugin
else
echo "[2/5] Docker Compose installed: $(docker compose version)"
fi
# ── 4. Install Certbot ────────────────────────────────────────────────────────
if ! command -v certbot &>/dev/null; then
echo "[3/5] Installing Certbot..."
sudo apt-get update -qq
sudo apt-get install -y certbot
else
echo "[3/5] Certbot already installed: $(certbot --version)"
fi
# ── 5. Obtain SSL certificate ─────────────────────────────────────────────────
if [ ! -d "/etc/letsencrypt/live/${DOMAIN}" ]; then
echo "[4/5] Obtaining SSL certificate for ${DOMAIN}..."
echo " (Certbot will temporarily listen on port 80 — ensure it is open)"
sudo certbot certonly \
--standalone \
--non-interactive \
--agree-tos \
--email "${EMAIL}" \
-d "${DOMAIN}"
echo " Certificate obtained successfully."
else
echo "[4/5] SSL certificate already exists for ${DOMAIN}."
fi
# ── 6. Generate nginx.conf from template ──────────────────────────────────────
echo "[5/5] Generating nginx configuration..."
sed "s/DOMAIN_PLACEHOLDER/${DOMAIN}/g" nginx/nginx.conf.template > nginx/nginx.conf
# ── 7. Build and start containers ────────────────────────────────────────────
echo "[5/5] Building images and starting containers..."
docker compose up -d --build
# ── 8. Configure automatic SSL renewal ───────────────────────────────────────
APP_DIR="$SCRIPT_DIR"
RENEW_CMD="certbot renew --quiet --pre-hook 'docker stop shortlink_nginx' --post-hook 'docker start shortlink_nginx' >> /var/log/certbot-renew.log 2>&1"
(sudo crontab -l 2>/dev/null | grep -v certbot; echo "0 3 * * 0 $RENEW_CMD") | sudo crontab -
echo " SSL auto-renewal cron job configured (every Sunday 03:00)."
echo ""
echo "╔══════════════════════════════════════════════╗"
echo "║ ✅ Deployment Successful! ║"
echo "╚══════════════════════════════════════════════╝"
echo ""
echo " Application URL : https://${DOMAIN}"
echo " Health endpoint : https://${DOMAIN}/health"
echo ""
echo "Container status:"
docker compose ps
echo ""
echo "To view logs: docker compose logs -f"
echo "To stop: ./remove-app.sh"
echo "To backup: ./scripts/backup.sh"