#!/bin/bash
# ===========================================
# Script principal de déploiement
# Usage: ./deploy.sh <project> <env> [services]
#
# Exemples:
# ./deploy.sh hellocar prod # Déploie tous les services
# ./deploy.sh hellocar prod api # Déploie seulement l'API
# ./deploy.sh hellocar prod api,admin # Déploie API et Admin
# ===========================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/config.sh"
source "$SCRIPT_DIR/../lib/colors.sh"
source "$SCRIPT_DIR/../lib/utils.sh"
# Arguments
PROJECT="$1"
ENV="$2"
SERVICES_FILTER="$3"
# Validation
if [ -z "$PROJECT" ] || [ -z "$ENV" ]; then
echo "Usage: $0 <project> <env> [services]"
echo ""
echo "Arguments:"
echo " project Nom du projet (hellocar, r7, ...)"
echo " env Environnement (prod, dev, recette)"
echo " services Services à déployer (optionnel, séparés par virgule)"
echo ""
echo "Exemples:"
echo " $0 hellocar prod"
echo " $0 hellocar prod api"
echo " $0 hellocar prod api,admin"
echo ""
echo "Projets disponibles:"
for proj in "${!PROJECTS[@]}"; do
echo " - $proj (${PROJECTS[$proj]})"
done
exit 1
fi
# Vérifier que le projet existe
if [ -z "${PROJECTS[$PROJECT]}" ]; then
log_error "Projet inconnu: $PROJECT"
echo "Projets disponibles: ${!PROJECTS[*]}"
exit 1
fi
# Pour l'instant, on supporte seulement PROD
if [ "$ENV" != "prod" ]; then
log_error "Seul l'environnement 'prod' est supporté pour l'instant"
exit 1
fi
print_header "Déploiement $PROJECT - $ENV"
# Parser les services du projet
ALL_SERVICES="${PROJECTS[$PROJECT]}"
log_info "Services disponibles: $ALL_SERVICES"
# Filtrer si demandé
if [ -n "$SERVICES_FILTER" ]; then
log_info "Services sélectionnés: $SERVICES_FILTER"
fi
echo ""
if ! confirm "Continuer le déploiement ?"; then
log_info "Annulé"
exit 0
fi
# Clone ou update du repo
REPO_PATH="$PROJECTS_PATH/$PROJECT"
BRANCH="main" # PROD = main
log_step "Récupération du code source..."
if [ -d "$REPO_PATH/.git" ]; then
log_info "Mise à jour du repo existant..."
cd "$REPO_PATH"
git fetch origin
git checkout "$BRANCH"
git pull origin "$BRANCH"
else
log_info "Clone du repo..."
rm -rf "$REPO_PATH"
git clone "https://$GITHUB_TOKEN@github.com/$GITHUB_USER/$PROJECT.git" "$REPO_PATH"
cd "$REPO_PATH"
git checkout "$BRANCH"
fi
# Parser et déployer chaque service
IFS=',' read -ra SERVICE_ARRAY <<< "$ALL_SERVICES"
for service_def in "${SERVICE_ARRAY[@]}"; do
SERVICE_NAME=$(get_service_name "$service_def")
SERVICE_PORT=$(get_service_port "$service_def")
# Vérifier si ce service est dans le filtre
if [ -n "$SERVICES_FILTER" ]; then
if ! echo "$SERVICES_FILTER" | grep -q "$SERVICE_NAME"; then
log_info "Skip $SERVICE_NAME (non sélectionné)"
continue
fi
fi
echo ""
print_separator
log_step "Déploiement: $SERVICE_NAME (port $SERVICE_PORT)"
CONTAINER_NAME="${PROJECT}-${SERVICE_NAME}-${ENV}"
IMAGE_NAME="${PROJECT}-${SERVICE_NAME}:${ENV}"
DOCKERFILE="Dockerfile.${SERVICE_NAME}"
# Vérifier que le Dockerfile existe
if [ ! -f "$REPO_PATH/$DOCKERFILE" ]; then
log_warn "Dockerfile non trouvé: $DOCKERFILE"
log_warn "Recherche d'un Dockerfile alternatif..."
# Chercher dans apps/ si c'est un monorepo
if [ -f "$REPO_PATH/apps/$SERVICE_NAME/Dockerfile" ]; then
DOCKERFILE="apps/$SERVICE_NAME/Dockerfile"
else
log_error "Aucun Dockerfile trouvé pour $SERVICE_NAME"
continue
fi
fi
# Build
log_info "Build de l'image $IMAGE_NAME..."
docker build -f "$DOCKERFILE" -t "$IMAGE_NAME" "$REPO_PATH"
# Stop et remove l'ancien container
if docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
log_info "Arrêt de l'ancien container..."
docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
docker rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
fi
# Charger les secrets
load_secrets "$ENV"
# Run le nouveau container
log_info "Démarrage du container $CONTAINER_NAME..."
docker run -d \
--name "$CONTAINER_NAME" \
--restart unless-stopped \
-p "${SERVICE_PORT}:${SERVICE_PORT}" \
-e "NODE_ENV=production" \
-e "PORT=${SERVICE_PORT}" \
-e "TZ=${TZ:-Europe/Paris}" \
"$IMAGE_NAME"
# Vérifier que le container tourne
sleep 3
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
log_success "$CONTAINER_NAME démarré"
else
log_error "$CONTAINER_NAME n'a pas démarré!"
docker logs "$CONTAINER_NAME" --tail 50
continue
fi
# Générer et déployer la config Nginx
log_info "Configuration Nginx..."
NGINX_CONFIG="/tmp/${PROJECT}-${SERVICE_NAME}-${ENV}.$DOMAIN_BASE.conf"
"$SCRIPT_DIR/../nginx/generate.sh" "$PROJECT" "$SERVICE_NAME" "$ENV" "$SERVICE_PORT" "$NGINX_CONFIG"
"$SCRIPT_DIR/../nginx/deploy.sh" "$NGINX_CONFIG"
log_success "Service $SERVICE_NAME déployé!"
done
echo ""
print_header "Déploiement terminé"
# Test des URLs
log_step "Test des URLs..."
for service_def in "${SERVICE_ARRAY[@]}"; do
SERVICE_NAME=$(get_service_name "$service_def")
if [ -n "$SERVICES_FILTER" ]; then
if ! echo "$SERVICES_FILTER" | grep -q "$SERVICE_NAME"; then
continue
fi
fi
DOMAIN="${PROJECT}-${SERVICE_NAME}-${ENV}.$DOMAIN_BASE"
print_url_status "https://$DOMAIN"
done
echo ""
log_success "Déploiement de $PROJECT terminé avec succès!"