feat: Ajout du script de gestion des services et documentation
Some checks failed
CI - 4NK_node / Code Quality (push) Failing after 50s
CI - 4NK_node / Unit Tests (push) Failing after 36s
CI - 4NK_node / Integration Tests (push) Successful in 34s
CI - 4NK_node / Security Tests (push) Failing after 32s
CI - 4NK_node / Docker Build & Test (push) Failing after 15s
CI - 4NK_node / Documentation Tests (push) Successful in 11s
CI - 4NK_node / Security Audit (push) Successful in 9s
CI - 4NK_node / Release Guard (push) Has been skipped
CI - 4NK_node / Performance Tests (push) Successful in 34s
CI - 4NK_node / Notify (push) Failing after 2s
CI - 4NK_node / Publish Release (push) Has been skipped

- Ajout du script manage_services.sh pour arrêter, nettoyer et redémarrer les services
- Documentation complète du script dans docs/scripts/
- Tests unitaires pour le script dans tests/scripts/
- Correction des contextes de build dans docker-compose.yml
This commit is contained in:
Debian 2025-08-29 15:37:32 +00:00
parent 6247fc9e54
commit 49b30a7ef1
4 changed files with 833 additions and 30 deletions

View File

@ -245,7 +245,9 @@ services:
- reverse_proxy - reverse_proxy
sdk_storage: sdk_storage:
build: ./sdk_storage build:
context: ../sdk_storage
dockerfile: Dockerfile
container_name: sdk-storage container_name: sdk-storage
restart: unless-stopped restart: unless-stopped
entrypoint: > entrypoint: >
@ -258,35 +260,35 @@ services:
- sdk_storage_data:/app/storage - sdk_storage_data:/app/storage
# Service interne: aucun port exposé # Service interne: aucun port exposé
sdk_signer: # sdk_signer:
build: # build:
context: ./sdk_signer # context: ../sdk_signer
dockerfile: ../dockerfiles/sdk_signer.Dockerfile # dockerfile: Dockerfile
container_name: sdk-signer # container_name: sdk-signer
restart: unless-stopped # restart: unless-stopped
user: "0:0" # user: "0:0"
environment: # environment:
- PORT=9090 # - PORT=9090
- API_KEY=dev-change-me # - API_KEY=dev-change-me
- RELAY_URLS=ws://sdk_relay_1:8090 # - RELAY_URLS=ws://sdk_relay_1:8090
- LOG_LEVEL=info # - LOG_LEVEL=info
- DATABASE_PATH=/app/data/server.db # - DATABASE_PATH=/app/data/server.db
entrypoint: > # entrypoint: >
/bin/sh -lc "mkdir -p /app/data && chown -R nodejs:nodejs /app/data || true; \ # /bin/sh -lc "mkdir -p /app/data && chown -R nodejs:nodejs /app/data || true; \
apk add --no-cache busybox-extras >/dev/null 2>&1 || true; \ # apk add --no-cache busybox-extras >/dev/null 2>&1 || true; \
mkdir -p /tmp/health && printf 'ok' > /tmp/health/health; \ # mkdir -p /tmp/health && printf 'ok' > /tmp/health/health; \
( /usr/sbin/httpd -f -h /tmp/health -p 9092 ) & \ # ( /usr/sbin/httpd -f -h /tmp/health -p 9092 ) & \
exec node -r ts-node/register/transpile-only src/index.ts" # exec node -r ts-node/register/transpile-only src/index.ts"
networks: # networks:
btcnet: # btcnet:
aliases: # aliases:
- sdk_signer # - sdk_signer
depends_on: # depends_on:
sdk_relay_1: # sdk_relay_1:
condition: service_started # condition: service_started
volumes: # volumes:
- sdk_signer_data:/app/data # - sdk_signer_data:/app/data
# Service interne: aucun port exposé # # Service interne: aucun port exposé
volumes: volumes:
bitcoin_data: bitcoin_data:

View File

@ -0,0 +1,179 @@
# Script de Gestion des Services 4NK Node
## Description
Le script `manage_services.sh` est un outil de gestion complet pour arrêter, nettoyer et relancer tous les services de l'infrastructure 4NK Node. Il utilise Docker Compose pour orchestrer les services et fournit des fonctionnalités de nettoyage et de surveillance.
## Emplacement
```
4NK_dev/4NK_node/scripts/manage_services.sh
```
## Fonctionnalités
### Commandes Disponibles
| Commande | Description |
|----------|-------------|
| `stop` | Arrêter tous les services |
| `clean` | Arrêter et nettoyer les conteneurs |
| `clean-all` | Arrêter, nettoyer conteneurs et volumes |
| `start` | Démarrer tous les services |
| `restart` | Arrêter, nettoyer et redémarrer (défaut) |
| `status` | Afficher le statut des services |
| `logs` | Afficher les logs en temps réel |
| `help` | Afficher l'aide |
### Services Gérés
Le script gère les services suivants définis dans `docker-compose.yml` :
- **tor-proxy** : Proxy Tor pour l'anonymat
- **bitcoin-signet** : Nœud Bitcoin Core (signet)
- **blindbit-oracle** : Oracle BlindBit
- **sdk_relay_1/2/3** : Trois instances de relais SDK
- **sdk-storage** : Service de stockage
- **4nk-ihm-client** : Interface utilisateur
- **4nk-reverse-proxy** : Proxy inverse Nginx
## Utilisation
### Redémarrage Complet (Recommandé)
```bash
./scripts/manage_services.sh
# ou
./scripts/manage_services.sh restart
```
### Arrêt des Services
```bash
./scripts/manage_services.sh stop
```
### Nettoyage Complet
```bash
./scripts/manage_services.sh clean-all
```
**⚠️ Attention** : Cette commande supprime TOUTES les données persistantes !
### Vérification du Statut
```bash
./scripts/manage_services.sh status
```
### Surveillance des Logs
```bash
./scripts/manage_services.sh logs
```
## Fonctionnalités Avancées
### Nettoyage Intelligent
Le script effectue un nettoyage intelligent en supprimant :
- Conteneurs arrêtés
- Images non utilisées
- Volumes non utilisés
- Réseaux non utilisés
### Attente des Services Critiques
Le script attend automatiquement que les services critiques soient prêts :
- Tor Proxy
- Bitcoin Core
- BlindBit Oracle
### Gestion des Erreurs
- Vérification de la présence de Docker
- Vérification du daemon Docker
- Vérification de Docker Compose
- Arrêt en cas d'erreur (`set -e`)
## Configuration
### Variables d'Environnement
Le script utilise les variables suivantes :
```bash
PROJECT_NAME="4NK Node"
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"
```
### Couleurs d'Affichage
Le script utilise des couleurs pour améliorer la lisibilité :
- 🔵 Bleu : En-têtes
- 🟢 Vert : Succès
- 🟡 Jaune : Avertissements
- 🔴 Rouge : Erreurs
- 🟣 Violet : Informations
- 🔵 Cyan : Étapes en cours
## Dépannage
### Problèmes Courants
1. **Docker non installé**
```
❌ Docker n'est pas installé ou n'est pas dans le PATH
```
2. **Daemon Docker non démarré**
```
❌ Docker daemon n'est pas en cours d'exécution
```
3. **Docker Compose non disponible**
```
❌ Docker Compose n'est pas installé ou n'est pas dans le PATH
```
### Logs de Construction
En cas de problème lors de la construction des images, utilisez :
```bash
docker compose -f docker-compose.yml build --no-cache --progress=plain
```
## Notes Techniques
### Services Temporairement Désactivés
Le service `sdk_signer` est temporairement désactivé en raison de dépendances manquantes (module `../pkg/sdk_client`).
### Volumes Persistants
Les volumes suivants sont préservés lors du redémarrage :
- `4nk_node_bitcoin_data`
- `4nk_node_blindbit_data`
- `4nk_node_sdk_relay_1_data`
- `4nk_node_sdk_relay_2_data`
- `4nk_node_sdk_relay_3_data`
- `4nk_node_sdk_storage_data`
- `4nk_node_sdk_signer_data`
### Réseau Docker
Le script utilise le réseau `4nk_node_btcnet` pour la communication inter-services.
## Historique des Modifications
- **2025-08-29** : Création du script avec support Docker Compose v2
- Correction des chemins de build pour sdk_storage et sdk_signer
- Désactivation temporaire du service sdk_signer
- Ajout de la documentation complète
## Auteur
Script créé pour l'infrastructure 4NK Node.

294
scripts/manage_services.sh Executable file
View File

@ -0,0 +1,294 @@
#!/bin/bash
# =============================================================================
# Script de Gestion des Services 4NK Node
# =============================================================================
# Date: $(date)
# Description: Arrêter, nettoyer et relancer tous les services
# =============================================================================
set -e # Arrêter en cas d'erreur
# =============================================================================
# CONFIGURATION
# =============================================================================
# Couleurs pour l'affichage
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# Configuration du projet
PROJECT_NAME="4NK Node"
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPOSE_FILE="$PROJECT_DIR/docker-compose.yml"
# =============================================================================
# FONCTIONS UTILITAIRES
# =============================================================================
print_header() {
echo -e "${BLUE}=============================================================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}=============================================================================${NC}"
}
print_step() {
echo -e "${CYAN}🔄 $1${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${PURPLE} $1${NC}"
}
wait_for_service() {
local service_name=$1
local max_attempts=30
local attempt=1
print_step "Attente du service $service_name..."
while [ $attempt -le $max_attempts ]; do
if docker compose -f "$COMPOSE_FILE" ps "$service_name" | grep -q "Up"; then
print_success "Service $service_name est prêt"
return 0
fi
echo -n "."
sleep 2
attempt=$((attempt + 1))
done
print_warning "Service $service_name n'est pas prêt après $max_attempts tentatives"
return 1
}
# =============================================================================
# FONCTIONS PRINCIPALES
# =============================================================================
stop_all_services() {
print_header "ARRÊT DE TOUS LES SERVICES"
if [ -f "$COMPOSE_FILE" ]; then
print_step "Arrêt des services Docker Compose..."
docker compose -f "$COMPOSE_FILE" down --timeout 30
print_success "Services Docker Compose arrêtés"
else
print_warning "Fichier docker-compose.yml non trouvé"
fi
# Arrêt des conteneurs individuels au cas où
print_step "Arrêt des conteneurs individuels..."
docker stop $(docker ps -q --filter "name=4nk" --filter "name=tor" --filter "name=bitcoin" --filter "name=blindbit" --filter "name=sdk" --filter "name=proxy") 2>/dev/null || true
print_success "Conteneurs individuels arrêtés"
}
cleanup_containers() {
print_header "NETTOYAGE DES CONTENEURS"
print_step "Suppression des conteneurs arrêtés..."
docker container prune -f
print_success "Conteneurs arrêtés supprimés"
print_step "Suppression des images non utilisées..."
docker image prune -f
print_success "Images non utilisées supprimées"
print_step "Nettoyage des volumes non utilisés..."
docker volume prune -f
print_success "Volumes non utilisés supprimés"
print_step "Nettoyage des réseaux non utilisés..."
docker network prune -f
print_success "Réseaux non utilisés supprimés"
}
cleanup_volumes() {
print_header "NETTOYAGE COMPLET DES VOLUMES"
print_warning "Cette opération supprimera TOUTES les données persistantes !"
read -p "Êtes-vous sûr de vouloir continuer ? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
print_step "Suppression des volumes 4NK..."
docker volume rm $(docker volume ls -q --filter "name=4nk_node") 2>/dev/null || true
print_success "Volumes 4NK supprimés"
else
print_info "Nettoyage des volumes annulé"
fi
}
start_all_services() {
print_header "DÉMARRAGE DE TOUS LES SERVICES"
if [ ! -f "$COMPOSE_FILE" ]; then
print_error "Fichier docker-compose.yml non trouvé dans $PROJECT_DIR"
exit 1
fi
print_step "Construction des images Docker..."
docker compose -f "$COMPOSE_FILE" build --no-cache
print_success "Images construites"
print_step "Démarrage de tous les services..."
docker compose -f "$COMPOSE_FILE" up -d
print_success "Services démarrés"
# Attente des services critiques
print_step "Attente des services critiques..."
wait_for_service "tor"
wait_for_service "bitcoin"
wait_for_service "blindbit"
print_success "Services critiques prêts"
}
show_status() {
print_header "STATUT DES SERVICES"
echo ""
print_info "Conteneurs en cours d'exécution:"
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(4nk|tor|bitcoin|blindbit|sdk|proxy)" || echo "Aucun conteneur 4NK en cours d'exécution"
echo ""
print_info "Services Docker Compose:"
if [ -f "$COMPOSE_FILE" ]; then
docker compose -f "$COMPOSE_FILE" ps
else
print_warning "Fichier docker-compose.yml non trouvé"
fi
echo ""
print_info "Volumes 4NK:"
docker volume ls --filter "name=4nk_node"
echo ""
print_info "Réseaux 4NK:"
docker network ls --filter "name=4nk_node"
}
show_logs() {
print_header "LOGS DES SERVICES"
if [ -f "$COMPOSE_FILE" ]; then
docker compose -f "$COMPOSE_FILE" logs --tail=50 -f
else
print_error "Fichier docker-compose.yml non trouvé"
fi
}
# =============================================================================
# FONCTION PRINCIPALE
# =============================================================================
main() {
print_header "SCRIPT DE GESTION DES SERVICES $PROJECT_NAME"
print_info "Répertoire de travail: $PROJECT_DIR"
print_info "Fichier compose: $COMPOSE_FILE"
print_info "Date: $(date)"
# Traitement des arguments
case "${1:-restart}" in
"stop")
stop_all_services
;;
"clean")
stop_all_services
cleanup_containers
;;
"clean-all")
stop_all_services
cleanup_containers
cleanup_volumes
;;
"start")
start_all_services
;;
"restart")
stop_all_services
cleanup_containers
start_all_services
;;
"status")
show_status
;;
"logs")
show_logs
;;
"help"|"-h"|"--help")
echo ""
echo -e "${CYAN}Usage: $0 [COMMANDE]${NC}"
echo ""
echo -e "${GREEN}Commandes disponibles:${NC}"
echo -e " ${GREEN}stop${NC} Arrêter tous les services"
echo -e " ${GREEN}clean${NC} Arrêter et nettoyer les conteneurs"
echo -e " ${GREEN}clean-all${NC} Arrêter, nettoyer conteneurs et volumes"
echo -e " ${GREEN}start${NC} Démarrer tous les services"
echo -e " ${GREEN}restart${NC} Arrêter, nettoyer et redémarrer (défaut)"
echo -e " ${GREEN}status${NC} Afficher le statut des services"
echo -e " ${GREEN}logs${NC} Afficher les logs en temps réel"
echo -e " ${GREEN}help${NC} Afficher cette aide"
echo ""
echo -e "${CYAN}Exemples:${NC}"
echo -e " ${GREEN}$0${NC} Redémarrage complet"
echo -e " ${GREEN}$0 stop${NC} Arrêter tous les services"
echo -e " ${GREEN}$0 status${NC} Vérifier le statut"
echo ""
exit 0
;;
*)
print_error "Commande inconnue: $1"
print_info "Utilisez '$0 help' pour voir les commandes disponibles"
exit 1
;;
esac
print_header "OPÉRATION TERMINÉE"
print_success "Gestion des services $PROJECT_NAME terminée !"
}
# =============================================================================
# VÉRIFICATIONS PRÉALABLES
# =============================================================================
# Vérification de Docker
if ! command -v docker &> /dev/null; then
print_error "Docker n'est pas installé ou n'est pas dans le PATH"
exit 1
fi
# Vérification que Docker daemon est en cours d'exécution
if ! docker info &> /dev/null; then
print_error "Docker daemon n'est pas en cours d'exécution"
exit 1
fi
# Vérification de Docker Compose
if ! docker compose version &> /dev/null; then
print_error "Docker Compose n'est pas installé ou n'est pas dans le PATH"
exit 1
fi
# =============================================================================
# EXÉCUTION
# =============================================================================
main "$@"

View File

@ -0,0 +1,328 @@
#!/bin/bash
# =============================================================================
# Tests pour le Script de Gestion des Services 4NK Node
# =============================================================================
set -e
# =============================================================================
# CONFIGURATION
# =============================================================================
# Couleurs pour l'affichage
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration des tests
SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../scripts" && pwd)/manage_services.sh"
TEST_DIR="/tmp/.4nk/test_manage_services_$(date +%s)"
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# =============================================================================
# FONCTIONS UTILITAIRES
# =============================================================================
print_header() {
echo -e "${BLUE}=============================================================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}=============================================================================${NC}"
}
print_test() {
echo -e "${YELLOW}🧪 Test: $1${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
# =============================================================================
# FONCTIONS DE TEST
# =============================================================================
test_script_exists() {
print_test "Vérification de l'existence du script"
if [ -f "$SCRIPT_PATH" ]; then
print_success "Le script existe"
return 0
else
print_error "Le script n'existe pas: $SCRIPT_PATH"
return 1
fi
}
test_script_executable() {
print_test "Vérification des permissions d'exécution"
if [ -x "$SCRIPT_PATH" ]; then
print_success "Le script est exécutable"
return 0
else
print_error "Le script n'est pas exécutable"
return 1
fi
}
test_help_command() {
print_test "Test de la commande help"
if output=$(bash "$SCRIPT_PATH" help 2>&1); then
if echo "$output" | grep -q "Usage:"; then
print_success "Commande help fonctionne"
return 0
else
print_error "Commande help ne retourne pas l'usage attendu"
return 1
fi
else
print_error "Commande help échoue"
return 1
fi
}
test_invalid_command() {
print_test "Test d'une commande invalide"
if output=$(bash "$SCRIPT_PATH" invalid_command 2>&1); then
print_error "Commande invalide devrait échouer"
return 1
else
if echo "$output" | grep -q "Commande inconnue"; then
print_success "Commande invalide correctement rejetée"
return 0
else
print_error "Message d'erreur inattendu pour commande invalide"
return 1
fi
fi
}
test_docker_requirements() {
print_test "Vérification des prérequis Docker"
# Test Docker
if ! command -v docker &> /dev/null; then
print_error "Docker n'est pas installé"
return 1
fi
# Test Docker daemon
if ! docker info &> /dev/null; then
print_error "Docker daemon n'est pas en cours d'exécution"
return 1
fi
# Test Docker Compose
if ! docker compose version &> /dev/null; then
print_error "Docker Compose n'est pas disponible"
return 1
fi
print_success "Tous les prérequis Docker sont satisfaits"
return 0
}
test_compose_file_exists() {
print_test "Vérification de l'existence du fichier docker-compose.yml"
local compose_file="$PROJECT_DIR/docker-compose.yml"
if [ -f "$compose_file" ]; then
print_success "Fichier docker-compose.yml trouvé"
return 0
else
print_error "Fichier docker-compose.yml manquant: $compose_file"
return 1
fi
}
test_status_command() {
print_test "Test de la commande status"
if output=$(bash "$SCRIPT_PATH" status 2>&1); then
if echo "$output" | grep -q "STATUT DES SERVICES"; then
print_success "Commande status fonctionne"
return 0
else
print_error "Commande status ne retourne pas le format attendu"
return 1
fi
else
print_error "Commande status échoue"
return 1
fi
}
test_stop_command() {
print_test "Test de la commande stop"
# Vérifier d'abord s'il y a des services en cours
if ! docker compose -f "$PROJECT_DIR/docker-compose.yml" ps | grep -q "Up"; then
print_info "Aucun service en cours, test de stop ignoré"
return 0
fi
if output=$(bash "$SCRIPT_PATH" stop 2>&1); then
if echo "$output" | grep -q "Services Docker Compose arrêtés"; then
print_success "Commande stop fonctionne"
return 0
else
print_error "Commande stop ne retourne pas le message attendu"
return 1
fi
else
print_error "Commande stop échoue"
return 1
fi
}
test_clean_command() {
print_test "Test de la commande clean"
if output=$(bash "$SCRIPT_PATH" clean 2>&1); then
if echo "$output" | grep -q "Nettoyage des conteneurs"; then
print_success "Commande clean fonctionne"
return 0
else
print_error "Commande clean ne retourne pas le message attendu"
return 1
fi
else
print_error "Commande clean échoue"
return 1
fi
}
# =============================================================================
# FONCTION PRINCIPALE
# =============================================================================
run_tests() {
print_header "TESTS DU SCRIPT DE GESTION DES SERVICES 4NK NODE"
print_info "Script: $SCRIPT_PATH"
print_info "Projet: $PROJECT_DIR"
print_info "Date: $(date)"
local total_tests=0
local passed_tests=0
local failed_tests=0
# Créer le répertoire de test
mkdir -p "$TEST_DIR"
# Tests de base
((total_tests++))
if test_script_exists; then
((passed_tests++))
else
((failed_tests++))
fi
((total_tests++))
if test_script_executable; then
((passed_tests++))
else
((failed_tests++))
fi
((total_tests++))
if test_help_command; then
((passed_tests++))
else
((failed_tests++))
fi
((total_tests++))
if test_invalid_command; then
((passed_tests++))
else
((failed_tests++))
fi
# Tests des prérequis
((total_tests++))
if test_docker_requirements; then
((passed_tests++))
else
((failed_tests++))
fi
((total_tests++))
if test_compose_file_exists; then
((passed_tests++))
else
((failed_tests++))
fi
# Tests des commandes (si Docker est disponible)
if command -v docker &> /dev/null && docker info &> /dev/null; then
((total_tests++))
if test_status_command; then
((passed_tests++))
else
((failed_tests++))
fi
((total_tests++))
if test_stop_command; then
((passed_tests++))
else
((failed_tests++))
fi
((total_tests++))
if test_clean_command; then
((passed_tests++))
else
((failed_tests++))
fi
else
print_info "Tests des commandes Docker ignorés (Docker non disponible)"
fi
# Résumé
print_header "RÉSUMÉ DES TESTS"
echo -e "${GREEN}Tests réussis: $passed_tests${NC}"
echo -e "${RED}Tests échoués: $failed_tests${NC}"
echo -e "${BLUE}Total: $total_tests${NC}"
# Nettoyage
rm -rf "$TEST_DIR"
if [ $failed_tests -eq 0 ]; then
print_success "Tous les tests sont passés !"
exit 0
else
print_error "$failed_tests test(s) ont échoué"
exit 1
fi
}
# =============================================================================
# EXÉCUTION
# =============================================================================
if [ "${1:-}" = "help" ] || [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
echo "Usage: $0 [help]"
echo ""
echo "Tests pour le script de gestion des services 4NK Node"
echo ""
echo "Options:"
echo " help, -h, --help Afficher cette aide"
exit 0
fi
run_tests