#!/usr/bin/env bash # deploy-app.sh — déploie l'app Flask (static/app/) sur static.alpinux.org # # Usage : # ./deploy-app.sh # déploie et redémarre le service # ./deploy-app.sh -n # dry-run (aucune modification) set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" APP_DIR="$SCRIPT_DIR/../app" ENV_FILE="$SCRIPT_DIR/../.env" RED='\033[0;31m'; GREEN='\033[0;32m'; CYAN='\033[0;36m' BOLD='\033[1m'; RESET='\033[0m' if [ ! -f "$ENV_FILE" ]; then echo -e "${RED}Erreur : .env introuvable. Copier .env.example et remplir.${RESET}" exit 1 fi # shellcheck source=/dev/null source "$ENV_FILE" REMOTE_HOST="${STATIC_HOST:?Variable STATIC_HOST manquante dans .env}" REMOTE_DEST="/opt/static-cdn" SERVICE_FILE="$SCRIPT_DIR/../../infra/services/static-cdn.service" DRY_RUN=false for arg in "$@"; do case "$arg" in -n|--dry-run) DRY_RUN=true ;; -h|--help) sed -n '2,5p' "$0" | sed 's/^# //'; exit 0 ;; esac done echo -e "${BOLD}Déploiement de l'app Flask → $REMOTE_HOST:$REMOTE_DEST${RESET}" echo "" # ── 1. Rsync de l'app ──────────────────────────────────────────────── echo -e "${CYAN}[1/4] Synchronisation des fichiers…${RESET}" RSYNC_OPTS=(-rlcz --delete --human-readable --exclude='.env' --exclude='__pycache__/' --exclude='*.pyc' --exclude='venv/' --exclude='.env.example') if $DRY_RUN; then rsync --dry-run --itemize-changes "${RSYNC_OPTS[@]}" "$APP_DIR/" "$REMOTE_HOST:$REMOTE_DEST/" echo -e "${CYAN}Mode dry-run — aucune modification effectuée.${RESET}" exit 0 fi ssh "$REMOTE_HOST" "sudo mkdir -p $REMOTE_DEST && sudo chown abonnelc:abonnelc $REMOTE_DEST" rsync "${RSYNC_OPTS[@]}" "$APP_DIR/" "$REMOTE_HOST:$REMOTE_DEST/" echo -e " ${GREEN}✓ Fichiers copiés${RESET}" # ── 2. Environnement Python ────────────────────────────────────────── echo -e "${CYAN}[2/4] Mise à jour de l'environnement Python…${RESET}" ssh "$REMOTE_HOST" bash <<'ENDSSH' set -e cd /opt/static-cdn [ ! -d venv ] && python3 -m venv venv venv/bin/pip install --quiet --upgrade pip venv/bin/pip install --quiet -r requirements.txt ENDSSH echo -e " ${GREEN}✓ Dépendances installées${RESET}" # ── 3. Fichier .env distant ────────────────────────────────────────── echo -e "${CYAN}[3/4] Vérification du fichier .env distant…${RESET}" ENV_EXISTS=$(ssh "$REMOTE_HOST" "test -f $REMOTE_DEST/.env && echo yes || echo no") if [ "$ENV_EXISTS" = "no" ]; then echo -e " ${RED}ATTENTION : /opt/static-cdn/.env absent sur le serveur.${RESET}" echo " Créer le fichier avec les variables requises :" echo " ssh $REMOTE_HOST" echo " nano /opt/static-cdn/.env" echo " Variables minimales :" echo " SECRET_KEY=" echo " ALPID_CLIENT_ID=" echo " ALPID_CLIENT_SECRET=" echo " ALPID_DISCOVERY_URL=https://alpid.alpinux.org/realms/master/.well-known/openid-configuration" echo " ADMIN_EMAILS=cedric.alpinux@acemail.fr" echo " ASSETS_ROOT=/var/www/clients/client1/web17/web" echo " STATS_FILE=/opt/static-cdn/goaccess.html" echo " STATS_JSON=/opt/static-cdn/goaccess.json" echo " STATS_LOG_FILE=/var/log/ispconfig/httpd/static.alpinux.org/access.log" echo " STATS_GENERATE_CMD=goaccess \$STATS_LOG_FILE --config-file=/var/log/ispconfig/httpd/static.alpinux.org/goaccess.conf -o \$STATS_FILE -o \$STATS_JSON" echo "" else echo -e " ${GREEN}✓ .env présent${RESET}" fi # ── 4. Service systemd ─────────────────────────────────────────────── echo -e "${CYAN}[4/4] Déploiement du service systemd…${RESET}" scp "$SERVICE_FILE" "$REMOTE_HOST:/tmp/static-cdn.service" ssh "$REMOTE_HOST" bash <<'ENDSSH' set -e sudo mkdir -p /var/log/static-cdn sudo chown abonnelc:abonnelc /var/log/static-cdn sudo cp /tmp/static-cdn.service /etc/systemd/system/static-cdn.service sudo systemctl daemon-reload sudo systemctl enable static-cdn if systemctl is-active --quiet static-cdn; then sudo systemctl restart static-cdn echo "Service redémarré." else sudo systemctl start static-cdn 2>/dev/null || true echo "Service démarré." fi ENDSSH echo -e " ${GREEN}✓ Service systemd actif${RESET}" echo "" echo -e "${GREEN}✓ Déploiement terminé.${RESET}" echo "" echo -e "${BOLD}Étape manuelle restante — ISPConfig :${RESET}" echo " https://owni.alpinux.org:8080 → Sites → static.alpinux.org → Directives Apache" echo "" echo " Coller dans le champ 'Directives Apache SSL' :" echo "" cat << 'EOF' # CDN public → Apache sert directement depuis DocumentRoot ProxyPass /logo/ ! ProxyPass /wiki/ ! ProxyPass /error/ ! ProxyPass /favicon.ico ! ProxyPass /robots.txt ! # Tableau de bord → Flask (inclut /stats/ avec auth SSO) RequestHeader set X-Forwarded-Proto "https" ProxyPreserveHost On ProxyPass / http://127.0.0.1:5003/ ProxyPassReverse / http://127.0.0.1:5003/ EOF