Files
innotexBoard/ANSWERS.md
2026-01-16 18:40:39 +01:00

11 KiB

📋 Réponses aux questions - InnotexBoard

Question 1 : Code du fichier main.py pour FastAPI

Réponse

Le fichier backend/main.py contient tout ce qu'il faut.

Points clés :

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

# Initialisation
app = FastAPI(
    title="InnotexBoard - Debian Admin Panel",
    description="Interface d'administration légère pour Debian",
    version="0.1.0",
)

# Middleware de sécurité CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Routes
app.include_router(api_router, prefix="/api/v1")

# Lancement
if __name__ == "__main__":
    uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)

Structuration modulaire :

  • app/core/config.py → Configuration globale
  • app/core/security.py → Authentification PAM + JWT
  • app/api/endpoints/ → Routes (auth, system, docker)
  • app/services/ → Logique métier (psutil, Docker SDK)

Question 2 : Composant Vue.js pour Docker

Réponse

Voir frontend/src/views/ContainersView.vue - Composant complet avec :

Code minimaliste

<template>
  <div class="p-8">
    <!-- Liste des conteneurs -->
    <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
      <div 
        v-for="container in containers" 
        :key="container.id"
        class="card"
      >
        <!-- En-tête -->
        <h3 class="text-lg font-semibold text-blue-400">{{ container.name }}</h3>
        <p class="text-gray-400 text-sm">{{ container.image }}</p>
        
        <!-- Badge statut -->
        <span :class="getStatusClass(container.state)" class="badge">
          {{ container.state }}
        </span>
        
        <!-- Stats -->
        <div class="mt-4 grid grid-cols-2 gap-3">
          <div class="stat-box">CPU: {{ container.cpu_percent }}%</div>
          <div class="stat-box">MEM: {{ container.memory_usage }}</div>
        </div>
        
        <!-- Ports -->
        <div v-if="container.ports.length > 0" class="mt-3">
          <p class="text-xs text-gray-400">Ports:</p>
          <div v-for="port in container.ports" :key="port.private_port" class="text-xs text-gray-300">
            {{ port.public_port }}:{{ port.private_port }}/{{ port.type }}
          </div>
        </div>
        
        <!-- Boutons d'action -->
        <div class="mt-4 flex space-x-2">
          <button 
            v-if="container.state !== 'running'"
            @click="actionContainer(container.id, 'start')"
            class="btn btn-secondary flex-1"
          >
             Démarrer
          </button>
          <button 
            v-if="container.state === 'running'"
            @click="actionContainer(container.id, 'stop')"
            class="btn btn-danger flex-1"
          >
             Arrêter
          </button>
          <button 
            @click="actionContainer(container.id, 'restart')"
            class="btn btn-primary"
          >
            🔄
          </button>
          <button 
            @click="actionContainer(container.id, 'delete')"
            class="btn btn-danger"
          >
            🗑
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import api from '../api'

const containers = ref([])

// Récupérer les conteneurs
const fetchContainers = async () => {
  const response = await api.get('/docker/containers', { params: { all: true } })
  containers.value = response.data
}

// Exécuter une action (start/stop/restart/delete)
const actionContainer = async (id, action) => {
  try {
    if (action === 'start') {
      await api.post(`/docker/containers/${id}/start`)
    } else if (action === 'stop') {
      await api.post(`/docker/containers/${id}/stop`)
    } else if (action === 'restart') {
      await api.post(`/docker/containers/${id}/restart`)
    } else if (action === 'delete') {
      if (confirm('Êtes-vous sûr ?')) {
        await api.delete(`/docker/containers/${id}`)
      }
    }
    // Rafraîchir la liste
    await fetchContainers()
  } catch (error) {
    console.error('Erreur:', error)
  }
}

// Style du badge de statut
const getStatusClass = (state) => {
  if (state === 'running') return 'badge-green'
  if (state === 'exited') return 'badge-red'
  return 'badge-gray'
}

// Charger les conteneurs au montage
onMounted(() => {
  fetchContainers()
})
</script>

Caractéristiques :

  • Affichage en grille responsive (1 col mobile, 2 cols desktop)
  • Statut avec couleurs (vert=running, rouge=stopped)
  • Stats CPU/RAM temps réel
  • Affichage des ports mappés
  • Boutons d'action (Start/Stop/Restart/Delete)
  • Gestion des erreurs
  • Design moderne avec Tailwind

Question 3 : Configuration des permissions

Réponse

Voir PERMISSIONS.md pour le guide complet.

Résumé pour le démarrage rapide

1. Permissions Docker

# Option A (Développement - simple)
sudo usermod -aG docker $USER
newgrp docker
docker ps  # Vérifier

# Option B (Production - sécurisé)
sudo visudo
# Ajouter: www-data ALL=(ALL) NOPASSWD: /usr/bin/docker

2. Permissions PAM (Authentification système)

# L'utilisateur doit être dans le groupe shadow
sudo usermod -aG shadow $USER

# Vérifier
id $USER
# Doit contenir "shadow"

3. Permissions psutil (Stats système)

# psutil lit /proc et /sys (accessible par défaut)
ls -la /proc | head

# Si problèmes d'accès:
sudo python3 main.py  # Temporaire

# Ou modifier les permissions (attention!)
sudo chmod 755 /proc

4. Configuration recommandée pour production

# Créer un utilisateur dédié
sudo useradd -r -s /bin/false innotexboard

# Ajouter aux groupes
sudo usermod -aG docker innotexboard
sudo usermod -aG shadow innotexboard

# Sudo sans mot de passe pour Docker
echo "innotexboard ALL=(ALL) NOPASSWD: /usr/bin/docker" | sudo tee /etc/sudoers.d/innotexboard
sudo chmod 440 /etc/sudoers.d/innotexboard

# Lancer le service avec cet utilisateur
sudo -u innotexboard python3 main.py

5. Vérification des permissions

# Tester Docker
sudo -u innotexboard docker ps

# Tester psutil
sudo -u innotexboard python3 -c "import psutil; print(psutil.virtual_memory())"

# Tester PAM
python3 -c "import pam; print(pam.pam().authenticate('user', 'pass'))"

6. Systemd Service (Optionnel)

Créer /etc/systemd/system/innotexboard.service :

[Unit]
Description=InnotexBoard Admin Panel
After=network.target docker.service
Wants=docker.service

[Service]
Type=simple
User=innotexboard
WorkingDirectory=/opt/innotexboard/backend
ExecStart=/usr/bin/python3 main.py
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
# Activer et démarrer
sudo systemctl daemon-reload
sudo systemctl enable innotexboard
sudo systemctl start innotexboard
sudo systemctl status innotexboard

🎨 Design : Dashboard moderne sombre

Caractéristiques implémentées

Couleurs sombres :

  • Fond: bg-gray-900 (#0f172a)
  • Cards: bg-gray-800 (#1e293b)
  • Texte: text-gray-100

Cards élégantes :

.card {
  @apply bg-gray-800 rounded-lg p-6 shadow-lg border border-gray-700;
}

Barres de progression :

<div class="w-full bg-gray-700 rounded-full h-2">
  <div 
    class="bg-gradient-to-r from-blue-500 to-blue-600 h-2 rounded-full"
    :style="{ width: percentage + '%' }"
  ></div>
</div>

Responsive :

  • Sidebar + Main content en desktop
  • Stack verticalement en mobile

Interactive :

  • Hover effects sur les cards
  • Transitions smooth
  • Notifications toast
  • Chargement avec spinner

📊 Fichiers créés

Backend (Python/FastAPI)

Fichier Description
main.py Point d'entrée FastAPI
requirements.txt Dépendances Python
app/core/config.py Configuration globale
app/core/security.py Auth PAM + JWT
app/api/endpoints/auth.py Routes login
app/api/endpoints/system.py Routes CPU/RAM
app/api/endpoints/docker.py Routes Docker
app/services/system.py Logique psutil
app/services/docker_service.py Logique Docker

Frontend (Vue.js 3)

Fichier Description
src/main.js Point d'entrée Vue
src/App.vue Layout principal
src/api/index.js Client Axios
src/stores/auth.js State Pinia
src/router/index.js Routes Vue Router
src/views/LoginView.vue Écran login
src/views/DashboardView.vue Écran stats
src/views/ContainersView.vue Écran Docker
src/assets/styles.css Tailwind CSS

Configuration

Fichier Description
README.md Documentation générale
QUICKSTART.md Guide de démarrage rapide
PERMISSIONS.md Guide permissions
TECHNICAL_EXPLANATION.md Explication technique
docker-compose.yml Compose basique
docker-compose.advanced.yml Compose production
nginx.conf Configuration Nginx
test_api.sh Script de test

🚀 Démarrage rapide (30 secondes)

Terminal 1 - Backend

cd backend
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python3 main.py

Terminal 2 - Frontend

cd frontend
npm install
npm run dev

Terminal 3 - Accéder


Points forts de cette implémentation

  1. Authentification sécurisée - PAM + JWT tokens
  2. Monitoring temps réel - Stats CPU/RAM/processus
  3. Gestion Docker complète - Start/stop/restart/delete
  4. UI moderne - Dashboard dark mode avec Tailwind
  5. Architecture modulaire - Code facilement extensible
  6. Documentation complète - Guides et explications
  7. Prêt pour production - Dockerfile, docker-compose, Nginx
  8. Permissions configurables - Dev et production

🎯 Prochaines étapes possibles

  • Ajouter la gestion des fichiers/logs
  • Support des alertes/notifications
  • Graphiques de tendance (historique)
  • Gestion des volumes Docker
  • Configuration réseau
  • Backup automatiques
  • 2FA (Two-Factor Authentication)
  • API WebSocket pour live updates

Voilà ! Vous avez maintenant une interface d'administration Debian complète et moderne ! 🎉