|
|
#!/bin/bash |
|
|
|
|
|
|
|
|
|
|
|
set -e |
|
|
|
|
|
|
|
|
RED='\033[0;31m' |
|
|
GREEN='\033[0;32m' |
|
|
YELLOW='\033[1;33m' |
|
|
BLUE='\033[0;34m' |
|
|
PURPLE='\033[0;35m' |
|
|
NC='\033[0m' |
|
|
|
|
|
|
|
|
PROJECT_NAME="firewatch_project" |
|
|
DEPLOY_USER="firewatch" |
|
|
DEPLOY_PATH="/opt/firewatch" |
|
|
SERVICE_NAME="firewatch" |
|
|
NGINX_SITE="firewatch" |
|
|
|
|
|
log() { |
|
|
echo -e "${GREEN}[$(date +'%H:%M:%S')] $1${NC}" |
|
|
} |
|
|
|
|
|
error() { |
|
|
echo -e "${RED}[$(date +'%H:%M:%S')] ERROR: $1${NC}" |
|
|
exit 1 |
|
|
} |
|
|
|
|
|
warning() { |
|
|
echo -e "${YELLOW}[$(date +'%H:%M:%S')] WARNING: $1${NC}" |
|
|
} |
|
|
|
|
|
info() { |
|
|
echo -e "${BLUE}[$(date +'%H:%M:%S')] INFO: $1${NC}" |
|
|
} |
|
|
|
|
|
|
|
|
echo -e "${PURPLE}" |
|
|
echo "🚀 ========================================= 🚀" |
|
|
echo " FireWatch AI - Déploiement Production" |
|
|
echo " Créé par Marino ATOHOUN" |
|
|
echo "🚀 ========================================= 🚀" |
|
|
echo -e "${NC}" |
|
|
|
|
|
|
|
|
if [[ $EUID -ne 0 ]]; then |
|
|
error "Ce script doit être exécuté en tant que root (sudo)" |
|
|
fi |
|
|
|
|
|
|
|
|
echo "Modes de déploiement disponibles :" |
|
|
echo "1. Docker (Recommandé)" |
|
|
echo "2. Installation manuelle" |
|
|
echo "3. Mise à jour" |
|
|
read -p "Choisissez un mode (1-3): " deploy_mode |
|
|
|
|
|
case $deploy_mode in |
|
|
1) |
|
|
log "Déploiement avec Docker..." |
|
|
deploy_docker |
|
|
;; |
|
|
2) |
|
|
log "Installation manuelle..." |
|
|
deploy_manual |
|
|
;; |
|
|
3) |
|
|
log "Mise à jour..." |
|
|
update_deployment |
|
|
;; |
|
|
*) |
|
|
error "Mode invalide" |
|
|
;; |
|
|
esac |
|
|
|
|
|
deploy_docker() { |
|
|
log "Installation de Docker et Docker Compose..." |
|
|
|
|
|
|
|
|
if ! command -v docker &> /dev/null; then |
|
|
curl -fsSL https://get.docker.com -o get-docker.sh |
|
|
sh get-docker.sh |
|
|
rm get-docker.sh |
|
|
fi |
|
|
|
|
|
|
|
|
if ! command -v docker-compose &> /dev/null; then |
|
|
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose |
|
|
chmod +x /usr/local/bin/docker-compose |
|
|
fi |
|
|
|
|
|
|
|
|
mkdir -p $DEPLOY_PATH |
|
|
cd $DEPLOY_PATH |
|
|
|
|
|
|
|
|
if [ -f "/tmp/firewatch-deploy.tar.gz" ]; then |
|
|
tar -xzf /tmp/firewatch-deploy.tar.gz |
|
|
else |
|
|
error "Archive de déploiement non trouvée" |
|
|
fi |
|
|
|
|
|
|
|
|
if [ ! -f ".env" ]; then |
|
|
cp .env.example .env |
|
|
|
|
|
|
|
|
DB_PASSWORD=$(openssl rand -base64 32) |
|
|
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(50))") |
|
|
|
|
|
sed -i "s/SECRET_KEY=.*/SECRET_KEY=$SECRET_KEY/" .env |
|
|
sed -i "s/firewatch123/$DB_PASSWORD/g" .env |
|
|
|
|
|
warning "Veuillez éditer .env avec vos configurations spécifiques" |
|
|
fi |
|
|
|
|
|
|
|
|
log "Démarrage des services Docker..." |
|
|
docker-compose up -d |
|
|
|
|
|
|
|
|
sleep 30 |
|
|
|
|
|
|
|
|
if docker-compose ps | grep -q "Up"; then |
|
|
log "✓ Services Docker démarrés avec succès" |
|
|
else |
|
|
error "Échec du démarrage des services" |
|
|
fi |
|
|
|
|
|
|
|
|
setup_nginx_docker |
|
|
} |
|
|
|
|
|
deploy_manual() { |
|
|
log "Installation manuelle..." |
|
|
|
|
|
|
|
|
apt update |
|
|
apt install -y python3.11 python3.11-venv python3-pip nginx postgresql redis-server |
|
|
apt install -y libgl1-mesa-glx libglib2.0-0 libsm6 libxext6 libxrender-dev |
|
|
|
|
|
|
|
|
if ! id "$DEPLOY_USER" &>/dev/null; then |
|
|
useradd -m -s /bin/bash $DEPLOY_USER |
|
|
log "Utilisateur $DEPLOY_USER créé" |
|
|
fi |
|
|
|
|
|
|
|
|
mkdir -p $DEPLOY_PATH |
|
|
chown $DEPLOY_USER:$DEPLOY_USER $DEPLOY_PATH |
|
|
|
|
|
|
|
|
if [ -f "/tmp/firewatch-deploy.tar.gz" ]; then |
|
|
cd $DEPLOY_PATH |
|
|
tar -xzf /tmp/firewatch-deploy.tar.gz |
|
|
chown -R $DEPLOY_USER:$DEPLOY_USER . |
|
|
else |
|
|
error "Archive de déploiement non trouvée" |
|
|
fi |
|
|
|
|
|
|
|
|
sudo -u $DEPLOY_USER python3.11 -m venv $DEPLOY_PATH/venv |
|
|
sudo -u $DEPLOY_USER $DEPLOY_PATH/venv/bin/pip install -r $DEPLOY_PATH/requirements.txt |
|
|
|
|
|
|
|
|
setup_postgresql |
|
|
|
|
|
|
|
|
systemctl enable redis-server |
|
|
systemctl start redis-server |
|
|
|
|
|
|
|
|
setup_application |
|
|
|
|
|
|
|
|
setup_systemd_service |
|
|
|
|
|
|
|
|
setup_nginx_manual |
|
|
|
|
|
log "Installation manuelle terminée" |
|
|
} |
|
|
|
|
|
setup_postgresql() { |
|
|
log "Configuration de PostgreSQL..." |
|
|
|
|
|
|
|
|
systemctl enable postgresql |
|
|
systemctl start postgresql |
|
|
|
|
|
|
|
|
sudo -u postgres psql << EOF |
|
|
CREATE DATABASE firewatch_db; |
|
|
CREATE USER firewatch WITH PASSWORD 'firewatch_secure_password_2024'; |
|
|
GRANT ALL PRIVILEGES ON DATABASE firewatch_db TO firewatch; |
|
|
\q |
|
|
EOF |
|
|
|
|
|
log "✓ PostgreSQL configuré" |
|
|
} |
|
|
|
|
|
setup_application() { |
|
|
log "Configuration de l'application..." |
|
|
|
|
|
cd $DEPLOY_PATH |
|
|
|
|
|
|
|
|
if [ ! -f ".env" ]; then |
|
|
cp .env.example .env |
|
|
|
|
|
SECRET_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(50))") |
|
|
sed -i "s/SECRET_KEY=.*/SECRET_KEY=$SECRET_KEY/" .env |
|
|
sed -i "s/DEBUG=True/DEBUG=False/" .env |
|
|
sed -i "s/DATABASE_URL=.*/DATABASE_URL=postgresql:\/\/firewatch:firewatch_secure_password_2024@localhost:5432\/firewatch_db/" .env |
|
|
fi |
|
|
|
|
|
|
|
|
sudo -u $DEPLOY_USER $DEPLOY_PATH/venv/bin/python manage.py migrate |
|
|
sudo -u $DEPLOY_USER $DEPLOY_PATH/venv/bin/python manage.py collectstatic --noinput |
|
|
|
|
|
|
|
|
mkdir -p $DEPLOY_PATH/media $DEPLOY_PATH/logs |
|
|
chown -R $DEPLOY_USER:$DEPLOY_USER $DEPLOY_PATH/media $DEPLOY_PATH/logs |
|
|
|
|
|
log "✓ Application configurée" |
|
|
} |
|
|
|
|
|
setup_systemd_service() { |
|
|
log "Configuration du service systemd..." |
|
|
|
|
|
cat > /etc/systemd/system/$SERVICE_NAME.service << EOF |
|
|
[Unit] |
|
|
Description=FireWatch AI Django Application |
|
|
After=network.target postgresql.service redis.service |
|
|
|
|
|
[Service] |
|
|
Type=exec |
|
|
User=$DEPLOY_USER |
|
|
Group=$DEPLOY_USER |
|
|
WorkingDirectory=$DEPLOY_PATH |
|
|
Environment=PATH=$DEPLOY_PATH/venv/bin |
|
|
ExecStart=$DEPLOY_PATH/venv/bin/gunicorn --bind 127.0.0.1:8000 --workers 4 --timeout 120 $PROJECT_NAME.wsgi:application |
|
|
ExecReload=/bin/kill -s HUP \$MAINPID |
|
|
Restart=always |
|
|
RestartSec=10 |
|
|
|
|
|
[Install] |
|
|
WantedBy=multi-user.target |
|
|
EOF |
|
|
|
|
|
systemctl daemon-reload |
|
|
systemctl enable $SERVICE_NAME |
|
|
systemctl start $SERVICE_NAME |
|
|
|
|
|
log "✓ Service systemd configuré et démarré" |
|
|
} |
|
|
|
|
|
setup_nginx_manual() { |
|
|
log "Configuration de Nginx..." |
|
|
|
|
|
cat > /etc/nginx/sites-available/$NGINX_SITE << EOF |
|
|
server { |
|
|
listen 80; |
|
|
server_name _; |
|
|
|
|
|
client_max_body_size 50M; |
|
|
|
|
|
location /static/ { |
|
|
alias $DEPLOY_PATH/staticfiles/; |
|
|
expires 1y; |
|
|
add_header Cache-Control "public, immutable"; |
|
|
} |
|
|
|
|
|
location /media/ { |
|
|
alias $DEPLOY_PATH/media/; |
|
|
expires 1y; |
|
|
add_header Cache-Control "public"; |
|
|
} |
|
|
|
|
|
location / { |
|
|
proxy_pass http://127.0.0.1:8000; |
|
|
proxy_set_header Host \$host; |
|
|
proxy_set_header X-Real-IP \$remote_addr; |
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; |
|
|
proxy_set_header X-Forwarded-Proto \$scheme; |
|
|
proxy_connect_timeout 60s; |
|
|
proxy_send_timeout 60s; |
|
|
proxy_read_timeout 60s; |
|
|
} |
|
|
} |
|
|
EOF |
|
|
|
|
|
|
|
|
ln -sf /etc/nginx/sites-available/$NGINX_SITE /etc/nginx/sites-enabled/ |
|
|
rm -f /etc/nginx/sites-enabled/default |
|
|
|
|
|
|
|
|
nginx -t |
|
|
systemctl enable nginx |
|
|
systemctl restart nginx |
|
|
|
|
|
log "✓ Nginx configuré" |
|
|
} |
|
|
|
|
|
setup_nginx_docker() { |
|
|
log "Configuration de Nginx pour Docker..." |
|
|
|
|
|
cat > nginx.conf << EOF |
|
|
events { |
|
|
worker_connections 1024; |
|
|
} |
|
|
|
|
|
http { |
|
|
upstream firewatch_app { |
|
|
server web:8000; |
|
|
} |
|
|
|
|
|
server { |
|
|
listen 80; |
|
|
server_name _; |
|
|
|
|
|
client_max_body_size 50M; |
|
|
|
|
|
location /static/ { |
|
|
alias /app/staticfiles/; |
|
|
} |
|
|
|
|
|
location /media/ { |
|
|
alias /app/media/; |
|
|
} |
|
|
|
|
|
location / { |
|
|
proxy_pass http://firewatch_app; |
|
|
proxy_set_header Host \$host; |
|
|
proxy_set_header X-Real-IP \$remote_addr; |
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; |
|
|
proxy_set_header X-Forwarded-Proto \$scheme; |
|
|
} |
|
|
} |
|
|
} |
|
|
EOF |
|
|
|
|
|
log "✓ Configuration Nginx pour Docker créée" |
|
|
} |
|
|
|
|
|
update_deployment() { |
|
|
log "Mise à jour du déploiement..." |
|
|
|
|
|
if [ -f "$DEPLOY_PATH/docker-compose.yml" ]; then |
|
|
|
|
|
cd $DEPLOY_PATH |
|
|
docker-compose down |
|
|
|
|
|
|
|
|
backup_dir="/tmp/firewatch-backup-$(date +%Y%m%d-%H%M%S)" |
|
|
mkdir -p $backup_dir |
|
|
cp -r media models .env $backup_dir/ |
|
|
|
|
|
|
|
|
if [ -f "/tmp/firewatch-deploy.tar.gz" ]; then |
|
|
tar -xzf /tmp/firewatch-deploy.tar.gz |
|
|
fi |
|
|
|
|
|
|
|
|
cp -r $backup_dir/* . |
|
|
|
|
|
|
|
|
docker-compose up -d |
|
|
|
|
|
else |
|
|
|
|
|
systemctl stop $SERVICE_NAME |
|
|
|
|
|
cd $DEPLOY_PATH |
|
|
|
|
|
|
|
|
backup_dir="/tmp/firewatch-backup-$(date +%Y%m%d-%H%M%S)" |
|
|
mkdir -p $backup_dir |
|
|
cp -r media models .env $backup_dir/ |
|
|
|
|
|
|
|
|
if [ -f "/tmp/firewatch-deploy.tar.gz" ]; then |
|
|
tar -xzf /tmp/firewatch-deploy.tar.gz |
|
|
fi |
|
|
|
|
|
|
|
|
cp -r $backup_dir/* . |
|
|
chown -R $DEPLOY_USER:$DEPLOY_USER . |
|
|
|
|
|
|
|
|
sudo -u $DEPLOY_USER $DEPLOY_PATH/venv/bin/pip install -r requirements.txt |
|
|
|
|
|
|
|
|
sudo -u $DEPLOY_USER $DEPLOY_PATH/venv/bin/python manage.py migrate |
|
|
sudo -u $DEPLOY_USER $DEPLOY_PATH/venv/bin/python manage.py collectstatic --noinput |
|
|
|
|
|
|
|
|
systemctl start $SERVICE_NAME |
|
|
systemctl restart nginx |
|
|
fi |
|
|
|
|
|
log "✓ Mise à jour terminée" |
|
|
} |
|
|
|
|
|
|
|
|
log "Vérification du déploiement..." |
|
|
sleep 10 |
|
|
|
|
|
if curl -f http://localhost/ > /dev/null 2>&1; then |
|
|
log "✅ Déploiement réussi ! FireWatch AI est accessible" |
|
|
echo "" |
|
|
echo -e "${GREEN}🎉 FireWatch AI est maintenant en production ! 🎉${NC}" |
|
|
echo -e "${BLUE}URL: http://votre-serveur/${NC}" |
|
|
echo -e "${BLUE}Admin: http://votre-serveur/admin/${NC}" |
|
|
echo "" |
|
|
echo -e "${YELLOW}N'oubliez pas de :${NC}" |
|
|
echo "1. Configurer un nom de domaine" |
|
|
echo "2. Installer un certificat SSL" |
|
|
echo "3. Configurer les sauvegardes" |
|
|
echo "4. Placer vos modèles YOLOv8 dans models/" |
|
|
echo "" |
|
|
echo -e "${PURPLE}Créé par Marino ATOHOUN${NC}" |
|
|
else |
|
|
error "Échec du déploiement - L'application n'est pas accessible" |
|
|
fi |
|
|
|
|
|
|