Add server deployment support with Essentia
- Add install-server.sh for easy deployment on Linux servers - Update Dockerfile to auto-detect architecture (x86_64/ARM64) - Add deploy.sh for remote deployment - Update requirements.txt with Essentia support notes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,23 @@ COPY requirements.txt .
|
||||
# Install Python dependencies in stages for better caching
|
||||
RUN pip install --no-cache-dir numpy==1.24.3
|
||||
RUN pip install --no-cache-dir scipy==1.11.4
|
||||
|
||||
# Install Essentia - detect architecture and install appropriate wheel
|
||||
RUN ARCH=$(uname -m) && \
|
||||
if [ "$ARCH" = "x86_64" ]; then \
|
||||
echo "Installing Essentia for x86_64..." && \
|
||||
pip install --no-cache-dir --trusted-host essentia.upf.edu \
|
||||
https://essentia.upf.edu/python-wheels/essentia-2.1_beta6.dev374-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl || \
|
||||
echo "Essentia installation failed, using fallback mode"; \
|
||||
elif [ "$ARCH" = "aarch64" ]; then \
|
||||
echo "Installing Essentia for aarch64..." && \
|
||||
pip install --no-cache-dir --trusted-host essentia.upf.edu \
|
||||
https://essentia.upf.edu/python-wheels/essentia-2.1_beta6.dev374-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl || \
|
||||
echo "Essentia installation failed, using fallback mode"; \
|
||||
else \
|
||||
echo "Unsupported architecture: $ARCH, using fallback mode"; \
|
||||
fi
|
||||
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy application code
|
||||
|
||||
@@ -15,12 +15,8 @@ soundfile==0.12.1
|
||||
audioread==3.0.1
|
||||
mutagen==1.47.0
|
||||
|
||||
# Optional: Essentia for genre/mood/instrument classification
|
||||
# Note: essentia-tensorflow not available on PyPI for all platforms
|
||||
# Uncomment if you can install it (Linux x86_64 only):
|
||||
# essentia==2.1b6.dev1110
|
||||
# For manual installation: pip install essentia
|
||||
# Or build from source: https://github.com/MTG/essentia
|
||||
# Essentia for genre/mood/instrument classification
|
||||
# Note: Essentia is installed separately in Dockerfile from official wheels
|
||||
|
||||
# Scientific Computing
|
||||
numpy==1.24.3
|
||||
|
||||
37
backend/src/alembic/versions/20251127_002_rename_metadata.py
Normal file
37
backend/src/alembic/versions/20251127_002_rename_metadata.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""Rename metadata to extra_metadata
|
||||
|
||||
Revision ID: 002
|
||||
Revises: 001
|
||||
Create Date: 2025-11-27
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '002'
|
||||
down_revision: Union[str, None] = '001'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Check if column exists before renaming
|
||||
op.execute("""
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name='audio_tracks' AND column_name='metadata'
|
||||
) THEN
|
||||
ALTER TABLE audio_tracks RENAME COLUMN metadata TO extra_metadata;
|
||||
END IF;
|
||||
END $$;
|
||||
""")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# Rename back to metadata
|
||||
op.execute('ALTER TABLE audio_tracks RENAME COLUMN extra_metadata TO metadata')
|
||||
82
deploy.sh
Executable file
82
deploy.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de déploiement pour Audio Classifier
|
||||
# Usage: ./deploy.sh [user@]hostname
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: ./deploy.sh user@hostname"
|
||||
echo "Exemple: ./deploy.sh root@mon-serveur.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SERVER=$1
|
||||
APP_NAME="audio-classifier"
|
||||
REMOTE_DIR="~/$APP_NAME"
|
||||
|
||||
echo "🚀 Déploiement de Audio Classifier sur $SERVER"
|
||||
echo ""
|
||||
|
||||
# 1. Vérifier la connexion SSH
|
||||
echo "📡 Vérification de la connexion SSH..."
|
||||
ssh $SERVER "echo '✅ Connexion SSH OK'" || exit 1
|
||||
echo ""
|
||||
|
||||
# 2. Créer le dossier distant
|
||||
echo "📁 Création du dossier distant $REMOTE_DIR..."
|
||||
ssh $SERVER "mkdir -p $REMOTE_DIR"
|
||||
echo ""
|
||||
|
||||
# 3. Copier les fichiers
|
||||
echo "📦 Transfert des fichiers..."
|
||||
rsync -avz --progress \
|
||||
--exclude 'node_modules' \
|
||||
--exclude '.next' \
|
||||
--exclude '__pycache__' \
|
||||
--exclude '*.pyc' \
|
||||
--exclude '.git' \
|
||||
--exclude 'backend/models/*.pb' \
|
||||
./ $SERVER:$REMOTE_DIR/
|
||||
echo ""
|
||||
|
||||
# 4. Télécharger les modèles Essentia sur le serveur
|
||||
echo "🤖 Téléchargement des modèles Essentia..."
|
||||
ssh $SERVER "cd $REMOTE_DIR && bash scripts/download-essentia-models.sh"
|
||||
echo ""
|
||||
|
||||
# 5. Vérifier Docker
|
||||
echo "🐳 Vérification de Docker..."
|
||||
ssh $SERVER "command -v docker >/dev/null 2>&1" || {
|
||||
echo "⚠️ Docker n'est pas installé sur le serveur."
|
||||
echo "Installation de Docker..."
|
||||
ssh $SERVER "curl -fsSL https://get.docker.com | sudo sh && sudo usermod -aG docker \$(whoami)"
|
||||
echo "✅ Docker installé. Vous devrez peut-être vous reconnecter au serveur."
|
||||
}
|
||||
|
||||
ssh $SERVER "command -v docker-compose >/dev/null 2>&1 || command -v docker compose >/dev/null 2>&1" || {
|
||||
echo "⚠️ Docker Compose n'est pas installé."
|
||||
echo "Installation de Docker Compose..."
|
||||
ssh $SERVER "sudo apt-get update && sudo apt-get install -y docker-compose-plugin"
|
||||
}
|
||||
echo ""
|
||||
|
||||
# 6. Build et démarrage
|
||||
echo "🔨 Build et démarrage de l'application..."
|
||||
ssh $SERVER "cd $REMOTE_DIR && docker-compose down && docker-compose build && docker-compose up -d"
|
||||
echo ""
|
||||
|
||||
# 7. Vérifier le statut
|
||||
echo "📊 Vérification du statut..."
|
||||
sleep 5
|
||||
ssh $SERVER "cd $REMOTE_DIR && docker-compose ps"
|
||||
echo ""
|
||||
|
||||
echo "✅ Déploiement terminé !"
|
||||
echo ""
|
||||
echo "🌐 L'application devrait être accessible sur:"
|
||||
echo " - Backend API: http://$SERVER:8000"
|
||||
echo " - Frontend: http://$SERVER:3000"
|
||||
echo ""
|
||||
echo "📝 Pour voir les logs:"
|
||||
echo " ssh $SERVER 'cd $REMOTE_DIR && docker-compose logs -f'"
|
||||
136
install-server.sh
Executable file
136
install-server.sh
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script d'installation pour Audio Classifier sur serveur Linux
|
||||
# À exécuter directement sur le serveur après avoir cloné le repo
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Installation de Audio Classifier"
|
||||
echo ""
|
||||
|
||||
# 1. Vérifier qu'on est dans le bon dossier
|
||||
if [ ! -f "docker-compose.yml" ]; then
|
||||
echo "❌ Erreur: Ce script doit être exécuté depuis la racine du projet"
|
||||
echo "Usage: cd audio-classifier && bash install-server.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. Vérifier l'architecture
|
||||
echo "🔍 Détection de l'architecture..."
|
||||
ARCH=$(uname -m)
|
||||
echo "Architecture détectée: $ARCH"
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
echo "✅ Architecture x86_64 - Parfait pour Essentia !"
|
||||
elif [ "$ARCH" = "aarch64" ]; then
|
||||
echo "⚠️ Architecture ARM64 - Essentia pourrait avoir des limitations"
|
||||
else
|
||||
echo "⚠️ Architecture non testée: $ARCH"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Installer Docker si nécessaire
|
||||
echo "🐳 Vérification de Docker..."
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "Docker non trouvé. Installation..."
|
||||
curl -fsSL https://get.docker.com | sudo sh
|
||||
sudo usermod -aG docker $USER
|
||||
echo "✅ Docker installé"
|
||||
echo "⚠️ Vous devrez vous reconnecter pour utiliser Docker sans sudo"
|
||||
echo "Commande: exit puis reconnectez-vous en SSH"
|
||||
else
|
||||
echo "✅ Docker déjà installé"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. Installer Docker Compose si nécessaire
|
||||
echo "🐳 Vérification de Docker Compose..."
|
||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null 2>&1; then
|
||||
echo "Docker Compose non trouvé. Installation..."
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y docker-compose-plugin
|
||||
echo "✅ Docker Compose installé"
|
||||
else
|
||||
echo "✅ Docker Compose déjà installé"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 5. Télécharger les modèles Essentia
|
||||
echo "🤖 Téléchargement des modèles Essentia..."
|
||||
if [ -f "scripts/download-essentia-models.sh" ]; then
|
||||
bash scripts/download-essentia-models.sh
|
||||
echo "✅ Modèles téléchargés"
|
||||
else
|
||||
echo "⚠️ Script de téléchargement non trouvé, les modèles seront téléchargés plus tard"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 6. Créer le fichier .env si nécessaire
|
||||
if [ ! -f ".env" ]; then
|
||||
echo "📝 Création du fichier .env..."
|
||||
cat > .env << 'EOF'
|
||||
# Database
|
||||
POSTGRES_USER=audio_classifier
|
||||
POSTGRES_PASSWORD=change_this_password
|
||||
POSTGRES_DB=audio_classifier
|
||||
DATABASE_URL=postgresql://audio_classifier:change_this_password@db:5432/audio_classifier
|
||||
|
||||
# Backend
|
||||
ESSENTIA_MODELS_PATH=/app/models
|
||||
|
||||
# Frontend
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8000
|
||||
EOF
|
||||
echo "✅ Fichier .env créé"
|
||||
echo "⚠️ Pensez à modifier les mots de passe dans .env"
|
||||
else
|
||||
echo "✅ Fichier .env existe déjà"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 7. Arrêter les conteneurs existants
|
||||
echo "🛑 Arrêt des conteneurs existants..."
|
||||
docker-compose down 2>/dev/null || true
|
||||
echo ""
|
||||
|
||||
# 8. Build de l'application
|
||||
echo "🔨 Build de l'application..."
|
||||
docker-compose build
|
||||
echo "✅ Build terminé"
|
||||
echo ""
|
||||
|
||||
# 9. Démarrer l'application
|
||||
echo "🚀 Démarrage de l'application..."
|
||||
docker-compose up -d
|
||||
echo ""
|
||||
|
||||
# 10. Attendre que les services démarrent
|
||||
echo "⏳ Attente du démarrage des services..."
|
||||
sleep 10
|
||||
echo ""
|
||||
|
||||
# 11. Vérifier le statut
|
||||
echo "📊 Statut des services:"
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# 12. Vérifier Essentia
|
||||
echo "🔍 Vérification d'Essentia..."
|
||||
docker-compose logs backend | grep -i essentia | tail -3
|
||||
echo ""
|
||||
|
||||
# 13. Afficher les informations finales
|
||||
echo "✅ Installation terminée !"
|
||||
echo ""
|
||||
echo "🌐 Application accessible sur:"
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
echo " - Backend API: http://$SERVER_IP:8000"
|
||||
echo " - API Docs: http://$SERVER_IP:8000/docs"
|
||||
echo " - Frontend: http://$SERVER_IP:3000"
|
||||
echo ""
|
||||
echo "📝 Commandes utiles:"
|
||||
echo " - Voir les logs: docker-compose logs -f"
|
||||
echo " - Arrêter: docker-compose down"
|
||||
echo " - Redémarrer: docker-compose restart"
|
||||
echo ""
|
||||
echo "🎵 Pour scanner vos fichiers audio:"
|
||||
echo " docker-compose exec backend python -m src.cli.scanner /path/to/music"
|
||||
Reference in New Issue
Block a user