align for IA agents + grafana
This commit is contained in:
parent
242e7bcd57
commit
c49b8f86ec
@ -16,16 +16,14 @@ Consulte attentivement `lecoffre_node/IA_agents/flux.md`.
|
|||||||
Le déploiement se fait depuis le répertoire **`lecoffre_node/`**, en utilisant les scripts présents dans **`scripts/`**.
|
Le déploiement se fait depuis le répertoire **`lecoffre_node/`**, en utilisant les scripts présents dans **`scripts/`**.
|
||||||
Ces scripts doivent évoluer au fil des retours et être améliorés plutôt que dupliqués.
|
Ces scripts doivent évoluer au fil des retours et être améliorés plutôt que dupliqués.
|
||||||
|
|
||||||
Dans **tous les projets** :
|
Dans **tous les projets** à vérifier un par un dont lecoffre_node:
|
||||||
|
|
||||||
- Analyse le dossier pour bien le comprendre
|
- Analyse le dossier pour bien le comprendre
|
||||||
- Analyse le code pour bien le comprendre
|
- Analyse le code pour bien le comprendre
|
||||||
- Une branche Git dédiée `ext` existe.
|
- Une branche Git dédiée `ext` existe.
|
||||||
- Aucun tag Git nommé `ext` n’existe.
|
- Aucun tag Git nommé `ext` n’existe.
|
||||||
- Des images Docker avec le tag `ext` existent.
|
|
||||||
- Les images Docker ne sont build que via CI qui est la seule à pousser sur le registry ou pour test localement.
|
|
||||||
- Aucun Dockerfile ne doit utiliser de clés ssh car aucun repos n'est privé, utiliser HTTPS.
|
|
||||||
- Les services doivent écouter sur 0.0.0.0 (et non sur 127.0.0.1).
|
- Les services doivent écouter sur 0.0.0.0 (et non sur 127.0.0.1).
|
||||||
|
- Le serveur ngnix gère les url d'accès extérieurs
|
||||||
- Corrige aussi les erreurs non critiques.
|
- Corrige aussi les erreurs non critiques.
|
||||||
|
|
||||||
Via les scripts, lance tous les services de `lecoffre_node/docker-compose.yml`.
|
Via les scripts, lance tous les services de `lecoffre_node/docker-compose.yml`.
|
||||||
@ -54,6 +52,7 @@ Via les scripts, lance tous les services de `lecoffre_node/docker-compose.yml`.
|
|||||||
### Synchronisations
|
### Synchronisations
|
||||||
|
|
||||||
11. Synchroniser les configurations dans `lecoffre_node/conf`.
|
11. Synchroniser les configurations dans `lecoffre_node/conf`.
|
||||||
|
Les configurations ngnix doivent toutes être cenralisées dans lecoffre_node/conf/ngninx (à synchroniser par des copies depuis lecoffre_node vers les fichiers cibles qui seront réellement utilisés -sauf dans lecoffre_node ce sont les fichiers de lecoffre_node/conf/ qui sont utilisés-, toujours vérifier la cohérence entre les copie et les fichiers utilisés, à intégrer dans le script existant de synchronisation à mettre à jour). Ne pas faire de liens symboliques pour les confs afin de le maintenir via git et docker.
|
||||||
12. Synchroniser les logs dans `lecoffre_node/logs` (brancher grafana pour un dashboard par projet)
|
12. Synchroniser les logs dans `lecoffre_node/logs` (brancher grafana pour un dashboard par projet)
|
||||||
|
|
||||||
### Sécurité et conformité
|
### Sécurité et conformité
|
||||||
@ -109,6 +108,9 @@ Via les scripts, lance tous les services de `lecoffre_node/docker-compose.yml`.
|
|||||||
|
|
||||||
Pour tous les projets contenant un **Dockerfile**, avant de pousser sur la branche `ext` :
|
Pour tous les projets contenant un **Dockerfile**, avant de pousser sur la branche `ext` :
|
||||||
|
|
||||||
|
- Des images Docker avec le tag `ext` existent.
|
||||||
|
- Les images Docker ne sont build que via CI qui est la seule à pousser sur le registry ou pour test localement.
|
||||||
|
- Aucun Dockerfile ne doit utiliser de clés ssh car aucun repos n'est privé, utiliser HTTPS.
|
||||||
- Mettre à jour le Dockerfile pour maîtriser les prérequis :
|
- Mettre à jour le Dockerfile pour maîtriser les prérequis :
|
||||||
- inclure `sudo apt update && sudo apt upgrade`,
|
- inclure `sudo apt update && sudo apt upgrade`,
|
||||||
- installer `build-essential`, `autoconf`, `automake`, `libtool`, `pkg-config`, `cmake`, `ninja-build`, `clang`, `lldb`, `lld`, `make`, `tree`, `ncdu`, `mc`, `exuberant-ctags`, `cscope`, `vim`, `emacs`, `jq`, `curl`, `sed`, `gawk`, `inetutils-tools`, `iputils-*`, `net-tools`, `iproute2`
|
- installer `build-essential`, `autoconf`, `automake`, `libtool`, `pkg-config`, `cmake`, `ninja-build`, `clang`, `lldb`, `lld`, `make`, `tree`, `ncdu`, `mc`, `exuberant-ctags`, `cscope`, `vim`, `emacs`, `jq`, `curl`, `sed`, `gawk`, `inetutils-tools`, `iputils-*`, `net-tools`, `iproute2`
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
| **ihm_client** | ihm_client | 0.0.0.0:3003 | 3003 | HTTP | http://0.0.0.0:3003 |
|
| **ihm_client** | ihm_client | 0.0.0.0:3003 | 3003 | HTTP | http://0.0.0.0:3003 |
|
||||||
| **sdk_signer** | sdk_signer | 0.0.0.0:3001 | 3001 | HTTP/WebSocket | http://0.0.0.0:3001 |
|
| **sdk_signer** | sdk_signer | 0.0.0.0:3001 | 3001 | HTTP/WebSocket | http://0.0.0.0:3001 |
|
||||||
| **sdk_storage** | sdk_storage | 0.0.0.0:8081 | 8080 | HTTP | http://0.0.0.0:8081 |
|
| **sdk_storage** | sdk_storage | 0.0.0.0:8081 | 8080 | HTTP | http://0.0.0.0:8081 |
|
||||||
|
| **grafana** | grafana | 127.0.0.1:3005 | 3000 | HTTP | http://127.0.0.1:3005 |
|
||||||
|
| **loki** | loki | 127.0.0.1:3100 | 3100 | HTTP | http://127.0.0.1:3100 |
|
||||||
|
| **promtail** | promtail | - | - | - | Collecte des logs |
|
||||||
|
|
||||||
### 🌐 **Services Externes**
|
### 🌐 **Services Externes**
|
||||||
|
|
||||||
@ -39,6 +42,8 @@
|
|||||||
| **/ws/** | sdk_relay | 8090 | WebSocket | Relay WebSocket |
|
| **/ws/** | sdk_relay | 8090 | WebSocket | Relay WebSocket |
|
||||||
| **/signer/** | sdk_signer | 3001 | HTTP/WebSocket | Service Signer |
|
| **/signer/** | sdk_signer | 3001 | HTTP/WebSocket | Service Signer |
|
||||||
| **/src/service-workers/** | ihm_client | 3003 | HTTP | Service Workers |
|
| **/src/service-workers/** | ihm_client | 3003 | HTTP | Service Workers |
|
||||||
|
| **/grafana/** | grafana | 3005 | HTTP | Interface de monitoring |
|
||||||
|
| **/loki/** | loki | 3100 | HTTP | API de logs |
|
||||||
|
|
||||||
### 🏠 **Proxy Nginx Local (local.4nkweb.com)**
|
### 🏠 **Proxy Nginx Local (local.4nkweb.com)**
|
||||||
|
|
||||||
@ -73,6 +78,8 @@
|
|||||||
| **RELAY_URLS** | wss://dev4.4nkweb.com/ws/,wss://dev3.4nkweb.com/ws/ | sdk_signer |
|
| **RELAY_URLS** | wss://dev4.4nkweb.com/ws/,wss://dev3.4nkweb.com/ws/ | sdk_signer |
|
||||||
| **bootstrap_url** | wss://dev3.4nkweb.com/ws/ | sdk_relay |
|
| **bootstrap_url** | wss://dev3.4nkweb.com/ws/ | sdk_relay |
|
||||||
| **storage** | https://dev4.4nkweb.com/storage | sdk_relay |
|
| **storage** | https://dev4.4nkweb.com/storage | sdk_relay |
|
||||||
|
| **GRAFANA_ADMIN_PASSWORD** | admin123 | grafana |
|
||||||
|
| **GF_SERVER_ROOT_URL** | https://dev4.4nkweb.com/grafana/ | grafana |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -88,6 +95,8 @@ Internet → dev4.4nkweb.com (Nginx) → Services Locaux
|
|||||||
2. **API** : `https://dev4.4nkweb.com/api/` → lecoffre-back (0.0.0.0:8080)
|
2. **API** : `https://dev4.4nkweb.com/api/` → lecoffre-back (0.0.0.0:8080)
|
||||||
3. **IHM** : `https://dev4.4nkweb.com/` → ihm_client (0.0.0.0:3003)
|
3. **IHM** : `https://dev4.4nkweb.com/` → ihm_client (0.0.0.0:3003)
|
||||||
4. **WebSocket** : `https://dev4.4nkweb.com/ws/` → sdk_relay (0.0.0.0:8090)
|
4. **WebSocket** : `https://dev4.4nkweb.com/ws/` → sdk_relay (0.0.0.0:8090)
|
||||||
|
5. **Monitoring** : `https://dev4.4nkweb.com/grafana/` → grafana (127.0.0.1:3005)
|
||||||
|
6. **Logs API** : `https://dev4.4nkweb.com/loki/` → loki (127.0.0.1:3100)
|
||||||
|
|
||||||
### 🔗 **Flux de Redirection**
|
### 🔗 **Flux de Redirection**
|
||||||
|
|
||||||
@ -103,17 +112,65 @@ local.4nkdev.com → local.4nkweb.com → https://dev4.4nkweb.com/lecoffre
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 📊 **Architecture du Monitoring**
|
||||||
|
|
||||||
|
### 🔄 **Stack de Monitoring**
|
||||||
|
|
||||||
|
```
|
||||||
|
Services → Logs Centralisés → Promtail → Loki → Grafana
|
||||||
|
↓ ↓ ↓ ↓ ↓
|
||||||
|
Docker logs/ Collecte Stockage Dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
### 📁 **Centralisation des Logs**
|
||||||
|
|
||||||
|
| Service | Dossier de Logs | Volume Docker | Description |
|
||||||
|
|---------|-----------------|---------------|-------------|
|
||||||
|
| **bitcoin** | `logs/bitcoin/` | `./logs/bitcoin:/var/log/bitcoin` | Logs Bitcoin Signet |
|
||||||
|
| **blindbit** | `logs/blindbit/` | `./logs/blindbit:/var/log/blindbit` | Logs Oracle |
|
||||||
|
| **sdk_relay** | `logs/sdk_relay/` | `./logs/sdk_relay:/var/log/sdk_relay` | Logs Relay |
|
||||||
|
| **sdk_signer** | `logs/sdk_signer/` | `./logs/sdk_signer:/var/log/sdk_signer` | Logs Signer |
|
||||||
|
| **sdk_storage** | `logs/sdk_storage/` | `./logs/sdk_storage:/var/log/sdk_storage` | Logs Storage |
|
||||||
|
| **lecoffre-back** | `logs/lecoffre-back/` | `./logs/lecoffre-back:/var/log/lecoffre-back` | Logs Backend |
|
||||||
|
| **lecoffre-front** | `logs/lecoffre-front/` | `./logs/lecoffre-front:/var/log/lecoffre-front` | Logs Frontend |
|
||||||
|
| **ihm_client** | `logs/ihm_client/` | `./logs/ihm_client:/var/log/ihm_client` | Logs IHM |
|
||||||
|
| **miner** | `logs/miner/` | `./logs/miner:/var/log/miner` | Logs Mineur |
|
||||||
|
| **tor** | `logs/tor/` | `./logs/tor:/var/log/tor` | Logs Tor |
|
||||||
|
|
||||||
|
### 📊 **Dashboards Grafana**
|
||||||
|
|
||||||
|
| Dashboard | ID | Description | Métriques |
|
||||||
|
|-----------|----|--------------|-----------|
|
||||||
|
| **Vue d'ensemble LeCoffre** | `lecoffre-overview` | Monitoring global | Erreurs par service, volume de logs, logs d'erreur temps réel |
|
||||||
|
| **Bitcoin & Miner** | `bitcoin-miner` | Monitoring blockchain | Nouveaux blocs, blocs minés, erreurs blockchain |
|
||||||
|
| **Services Applications** | `services-overview` | Monitoring applicatif | Volume de logs par service, erreurs applications |
|
||||||
|
|
||||||
|
### 🔧 **Scripts de Gestion**
|
||||||
|
|
||||||
|
| Script | Description | Usage |
|
||||||
|
|--------|-------------|-------|
|
||||||
|
| `deploy-grafana.sh` | Déploiement du monitoring | `./scripts/deploy-grafana.sh start` |
|
||||||
|
| `setup-logs.sh` | Configuration des logs | `./scripts/setup-logs.sh` |
|
||||||
|
| `collect-logs.sh` | Collecte des logs | `./scripts/collect-logs.sh` |
|
||||||
|
| `test-monitoring.sh` | Test de connectivité | `./scripts/test-monitoring.sh` |
|
||||||
|
| `sync-monitoring-config.sh` | Synchronisation config | `./scripts/sync-monitoring-config.sh` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## ⚠️ **Points d'Attention**
|
## ⚠️ **Points d'Attention**
|
||||||
|
|
||||||
1. **dev3.4nkweb.com:9090** - Service signer externe actuellement inactif
|
1. **dev3.4nkweb.com:9090** - Service signer externe actuellement inactif
|
||||||
2. **dev3.4nkweb.com** - Retourne 502 Bad Gateway (services backend indisponibles)
|
2. **dev3.4nkweb.com** - Retourne 502 Bad Gateway (services backend indisponibles)
|
||||||
3. **Ports 0.0.0.0** - Services locaux uniquement accessibles depuis la machine
|
3. **Ports 0.0.0.0** - Services locaux uniquement accessibles depuis la machine
|
||||||
4. **Ports 127.0.0.2** - lecoffre-front sur interface séparée
|
4. **Ports 127.0.0.2** - lecoffre-front sur interface séparée
|
||||||
|
5. **Grafana Port 3005** - Changé de 3000 pour éviter conflit avec lecoffre-front
|
||||||
|
6. **Monitoring** - Loki et Promtail doivent être démarrés avant Grafana
|
||||||
|
|
||||||
## 📋 **Ordre de Démarrage des Services**
|
## 📋 **Ordre de Démarrage des Services**
|
||||||
|
|
||||||
Selon les règles du projet, l'ordre de démarrage est :
|
Selon les règles du projet, l'ordre de démarrage est :
|
||||||
|
|
||||||
|
### 🚀 **Services Principaux**
|
||||||
1. **tor** - Proxy anonyme
|
1. **tor** - Proxy anonyme
|
||||||
2. **bitcoin** - Nœud Bitcoin Signet
|
2. **bitcoin** - Nœud Bitcoin Signet
|
||||||
3. **blindbit** - Oracle Bitcoin
|
3. **blindbit** - Oracle Bitcoin
|
||||||
@ -121,16 +178,96 @@ Selon les règles du projet, l'ordre de démarrage est :
|
|||||||
5. **sdk_relay** - Relais des transactions
|
5. **sdk_relay** - Relais des transactions
|
||||||
6. **sdk_signer** - Signature des processus
|
6. **sdk_signer** - Signature des processus
|
||||||
7. **ihm_client** - Interface utilisateur
|
7. **ihm_client** - Interface utilisateur
|
||||||
|
8. **lecoffre-back** - Backend API
|
||||||
|
9. **lecoffre-front** - Frontend application
|
||||||
|
|
||||||
|
### 📊 **Services de Monitoring**
|
||||||
|
10. **loki** - Base de données de logs
|
||||||
|
11. **promtail** - Agent de collecte des logs
|
||||||
|
12. **grafana** - Interface de visualisation
|
||||||
|
|
||||||
|
### 🔧 **Services Utilitaires**
|
||||||
|
- **watchtower** - Surveillance automatique des conteneurs
|
||||||
|
- **signet_miner** - Mineur Bitcoin (profil séparé)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🔧 **Configuration Critique**
|
## 🔧 **Configuration Critique**
|
||||||
|
|
||||||
|
### 🌐 **Services Externes**
|
||||||
- **Mempool du réseau signet** : `https://mempool2.4nkweb.com/fr/docs/api/rest`
|
- **Mempool du réseau signet** : `https://mempool2.4nkweb.com/fr/docs/api/rest`
|
||||||
- **Test de connectivité Bitcoin** : `docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile=/home/bitcoin/.bitcoin/signet/.cookie getblockchaininfo`
|
- **Test de connectivité Bitcoin** : `docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile=/home/bitcoin/.bitcoin/signet/.cookie getblockchaininfo`
|
||||||
- **Test WebSocket Bootstrap** : `wss://dev3.4nkweb.com/ws/`
|
- **Test WebSocket Bootstrap** : `wss://dev3.4nkweb.com/ws/`
|
||||||
|
|
||||||
|
### 📊 **Monitoring et Tests**
|
||||||
|
- **Test monitoring complet** : `./scripts/test-monitoring.sh`
|
||||||
|
- **Déploiement Grafana** : `./scripts/deploy-grafana.sh start`
|
||||||
|
- **Collecte des logs** : `./scripts/collect-logs.sh`
|
||||||
|
- **Grafana local** : `http://localhost:3005` (admin/admin123)
|
||||||
|
- **Loki API** : `http://localhost:3100/loki/api/v1/labels`
|
||||||
|
- **Test connectivité Grafana** : `curl http://localhost:3005/api/health`
|
||||||
|
- **Test connectivité Loki** : `curl http://localhost:3100/ready`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Met à jour ce document si tu détectes des incohérences ou pose des questions pour confirmer.
|
## 💾 **Volumes et Persistance des Données**
|
||||||
Propose des améliorations dans un document lecoffre_node/IA_agents/todo.md
|
|
||||||
|
### 📦 **Volumes Docker**
|
||||||
|
|
||||||
|
| Volume | Services | Données | Persistance |
|
||||||
|
|--------|----------|---------|-------------|
|
||||||
|
| **4nk_node_bitcoin_data** | bitcoin, blindbit | Blockchain, wallet, conf | ✅ Critique |
|
||||||
|
| **blindbit_data** | blindbit | Oracle data, tweaks | ✅ Critique |
|
||||||
|
| **sdk_data** | sdk_relay | Relay data, logs | ✅ Important |
|
||||||
|
| **grafana_data** | grafana | Dashboards, config | ✅ Important |
|
||||||
|
| **loki_data** | loki | Logs stockés | ✅ Important |
|
||||||
|
|
||||||
|
### 📁 **Volumes de Logs**
|
||||||
|
|
||||||
|
| Service | Volume Local | Volume Conteneur | Description |
|
||||||
|
|---------|--------------|------------------|-------------|
|
||||||
|
| **Tous services** | `./logs/{service}/` | `/var/log/{service}` | Logs centralisés |
|
||||||
|
| **Bitcoin** | `./logs/bitcoin/` | `/var/log/bitcoin` | Logs blockchain |
|
||||||
|
| **Applications** | `./logs/{app}/` | `/var/log/{app}` | Logs applicatifs |
|
||||||
|
|
||||||
|
### 🔄 **Rotation et Nettoyage**
|
||||||
|
|
||||||
|
- **Rotation automatique** : Configuration dans `conf/logrotate/`
|
||||||
|
- **Rétention** : 7 jours par défaut
|
||||||
|
- **Compression** : Automatique après rotation
|
||||||
|
- **Nettoyage** : Scripts de maintenance disponibles
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 **Déploiement et Maintenance**
|
||||||
|
|
||||||
|
### 📋 **Commandes Essentielles**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Démarrage complet
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# Démarrage monitoring
|
||||||
|
./scripts/deploy-grafana.sh start
|
||||||
|
|
||||||
|
# Test de connectivité
|
||||||
|
./scripts/test-monitoring.sh
|
||||||
|
|
||||||
|
# Collecte des logs
|
||||||
|
./scripts/collect-logs.sh
|
||||||
|
|
||||||
|
# Synchronisation config
|
||||||
|
./scripts/sync-monitoring-config.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🔧 **Maintenance**
|
||||||
|
|
||||||
|
- **Surveillance** : Watchtower automatique toutes les 30s
|
||||||
|
- **Logs** : Centralisés et rotatifs
|
||||||
|
- **Monitoring** : Grafana + Loki + Promtail
|
||||||
|
- **Backup** : Volumes Docker persistants
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Met à jour ce document si tu détectes des incohérences ou pose des questions pour confirmer.**
|
||||||
|
**Propose des améliorations dans un document lecoffre_node/IA_agents/todo.md**
|
@ -36,12 +36,9 @@ enabled = false
|
|||||||
# Configuration des dashboards
|
# Configuration des dashboards
|
||||||
default_home_dashboard_path = /var/lib/grafana/dashboards/lecoffre-overview.json
|
default_home_dashboard_path = /var/lib/grafana/dashboards/lecoffre-overview.json
|
||||||
|
|
||||||
[alerting]
|
[unified_alerting]
|
||||||
# Configuration des alertes
|
# Configuration des alertes unifiées
|
||||||
enabled = true
|
enabled = true
|
||||||
execute_alerts = true
|
|
||||||
error_or_timeout = alerting
|
|
||||||
nodata_or_nullvalues = no_data
|
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
# Configuration des logs Grafana
|
# Configuration des logs Grafana
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
|
# HTTP server for ACME and initial proxying
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 80;
|
||||||
server_name dev4.4nkweb.com;
|
server_name dev4.4nkweb.com;
|
||||||
ssl_certificate /etc/letsencrypt/live/dev4.4nkweb.com/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/dev4.4nkweb.com/privkey.pem;
|
# Forcer l'upgrade des requêtes HTTP en HTTPS pour éviter les contenus mixtes
|
||||||
include /etc/nginx/proxy_params;
|
add_header Content-Security-Policy "upgrade-insecure-requests" always;
|
||||||
|
|
||||||
|
# ACME HTTP-01 challenges
|
||||||
|
location /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/letsencrypt;
|
||||||
|
}
|
||||||
|
|
||||||
# API backend - route /back/ vers /api/ du backend
|
# API backend - route /back/ vers /api/ du backend
|
||||||
location ~* ^/back/(.*)$ {
|
location ~* ^/back/(.*)$ {
|
||||||
@ -18,7 +24,32 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# API direct - route /api/ vers le backend
|
# API direct - route /api/ vers le backend
|
||||||
|
# Autorisations CORS dynamiques pour origines connues
|
||||||
|
set $cors_origin "";
|
||||||
|
if ($http_origin ~* ^(http://local\.4nkweb\.com:3000|https://dev4\.4nkweb\.com)$) {
|
||||||
|
set $cors_origin $http_origin;
|
||||||
|
}
|
||||||
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
|
# CORS pour développement local Next.js
|
||||||
|
proxy_hide_header Access-Control-Allow-Origin;
|
||||||
|
proxy_hide_header Access-Control-Allow-Credentials;
|
||||||
|
proxy_hide_header Access-Control-Allow-Headers;
|
||||||
|
proxy_hide_header Access-Control-Allow-Methods;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, x-session-id, Authorization" always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, x-session-id, Authorization" always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||||
|
|
||||||
proxy_pass http://127.0.0.1:8080/api/;
|
proxy_pass http://127.0.0.1:8080/api/;
|
||||||
include /etc/nginx/proxy_params;
|
include /etc/nginx/proxy_params;
|
||||||
proxy_read_timeout 300;
|
proxy_read_timeout 300;
|
||||||
@ -26,7 +57,147 @@ server {
|
|||||||
proxy_send_timeout 300;
|
proxy_send_timeout 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Root → ihm_client
|
# Compat: certains clients appellent /apiv1 -> réécriture vers /api/v1
|
||||||
|
location ~* ^/apiv1/(.*)$ {
|
||||||
|
# CORS pour compatibilité
|
||||||
|
proxy_hide_header Access-Control-Allow-Origin;
|
||||||
|
proxy_hide_header Access-Control-Allow-Credentials;
|
||||||
|
proxy_hide_header Access-Control-Allow-Headers;
|
||||||
|
proxy_hide_header Access-Control-Allow-Methods;
|
||||||
|
|
||||||
|
if ($request_method = OPTIONS) {
|
||||||
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, x-session-id, Authorization" always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_header Access-Control-Allow-Origin $cors_origin always;
|
||||||
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, x-session-id, Authorization" always;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||||
|
|
||||||
|
proxy_pass http://127.0.0.1:8080/api/v1/$1;
|
||||||
|
include /etc/nginx/proxy_params;
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_send_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
# WebSocket relay (sdk_relay)
|
||||||
|
location /ws/ {
|
||||||
|
proxy_pass http://127.0.0.1:8090/;
|
||||||
|
proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
|
||||||
|
proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;
|
||||||
|
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol;
|
||||||
|
proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
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_read_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
# API de transfert de fonds
|
||||||
|
location /api/v1/funds/ {
|
||||||
|
proxy_pass http://127.0.0.1:8080/api/v1/funds/;
|
||||||
|
include /etc/nginx/proxy_params;
|
||||||
|
proxy_read_timeout 300;
|
||||||
|
proxy_connect_timeout 300;
|
||||||
|
proxy_send_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Grafana - Interface de monitoring (DOIT être avant location /)
|
||||||
|
location /grafana/ {
|
||||||
|
proxy_pass http://127.0.0.1:3005/;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# Configuration spécifique pour Grafana
|
||||||
|
proxy_set_header X-Grafana-Org-Id 1;
|
||||||
|
|
||||||
|
# Support des WebSockets pour les live updates
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# Buffer settings
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Loki API - API de logs (DOIT être avant location /)
|
||||||
|
location /loki/ {
|
||||||
|
proxy_pass http://127.0.0.1:3100/;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# CORS pour les requêtes depuis Grafana
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Page de statut des services (DOIT être avant location /)
|
||||||
|
location /status/ {
|
||||||
|
# Serveur statique pour la page HTML
|
||||||
|
root /var/www/lecoffre/status;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
|
||||||
|
# Headers de sécurité
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
|
# Cache pour les assets statiques
|
||||||
|
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
|
||||||
|
expires 1h;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# API de statut des services (DOIT être avant location /)
|
||||||
|
location /status/api {
|
||||||
|
proxy_pass http://127.0.0.1:3006/api;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# CORS pour les requêtes AJAX
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
proxy_send_timeout 10s;
|
||||||
|
proxy_read_timeout 10s;
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ihm_client (root) - DOIT être en dernier
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://127.0.0.1:3003;
|
proxy_pass http://127.0.0.1:3003;
|
||||||
include /etc/nginx/proxy_params;
|
include /etc/nginx/proxy_params;
|
||||||
@ -36,94 +207,55 @@ server {
|
|||||||
proxy_read_timeout 300;
|
proxy_read_timeout 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
# lecoffre-front (préserver le préfixe)
|
# favicon
|
||||||
location = /lecoffre {
|
location = /favicon.ico {
|
||||||
proxy_pass http://127.0.0.2:3004;
|
root /home/debian/lecoffre_node/conf/nginx/assets;
|
||||||
include /etc/nginx/proxy_params;
|
try_files /favicon.ico =404;
|
||||||
proxy_set_header Host $host;
|
access_log off;
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
expires 30d;
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Prefix /lecoffre;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
}
|
|
||||||
location /lecoffre/ {
|
|
||||||
proxy_pass http://127.0.0.2:3004;
|
|
||||||
include /etc/nginx/proxy_params;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Prefix /lecoffre;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Next.js assets sous basePath
|
# lecoffre frontend
|
||||||
location /lecoffre/_next/webpack-hmr {
|
location = /lecoffre {
|
||||||
|
proxy_pass http://127.0.0.2:3004/lecoffre;
|
||||||
|
include /etc/nginx/proxy_params;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto http;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /lecoffre/ {
|
||||||
|
proxy_pass http://127.0.0.2:3004/lecoffre/;
|
||||||
|
include /etc/nginx/proxy_params;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto http;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_pass http://127.0.0.2:3004/lecoffre/_next/webpack-hmr;
|
|
||||||
proxy_read_timeout 600s;
|
|
||||||
}
|
|
||||||
location /lecoffre/_next/ {
|
|
||||||
proxy_pass http://127.0.0.2:3004/lecoffre/_next/;
|
|
||||||
include /etc/nginx/proxy_params;
|
|
||||||
proxy_read_timeout 300;
|
proxy_read_timeout 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Service Workers (servis par ihm_client)
|
# Next.js assets
|
||||||
location /src/service-workers/ {
|
location /_next/ {
|
||||||
proxy_pass http://127.0.0.1:3003/src/service-workers/;
|
proxy_pass http://127.0.0.2:3004/_next/;
|
||||||
|
include /etc/nginx/proxy_params;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto http;
|
||||||
|
}
|
||||||
|
|
||||||
|
# blindbit
|
||||||
|
location /blindbit/ {
|
||||||
|
proxy_pass http://127.0.0.1:8000/;
|
||||||
include /etc/nginx/proxy_params;
|
include /etc/nginx/proxy_params;
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# signer (sdk_signer) avec support WebSocket
|
# signer (sdk_signer) avec support WebSocket
|
||||||
location /signer/ {
|
location /signer/ {
|
||||||
|
proxy_pass http://127.0.0.1:3001/;
|
||||||
|
include /etc/nginx/proxy_params;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_pass http://127.0.0.1:3001/;
|
|
||||||
proxy_read_timeout 600s;
|
|
||||||
proxy_buffering off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Next.js assets au root si nécessaire
|
|
||||||
location /_next/ {
|
|
||||||
proxy_pass http://127.0.0.2:3004/_next/;
|
|
||||||
include /etc/nginx/proxy_params;
|
|
||||||
proxy_read_timeout 300;
|
proxy_read_timeout 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
# WebSocket relay (sdk_relay) en HTTPS
|
|
||||||
location = /ws {
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_pass http://127.0.0.1:8090/;
|
|
||||||
proxy_read_timeout 600s;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /ws/ {
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto https;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_pass http://127.0.0.1:8090/;
|
|
||||||
proxy_read_timeout 600s;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,93 @@ server {
|
|||||||
proxy_send_timeout 300;
|
proxy_send_timeout 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ihm_client (root)
|
# Grafana - Interface de monitoring (DOIT être avant location /)
|
||||||
|
location /grafana/ {
|
||||||
|
proxy_pass http://127.0.0.1:3005/;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# Configuration spécifique pour Grafana
|
||||||
|
proxy_set_header X-Grafana-Org-Id 1;
|
||||||
|
|
||||||
|
# Support des WebSockets pour les live updates
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 60s;
|
||||||
|
proxy_read_timeout 60s;
|
||||||
|
|
||||||
|
# Buffer settings
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Loki API - API de logs (DOIT être avant location /)
|
||||||
|
location /loki/ {
|
||||||
|
proxy_pass http://127.0.0.1:3100/;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# CORS pour les requêtes depuis Grafana
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Page de statut des services (DOIT être avant location /)
|
||||||
|
location /status/ {
|
||||||
|
# Serveur statique pour la page HTML
|
||||||
|
root /var/www/lecoffre/status;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
|
||||||
|
# Headers de sécurité
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
|
# Cache pour les assets statiques
|
||||||
|
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
|
||||||
|
expires 1h;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# API de statut des services (DOIT être avant location /)
|
||||||
|
location /status/api {
|
||||||
|
proxy_pass http://127.0.0.1:3006/api;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# CORS pour les requêtes AJAX
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||||
|
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||||
|
|
||||||
|
# Timeouts
|
||||||
|
proxy_connect_timeout 10s;
|
||||||
|
proxy_send_timeout 10s;
|
||||||
|
proxy_read_timeout 10s;
|
||||||
|
|
||||||
|
if ($request_method = 'OPTIONS') {
|
||||||
|
return 204;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ihm_client (root) - DOIT être en dernier
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://127.0.0.1:3003;
|
proxy_pass http://127.0.0.1:3003;
|
||||||
include /etc/nginx/proxy_params;
|
include /etc/nginx/proxy_params;
|
||||||
@ -171,4 +257,5 @@ server {
|
|||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_read_timeout 300;
|
proxy_read_timeout 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ server {
|
|||||||
|
|
||||||
# Proxy pour Grafana
|
# Proxy pour Grafana
|
||||||
location /grafana/ {
|
location /grafana/ {
|
||||||
proxy_pass http://127.0.0.1:3000/;
|
proxy_pass http://127.0.0.1:3005/;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
@ -284,7 +284,7 @@ services:
|
|||||||
- GF_SECURITY_ADMIN_PASSWORD=admin123
|
- GF_SECURITY_ADMIN_PASSWORD=admin123
|
||||||
- GF_USERS_ALLOW_SIGN_UP=false
|
- GF_USERS_ALLOW_SIGN_UP=false
|
||||||
- GF_SERVER_ROOT_URL=https://dev4.4nkweb.com/grafana/
|
- GF_SERVER_ROOT_URL=https://dev4.4nkweb.com/grafana/
|
||||||
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
|
- GF_PLUGINS_PREINSTALL_SYNC=grafana-clock-panel,grafana-simple-json-datasource
|
||||||
networks:
|
networks:
|
||||||
btcnet:
|
btcnet:
|
||||||
aliases:
|
aliases:
|
||||||
@ -321,6 +321,23 @@ services:
|
|||||||
- promtail
|
- promtail
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Service de statut des services
|
||||||
|
status-api:
|
||||||
|
build: ./web/status
|
||||||
|
container_name: status-api
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3006:3006"
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./web/status/api.js:/app/api.js:ro
|
||||||
|
networks:
|
||||||
|
btcnet:
|
||||||
|
aliases:
|
||||||
|
- status-api
|
||||||
|
labels:
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
bitcoin_data:
|
bitcoin_data:
|
||||||
name: 4nk_node_bitcoin_data
|
name: 4nk_node_bitcoin_data
|
||||||
|
@ -1,107 +0,0 @@
|
|||||||
# Architecture LeCoffre Node
|
|
||||||
|
|
||||||
> **📚 Documentation IA Recommandée** : Commencez par lire [`../IA_agents/context.md`](../IA_agents/context.md) et [`../IA_agents/flux.md`](../IA_agents/flux.md)
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
LeCoffre Node orchestre les services nécessaires pour la plateforme de gestion de documents sécurisée LeCoffre, utilisant Bitcoin Signet et des technologies de cryptographie avancées.
|
|
||||||
|
|
||||||
## 🏗️ Architecture des Services
|
|
||||||
|
|
||||||
### Services Locaux (Docker Compose)
|
|
||||||
| Service | Port | Image | Statut | Description |
|
|
||||||
|---------|------|-------|--------|-------------|
|
|
||||||
| **tor-proxy** | 9050 | `btcpayserver/tor:0.4.8.10` | ✅ | Proxy anonyme pour Bitcoin |
|
|
||||||
| **bitcoin-signet** | - | `git.4nkweb.com/4nk/bitcoin:latest` | ✅ | Nœud Bitcoin Signet |
|
|
||||||
| **blindbit-oracle** | 8000 | `git.4nkweb.com/4nk/blindbit-oracle:dev` | ✅ | Oracle blockchain |
|
|
||||||
| **sdk_relay** | 8090-8091 | `git.4nkweb.com/4nk/sdk_relay:ext` | ✅ | Relay WebSocket |
|
|
||||||
| **sdk_signer** | 3001 | `git.4nkweb.com/4nk/sdk_signer:ext` | ✅ | Service de signature |
|
|
||||||
| **sdk_storage** | 8081 | `git.4nkweb.com/4nk/sdk_storage:ext` | ✅ | Stockage temporaire |
|
|
||||||
| **lecoffre-back** | 8080 | `git.4nkweb.com/4nk/lecoffre-back-mini:ext` | ✅ | API Backend |
|
|
||||||
| **lecoffre-front** | 3004 | `git.4nkweb.com/4nk/lecoffre-front:ext` | ✅ | Interface utilisateur |
|
|
||||||
| **ihm_client** | 3003 | `git.4nkweb.com/4nk/ihm_client:ext` | ✅ | Gestion des clés |
|
|
||||||
| **watchtower** | - | `containrrr/watchtower` | ✅ | Surveillance automatique |
|
|
||||||
|
|
||||||
### Services Externes
|
|
||||||
| Service | URL | Statut | Description |
|
|
||||||
|---------|-----|--------|-------------|
|
|
||||||
| **Bootstrap Relay** | `wss://dev3.4nkweb.com/ws/` | ✅ | Relay externe |
|
|
||||||
| **Signer Externe** | `ws://dev3.4nkweb.com:9090` | ✅ | Service de signature |
|
|
||||||
| **Mempool** | `https://mempool2.4nkweb.com` | ✅ | Explorateur Bitcoin Signet |
|
|
||||||
|
|
||||||
## 🔄 Flux d'Architecture
|
|
||||||
|
|
||||||
### Flux Principal
|
|
||||||
```
|
|
||||||
Internet → dev4.4nkweb.com (Nginx) → Services Locaux
|
|
||||||
├── Frontend: https://dev4.4nkweb.com/lecoffre → lecoffre-front:3004
|
|
||||||
├── IHM: https://dev4.4nkweb.com/ → ihm_client:3003
|
|
||||||
├── API: https://dev4.4nkweb.com/api/ → lecoffre-back:8080
|
|
||||||
└── WebSocket: https://dev4.4nkweb.com/ws/ → sdk_relay:8090
|
|
||||||
```
|
|
||||||
|
|
||||||
### Flux de Redirection
|
|
||||||
```
|
|
||||||
local.4nkdev.com → local.4nkweb.com → https://dev4.4nkweb.com/lecoffre
|
|
||||||
```
|
|
||||||
|
|
||||||
## ⚙️ Configuration des Services
|
|
||||||
|
|
||||||
### Variables d'Environnement Clés
|
|
||||||
```bash
|
|
||||||
# Services externes
|
|
||||||
VITE_BOOTSTRAPURL=wss://dev4.4nkweb.com/ws/
|
|
||||||
SIGNER_WS_URL=ws://dev3.4nkweb.com:9090
|
|
||||||
SIGNER_BASE_URL=https://dev3.4nkweb.com
|
|
||||||
RELAY_URLS=wss://dev4.4nkweb.com/ws/,wss://dev3.4nkweb.com/ws/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Réseau Docker
|
|
||||||
- **Réseau** : `btcnet` (bridge) - subnet `172.20.0.0/16`
|
|
||||||
- **Volumes** : `4nk_node_bitcoin_data`, `blindbit_data`, `sdk_data`
|
|
||||||
|
|
||||||
## 🚀 Séquence de Démarrage
|
|
||||||
|
|
||||||
### Ordre Optimisé
|
|
||||||
1. **tor** → **bitcoin** → **blindbit** → **sdk_storage** → **sdk_relay** → **sdk_signer** → **ihm_client** → **lecoffre-back** → **lecoffre-front**
|
|
||||||
|
|
||||||
### Healthchecks
|
|
||||||
- **bitcoin** : `bitcoin-cli getblockchaininfo`
|
|
||||||
- **blindbit** : `curl http://localhost:8000/tweaks/1`
|
|
||||||
- **sdk_relay** : `curl http://localhost:8091/`
|
|
||||||
- **lecoffre-back** : `curl http://localhost:8080/api/v1/health`
|
|
||||||
|
|
||||||
## 🔧 Monitoring et Surveillance
|
|
||||||
|
|
||||||
### Watchtower
|
|
||||||
- **Mise à jour automatique** des images Docker toutes les 30 secondes
|
|
||||||
- **Surveillance** de tous les services avec le label `com.centurylinklabs.watchtower.enable=true`
|
|
||||||
|
|
||||||
### Commandes de Vérification
|
|
||||||
```bash
|
|
||||||
# Statut des services
|
|
||||||
docker compose ps
|
|
||||||
|
|
||||||
# Logs en temps réel
|
|
||||||
docker compose logs -f
|
|
||||||
|
|
||||||
# Vérifier Bitcoin
|
|
||||||
docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile=/home/bitcoin/.bitcoin/signet/.cookie getblockchaininfo
|
|
||||||
|
|
||||||
# Vérifier l'oracle
|
|
||||||
curl http://localhost:8000/tweaks/1
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📚 Documentation Associée
|
|
||||||
|
|
||||||
- **[`../IA_agents/flux.md`](../IA_agents/flux.md)** - Flux détaillés et architecture
|
|
||||||
- **[`CONFIGURATION_SERVICES.md`](CONFIGURATION_SERVICES.md)** - Configuration détaillée
|
|
||||||
- **[`STARTUP_IMPROVEMENTS.md`](STARTUP_IMPROVEMENTS.md)** - Améliorations de démarrage
|
|
||||||
- **[`REX.md`](REX.md)** - Rapport d'expérience récent
|
|
||||||
|
|
||||||
## 🏷️ Historique des Versions
|
|
||||||
|
|
||||||
- **21/09/2025** : Déploiement réussi avec toutes les dépendances optimisées
|
|
||||||
- **21/09/2025** : Correction des imports WASM et compatibilité Alpine
|
|
||||||
- **21/09/2025** : Mise à jour de la documentation et nettoyage
|
|
||||||
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
|||||||
# Configuration des Services LeCoffre
|
|
||||||
|
|
||||||
## ⚠️ CONFIGURATION IMPORTANTE ⚠️
|
|
||||||
|
|
||||||
**RÈGLES CRITIQUES :**
|
|
||||||
- **Le seul signer utilisé est dev3.4nkweb.com** (NE PAS utiliser de signer local)
|
|
||||||
- **URL de lecoffre-front** : `https://dev4.4nkweb.com/lecoffre`
|
|
||||||
- **URL de ihm_client (iframe)** : `https://dev4.4nkweb.com`
|
|
||||||
- **Cette VM est** : `dev4.4nkweb.com`
|
|
||||||
|
|
||||||
## Architecture des Services
|
|
||||||
|
|
||||||
### Services Distants
|
|
||||||
- **Signer** : `dev3.4nkweb.com:9090` (seul signer utilisé)
|
|
||||||
- **LeCoffre Front** : `https://dev4.4nkweb.com/lecoffre`
|
|
||||||
- **IHM Client (iframe)** : `https://dev4.4nkweb.com`
|
|
||||||
|
|
||||||
### Ports des Services
|
|
||||||
- **Relai (sdk_relay)** : ports 8090-8091
|
|
||||||
- **Signer (sdk_signer)** : port 9090
|
|
||||||
|
|
||||||
### VM Actuelle
|
|
||||||
- **Host** : `dev4.4nkweb.com`
|
|
||||||
- **Services locaux** : sdk_relay, sdk_storage, bitcoin-signet, blindbit-oracle
|
|
||||||
|
|
||||||
## Configuration des Connexions
|
|
||||||
|
|
||||||
### lecoffre-back
|
|
||||||
```yaml
|
|
||||||
environment:
|
|
||||||
- SIGNER_WS_URL=ws://dev3.4nkweb.com:9090
|
|
||||||
- RELAY_URLS=ws://sdk_relay:8090
|
|
||||||
- SIGNER_BASE_URL=https://dev3.4nkweb.com
|
|
||||||
```
|
|
||||||
|
|
||||||
### Statut Actuel
|
|
||||||
✅ **Service signer réparé** : `dev3.4nkweb.com:9090` est maintenant accessible et fonctionnel.
|
|
||||||
✅ **LeCoffre-back connecté** : Connexion WebSocket réussie au signer distant.
|
|
||||||
✅ **LeCoffre-front accessible** : `https://dev4.4nkweb.com/lecoffre` répond correctement.
|
|
||||||
✅ **IHM Client corrigé** : Configuration WebSocket corrigée pour utiliser `sdk_relay` local.
|
|
||||||
|
|
||||||
## Tests de Connectivité Exhaustifs (20/09/2025)
|
|
||||||
|
|
||||||
### Résultats des Tests Complets
|
|
||||||
|
|
||||||
#### Port 9090 (Tous échouent)
|
|
||||||
- `http://dev3.4nkweb.com:9090` → ❌ Connection refused
|
|
||||||
- `https://dev3.4nkweb.com:9090` → ❌ Connection refused
|
|
||||||
- Tous les chemins avec port 9090 → ❌ Connection refused
|
|
||||||
|
|
||||||
#### Port 443 (Nginx OK, Backend KO)
|
|
||||||
- `https://dev3.4nkweb.com` → ⚠️ 502 Bad Gateway
|
|
||||||
- `https://dev3.4nkweb.com/ws` → ⚠️ 301 Redirect vers `/ws/`
|
|
||||||
- `https://dev3.4nkweb.com/ws/` → ⚠️ 502 Bad Gateway
|
|
||||||
- `https://dev3.4nkweb.com/signer` → ⚠️ 502 Bad Gateway
|
|
||||||
- `https://dev3.4nkweb.com/signer/ws` → ⚠️ 502 Bad Gateway
|
|
||||||
|
|
||||||
#### Port 8080 (Service Express.js Actif)
|
|
||||||
- `http://dev3.4nkweb.com:8080` → ✅ **SERVICE ACTIF** (Express.js)
|
|
||||||
- `http://dev3.4nkweb.com:8080/ws` → ⚠️ 404 Not Found
|
|
||||||
- `http://dev3.4nkweb.com:8080/signer` → ⚠️ 404 Not Found
|
|
||||||
- `http://dev3.4nkweb.com:8080/health` → ⚠️ 404 Not Found
|
|
||||||
|
|
||||||
### Découverte Importante
|
|
||||||
**Port 8080** : Un service Express.js est actif sur dev3.4nkweb.com:8080 avec :
|
|
||||||
- Headers : `X-Powered-By: Express`
|
|
||||||
- CORS configuré pour `http://localhost:3000`
|
|
||||||
- Aucune route WebSocket/signer configurée
|
|
||||||
|
|
||||||
### Analyse
|
|
||||||
- **Port 9090** : Complètement fermé (service signer non démarré)
|
|
||||||
- **Port 443** : Nginx fonctionne mais services backend retournent 502 Bad Gateway
|
|
||||||
- **Port 8080** : Service Express.js actif mais sans routes WebSocket/signer
|
|
||||||
- **Port 3001** : Fermé
|
|
||||||
|
|
||||||
### Conclusion
|
|
||||||
✅ **Problème résolu** : Le service signer sur dev3.4nkweb.com:9090 a été réparé et est maintenant accessible.
|
|
||||||
|
|
||||||
**Tests de validation réussis :**
|
|
||||||
- Port 9090 ouvert et accessible
|
|
||||||
- Connexion WebSocket fonctionnelle depuis lecoffre-back
|
|
||||||
- Service lecoffre-front accessible sur https://dev4.4nkweb.com/lecoffre
|
|
||||||
|
|
||||||
## Historique
|
|
||||||
- Le signer dev3.4nkweb.com:9090 fonctionnait dans des configurations précédentes
|
|
||||||
- Configuration mise à jour le 20/09/2025
|
|
||||||
|
|
||||||
## Correction du Bootstrap WebSocket
|
|
||||||
|
|
||||||
### Problème identifié
|
|
||||||
- Configuration bootstrap incorrecte : `ws://dev3.4nkweb.com:8090`
|
|
||||||
- Le bootstrap distant ne fournissait pas de faucet sur ce port
|
|
||||||
|
|
||||||
### Solution appliquée
|
|
||||||
- Correction de la configuration : `bootstrap_url="wss://dev3.4nkweb.com/ws/"`
|
|
||||||
- Test confirmé : connexion WSS fonctionnelle avec faucet actif
|
|
||||||
- Réponse reçue avec NewTx (tx hex et tweak_data présents)
|
|
||||||
|
|
||||||
### État actuel
|
|
||||||
- ✅ Bootstrap WebSocket corrigé
|
|
||||||
- ✅ Connexion WSS fonctionnelle
|
|
||||||
- ⏳ Attente de génération d'adresse SP par le relai
|
|
||||||
- ⏳ Attente de réception des fonds du faucet
|
|
||||||
|
|
||||||
### Prochaines étapes
|
|
||||||
1. Vérifier la génération d'adresse SP du relai
|
|
||||||
2. Confirmer la réception des fonds du faucet
|
|
||||||
3. Tester le processus de pairing avec les fonds disponibles
|
|
||||||
|
|
||||||
|
|
||||||
## Adresse SP Permanente
|
|
||||||
|
|
||||||
### Configuration appliquée
|
|
||||||
- **Adresse SP fixe** : `tsp1qqgmwp9n5p9ujhq2j6cfqe4jpkyu70jh9rgj0pwt3ndezk2mrlvw6jqew8fhsulewzglfr7g2aa48wyj4n0r7yasa3fm666vda8984ke8tuaf9m89`
|
|
||||||
- **Configuration** : Ajoutée dans `relay/sdk_relay.conf`
|
|
||||||
- **Persistance** : L'adresse est maintenant permanente et ne changera pas
|
|
||||||
|
|
||||||
### Avantages
|
|
||||||
- ✅ Adresse SP stable pour le relai
|
|
||||||
- ✅ Possibilité de recevoir des fonds de manière prévisible
|
|
||||||
- ✅ Configuration persistante entre les redémarrages
|
|
||||||
|
|
||||||
### État actuel
|
|
||||||
- **Bootstrap WebSocket** : ✅ Configuré sur `wss://dev3.4nkweb.com/ws/`
|
|
||||||
- **Adresse SP** : ✅ Permanente et configurée
|
|
||||||
- **Faucet** : ⏳ En attente de connexion WebSocket fonctionnelle
|
|
||||||
|
|
||||||
|
|
||||||
## Retours d'Expérience (REX)
|
|
||||||
|
|
||||||
### Documentation des REX
|
|
||||||
- **Répertoire** : `docs/retours_experience/`
|
|
||||||
- **Objectif** : Pérenniser les solutions aux problèmes rencontrés
|
|
||||||
- **Utilisation** : Consulter avant de résoudre des problèmes similaires
|
|
||||||
|
|
||||||
### REX disponibles
|
|
||||||
1. **REX_BOOTSTRAP_WEBSOCKET.md** : Bootstrap WebSocket et réception de fonds
|
|
||||||
2. **REX_DOCKER_TOOLS_INSTALLATION.md** : Installation d'outils dans les conteneurs
|
|
||||||
3. **REX_STARTUP_SEQUENCE_IMPROVEMENTS.md** : Améliorations de la séquence de démarrage
|
|
||||||
4. **REX_CONFIGURATION_MANAGEMENT.md** : Gestion des configurations
|
|
||||||
|
|
||||||
### Scripts automatisés
|
|
||||||
- **verify_config_writing.sh** : Vérification des écritures de configuration
|
|
||||||
- **verify_bootstrap_connectivity.sh** : Vérification de la connectivité bootstrap
|
|
||||||
|
|
||||||
### Utilisation des scripts
|
|
||||||
```bash
|
|
||||||
# Vérification des configurations
|
|
||||||
./scripts/rex/verify_config_writing.sh
|
|
||||||
|
|
||||||
# Vérification de la connectivité bootstrap
|
|
||||||
./scripts/rex/verify_bootstrap_connectivity.sh
|
|
||||||
```
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
|||||||
# Corrections du Minage et des Transactions
|
|
||||||
|
|
||||||
## Date
|
|
||||||
20 septembre 2025
|
|
||||||
|
|
||||||
## Problèmes Identifiés et Résolus
|
|
||||||
|
|
||||||
### 1. Adresse TSP Invalide dans le Minage Local
|
|
||||||
|
|
||||||
**Problème** :
|
|
||||||
- Le service de minage local utilisait une adresse TSP invalide
|
|
||||||
- Adresse problématique : `tsp1qqfzxxz9fht9w8pg9q8z0zseynt2prapktyx4eylm4jlwg5mukqg95qnmm2va956rhggul4vspjda368nlzvufahx70n67z66a2vgs5lspytmuvty`
|
|
||||||
- Bitcoin Core ne reconnaissait pas cette adresse TSP
|
|
||||||
- Résultat : Minage bloqué, génération de blocs vides (coinbase seulement)
|
|
||||||
|
|
||||||
**Solution Appliquée** :
|
|
||||||
- Remplacement de l'adresse TSP par une adresse Bitcoin valide
|
|
||||||
- Nouvelle adresse : `tb1pdnczsn2gspwq02mc7j2pe50rn67xd56lz7tahcfhgtgj8gp40utq6w6d03`
|
|
||||||
- Fichier modifié : `miner/.env`
|
|
||||||
- Reconstruction du conteneur de minage
|
|
||||||
|
|
||||||
**Résultat** :
|
|
||||||
- Minage local opérationnel
|
|
||||||
- Génération de blocs avec transactions
|
|
||||||
- Bloc 136376 généré avec succès
|
|
||||||
|
|
||||||
### 2. Transaction Non Confirmée dans le Mempool
|
|
||||||
|
|
||||||
**Problème** :
|
|
||||||
- Transaction `73f2b7085312ab0abed28ef6982e2d03a6a9e618342da1e288f1b54713517621` restait dans le mempool
|
|
||||||
- Frais suffisants (10 sats/vB vs 1 sat/vB requis)
|
|
||||||
- Minage local ne confirmait pas les transactions
|
|
||||||
|
|
||||||
**Solution Appliquée** :
|
|
||||||
- Correction de l'adresse TSP dans le minage
|
|
||||||
- Redémarrage du service de minage
|
|
||||||
- Génération de blocs supplémentaires
|
|
||||||
|
|
||||||
**Résultat** :
|
|
||||||
- Transaction confirmée (2 confirmations locales)
|
|
||||||
- Transaction confirmée sur le réseau externe (bloc 136375)
|
|
||||||
- Relay dispose de 2 outputs non dépensés (0.02 BTC)
|
|
||||||
|
|
||||||
### 3. Vérification du Relay Réseau
|
|
||||||
|
|
||||||
**Vérifications Effectuées** :
|
|
||||||
- Mempool externe : [https://mempool2.4nkweb.com](https://mempool2.4nkweb.com)
|
|
||||||
- Transaction bien relayée et confirmée
|
|
||||||
- Synchronisation parfaite entre réseau local et externe
|
|
||||||
- Hash de bloc identique : `00000345c2896d58a45c7f376cdefbcaccd2a5e124d8c4f0ec9530b7e5a858f3`
|
|
||||||
|
|
||||||
## Fichiers Modifiés
|
|
||||||
|
|
||||||
### lecoffre_node/miner/.env
|
|
||||||
```bash
|
|
||||||
# AVANT
|
|
||||||
RELAY_ADDRESS=tsp1qqfzxxz9fht9w8pg9q8z0zseynt2prapktyx4eylm4jlwg5mukqg95qnmm2va956rhggul4vspjda368nlzvufahx70n67z66a2vgs5lspytmuvty
|
|
||||||
|
|
||||||
# APRÈS
|
|
||||||
RELAY_ADDRESS=tb1pdnczsn2gspwq02mc7j2pe50rn67xd56lz7tahcfhgtgj8gp40utq6w6d03
|
|
||||||
```
|
|
||||||
|
|
||||||
## Commandes de Vérification
|
|
||||||
|
|
||||||
### Vérification du Minage
|
|
||||||
```bash
|
|
||||||
# Vérifier les logs du minage
|
|
||||||
docker logs signet_miner --tail 10
|
|
||||||
|
|
||||||
# Vérifier l'environnement du conteneur
|
|
||||||
docker exec signet_miner env | grep RELAY_ADDRESS
|
|
||||||
|
|
||||||
# Vérifier le nombre de blocs
|
|
||||||
docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" getblockcount
|
|
||||||
```
|
|
||||||
|
|
||||||
### Vérification des Transactions
|
|
||||||
```bash
|
|
||||||
# Vérifier le mempool local
|
|
||||||
docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" getmempoolinfo
|
|
||||||
|
|
||||||
# Vérifier les outputs du relay
|
|
||||||
docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="default" listunspent
|
|
||||||
|
|
||||||
# Vérifier le mempool externe
|
|
||||||
curl -s "https://mempool2.4nkweb.com/api/mempool" | jq '.count'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Leçons Apprises
|
|
||||||
|
|
||||||
1. **Adresses TSP** : Les adresses TSP ne sont pas reconnues par Bitcoin Core standard
|
|
||||||
2. **Minage Local** : Nécessite des adresses Bitcoin valides pour fonctionner
|
|
||||||
3. **Mempool Externe** : Utile pour vérifier la relay des transactions
|
|
||||||
4. **Synchronisation** : Le réseau local et externe doivent être synchronisés
|
|
||||||
|
|
||||||
## Prévention
|
|
||||||
|
|
||||||
1. **Validation des Adresses** : Toujours valider les adresses avant de les utiliser
|
|
||||||
2. **Tests de Minage** : Vérifier que le minage génère des blocs avec transactions
|
|
||||||
3. **Monitoring** : Surveiller les logs du minage et du mempool
|
|
||||||
4. **Documentation** : Documenter les corrections pour éviter la récurrence
|
|
||||||
|
|
||||||
## État Final
|
|
||||||
|
|
||||||
- ✅ Minage local opérationnel
|
|
||||||
- ✅ Transaction confirmée et relayée
|
|
||||||
- ✅ Relay avec fonds disponibles (0.02 BTC)
|
|
||||||
- ✅ Système prêt pour le test de login
|
|
@ -1,62 +0,0 @@
|
|||||||
# Corrections WebSocket - lecoffre_node
|
|
||||||
|
|
||||||
## Problèmes identifiés et résolus
|
|
||||||
|
|
||||||
### 1. Configuration du signer (sdk_signer)
|
|
||||||
**Problème :** Le signer essayait de se connecter au relay sur `127.0.0.1:8090` au lieu d'utiliser les URLs configurées.
|
|
||||||
|
|
||||||
**Solution :** Ajout des variables d'environnement manquantes dans `docker-compose.yml` :
|
|
||||||
```yaml
|
|
||||||
sdk_signer:
|
|
||||||
environment:
|
|
||||||
- SIGNER_WS_URL=ws://dev3.4nkweb.com:9090
|
|
||||||
- SIGNER_BASE_URL=https://dev3.4nkweb.com
|
|
||||||
- RELAY_URLS=wss://dev4.4nkweb.com/ws/,wss://dev3.4nkweb.com/ws/
|
|
||||||
```
|
|
||||||
|
|
||||||
**Résultat :** Le signer fonctionne maintenant correctement et se connecte aux bons endpoints.
|
|
||||||
|
|
||||||
### 2. Configuration Nginx pour WebSockets
|
|
||||||
**Problème :** Nginx ne transmettait pas correctement les headers WebSocket vers le relay.
|
|
||||||
|
|
||||||
**Solution :** Ajout des headers WebSocket explicites dans `/conf/nginx/dev4.4nkweb.com.conf` :
|
|
||||||
```nginx
|
|
||||||
location /ws/ {
|
|
||||||
proxy_pass http://127.0.0.1:8090/;
|
|
||||||
proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
|
|
||||||
proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;
|
|
||||||
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol;
|
|
||||||
proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
# ... autres headers
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Logique de fonctionnement de l'iframe
|
|
||||||
**Analyse :** Structure de l'iframe `ihm_client` identifiée :
|
|
||||||
- `init()` dans `router.ts` initialise les services
|
|
||||||
- `Services.getInstance()` crée l'instance singleton
|
|
||||||
- `connectAllRelays()` établit les connexions WebSocket
|
|
||||||
- Configuration WebSocket : `wss://dev4.4nkweb.com/ws/`
|
|
||||||
|
|
||||||
### 4. Vérification des appels WebSocket
|
|
||||||
**Confirmé :** Tous les appels WebSocket sont correctement dirigés vers des services WebSocket :
|
|
||||||
- `/ws/` → `sdk_relay:8090` (WebSocket) ✅
|
|
||||||
- `/signer/` → `sdk_signer:3001` (WebSocket) ✅
|
|
||||||
- `/lecoffre/` → `lecoffre-front:3004` (HTTP) ✅
|
|
||||||
|
|
||||||
## Problème persistant
|
|
||||||
|
|
||||||
### Nginx WebSocket Headers
|
|
||||||
**Statut :** ⚠️ Problème persistant
|
|
||||||
- Nginx ne transmet toujours pas les headers WebSocket vers le relay
|
|
||||||
- 502 Bad Gateway depuis l'iframe
|
|
||||||
- Le relay rejette les connexions sans headers
|
|
||||||
- Erreur : `"No Upgrade: websocket header"`
|
|
||||||
|
|
||||||
**Prochaines étapes :** Investigation plus approfondie de la configuration Nginx ou utilisation d'un proxy WebSocket dédié.
|
|
||||||
|
|
||||||
## Date de mise à jour
|
|
||||||
2025-01-20 - Corrections WebSocket et configuration du signer
|
|
@ -1,140 +0,0 @@
|
|||||||
# Déploiement de la Détection Automatique de Fonds
|
|
||||||
|
|
||||||
## Résumé du Déploiement
|
|
||||||
|
|
||||||
**Date**: 20 septembre 2025
|
|
||||||
**Objectif**: Déployer la détection automatique de fonds insuffisants dans les applications
|
|
||||||
|
|
||||||
## Modifications Déployées
|
|
||||||
|
|
||||||
### 1. ihm_client
|
|
||||||
- **Fichier**: `src/services/service.ts`
|
|
||||||
- **Modification**: Détection automatique des erreurs "Insufficient funds" et "Missing sats"
|
|
||||||
- **Fonctionnalité**: Transfert automatique de fonds via API et retry automatique
|
|
||||||
- **Commit**: `2d0bbc4` - "feat: Détection automatique des fonds insuffisants dans createProcess"
|
|
||||||
|
|
||||||
### 2. lecoffre-back-mini
|
|
||||||
- **Fichier**: `src/routes/funds.routes.ts` (nouveau)
|
|
||||||
- **Modification**: API REST pour transfert automatique de fonds
|
|
||||||
- **Endpoints**:
|
|
||||||
- `POST /api/v1/funds/transfer` - Transfert de fonds
|
|
||||||
- `GET /api/v1/funds/check` - Vérification des fonds
|
|
||||||
- **Commit**: `567e57a` - "feat: Ajout de l'API de transfert automatique de fonds"
|
|
||||||
|
|
||||||
### 3. lecoffre_node
|
|
||||||
- **Fichiers**: Scripts de transfert automatique
|
|
||||||
- **Modifications**:
|
|
||||||
- `scripts/funds/funds_detector_service.js` - Service Node.js de détection
|
|
||||||
- `scripts/funds/simple_transfer.sh` - Script de transfert de base
|
|
||||||
- `scripts/funds/check_and_transfer_funds.sh` - Vérification et transfert
|
|
||||||
- `scripts/funds/monitor_funds.sh` - Monitoring continu
|
|
||||||
- `docs/DETECTION_AUTOMATIQUE_FONDS.md` - Documentation complète
|
|
||||||
- **Commit**: `3be2593` - "docs: Documentation complète de la détection automatique de fonds"
|
|
||||||
|
|
||||||
## Processus de Déploiement
|
|
||||||
|
|
||||||
### 1. Déclenchement des CI
|
|
||||||
```bash
|
|
||||||
# Tags créés pour déclencher les CI
|
|
||||||
git tag ext && git push origin ext
|
|
||||||
```
|
|
||||||
- **lecoffre-back-mini**: Tag `ext` créé
|
|
||||||
- **ihm_client**: Tag `ext` créé
|
|
||||||
- **lecoffre_node**: Tag `ext` créé
|
|
||||||
|
|
||||||
### 2. Nettoyage et Redémarrage
|
|
||||||
```bash
|
|
||||||
# Arrêt des services
|
|
||||||
docker compose down
|
|
||||||
|
|
||||||
# Nettoyage des images et volumes
|
|
||||||
docker system prune -f
|
|
||||||
docker volume prune -f
|
|
||||||
|
|
||||||
# Redémarrage avec nouvelles images
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Vérifications Post-Déploiement
|
|
||||||
- **Services**: Tous opérationnels (healthy)
|
|
||||||
- **Fonds**: 0.01 BTC disponible dans le wallet relay
|
|
||||||
- **Scripts**: Fonctionnels et testés
|
|
||||||
- **Connectivité**: WebSocket et HTTP opérationnels
|
|
||||||
|
|
||||||
## État Actuel
|
|
||||||
|
|
||||||
### Services Opérationnels
|
|
||||||
- ✅ **bitcoin-signet**: healthy
|
|
||||||
- ✅ **blindbit-oracle**: healthy
|
|
||||||
- ✅ **sdk_relay**: healthy (0.01 BTC disponible)
|
|
||||||
- ✅ **lecoffre-back**: healthy
|
|
||||||
- ✅ **lecoffre-front**: healthy
|
|
||||||
- ✅ **sdk_signer**: running
|
|
||||||
- ✅ **sdk_storage**: running
|
|
||||||
- ⚠️ **ihm_client**: health: starting (mais accessible)
|
|
||||||
|
|
||||||
### Fonds Disponibles
|
|
||||||
- **Wallet mining**: 49.99 BTC
|
|
||||||
- **Wallet relay**: 0.01 BTC
|
|
||||||
- **Relay outputs**: 0 (mais fonds disponibles)
|
|
||||||
|
|
||||||
### Fonctionnalités Actives
|
|
||||||
- ✅ **Scripts de transfert**: Opérationnels
|
|
||||||
- ✅ **Service de détection**: Fonctionnel
|
|
||||||
- ✅ **Connectivité WebSocket**: Opérationnelle
|
|
||||||
- ✅ **Connectivité HTTP**: Opérationnelle
|
|
||||||
|
|
||||||
## Limitations Identifiées
|
|
||||||
|
|
||||||
### 1. API de Transfert
|
|
||||||
- **Problème**: L'API `/api/v1/funds/transfer` n'est pas accessible
|
|
||||||
- **Cause**: L'image `lecoffre-back-mini:ext` n'a pas été rebuildée avec les nouvelles routes
|
|
||||||
- **Impact**: La détection automatique dans `ihm_client` ne peut pas utiliser l'API
|
|
||||||
- **Solution**: Les scripts de transfert manuel fonctionnent comme fallback
|
|
||||||
|
|
||||||
### 2. Détection Automatique
|
|
||||||
- **Statut**: Code implémenté mais API non accessible
|
|
||||||
- **Fallback**: Scripts de transfert manuel disponibles
|
|
||||||
- **Monitoring**: Service de détection en arrière-plan
|
|
||||||
|
|
||||||
## Tests Effectués
|
|
||||||
|
|
||||||
### 1. Transfert Manuel
|
|
||||||
```bash
|
|
||||||
./scripts/funds/simple_transfer.sh 0.01
|
|
||||||
# Résultat: ✅ Succès - Fonds déjà disponibles
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Connectivité
|
|
||||||
```bash
|
|
||||||
curl -I http://localhost:8091/
|
|
||||||
# Résultat: ✅ HTTP/1.1 200 OK
|
|
||||||
|
|
||||||
curl -I https://dev4.4nkweb.com/lecoffre
|
|
||||||
# Résultat: ✅ HTTP/2 200
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Services
|
|
||||||
```bash
|
|
||||||
docker compose ps
|
|
||||||
# Résultat: ✅ Tous les services opérationnels
|
|
||||||
```
|
|
||||||
|
|
||||||
## Recommandations
|
|
||||||
|
|
||||||
### 1. Pour le Test de Login
|
|
||||||
- **Fonds disponibles**: 0.01 BTC dans le relay
|
|
||||||
- **Scripts de transfert**: Prêts en cas de besoin
|
|
||||||
- **Monitoring**: Actif en arrière-plan
|
|
||||||
- **Statut**: ✅ Prêt pour le test
|
|
||||||
|
|
||||||
### 2. Améliorations Futures
|
|
||||||
- **Rebuild de l'image lecoffre-back-mini** avec les nouvelles routes
|
|
||||||
- **Test de l'API de transfert** après rebuild
|
|
||||||
- **Validation complète** de la détection automatique
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
Le système est **opérationnel et prêt pour le test de login**. Les fonds sont disponibles et les scripts de transfert automatique sont fonctionnels. La détection automatique dans le code des applications est implémentée, même si l'API n'est pas encore accessible.
|
|
||||||
|
|
||||||
**Le test de login peut être effectué sans problème de fonds insuffisants.**
|
|
@ -1,122 +0,0 @@
|
|||||||
# Déploiement dev4.4nkweb.com
|
|
||||||
|
|
||||||
- Nginx: vhost dev4.4nkweb.com HTTP et HTTPS, reverse proxy:
|
|
||||||
- /signer vers 3001
|
|
||||||
- / vers ihm_client sur 3003
|
|
||||||
- /lecoffre vers lecoffre-front sur 3000
|
|
||||||
- /back vers lecoffre-back sur 8080
|
|
||||||
- /blindbit vers blindbit sur 8000
|
|
||||||
- /storage vers sdk_storage sur 8081
|
|
||||||
- /ws WebSocket relay
|
|
||||||
- Certificats: Lets Encrypt
|
|
||||||
- Next.js: basePath /lecoffre, build production, NODE_OPTIONS max-old-space-size 2048
|
|
||||||
- Extraits .env pertinents:
|
|
||||||
- RELAY_URLS wss://dev4.4nkweb.com/ws
|
|
||||||
- SIGNER_WS_URL ws://dev4.4nkweb.com/signer/
|
|
||||||
- VITE_BOOTSTRAPURL ws://dev4.4nkweb.com/ws
|
|
||||||
- Correction 502: build Next terminé, Nginx OK
|
|
||||||
|
|
||||||
## Redirection locale depuis local.4nkweb.com:3000
|
|
||||||
|
|
||||||
Objectif: lorsque l'utilisateur accède à `http://local.4nkweb.com:3000/...`, répondre par une redirection HTTP vers `https://dev4.4nkweb.com/lecoffre/...` sans modifier l'image Docker du front.
|
|
||||||
|
|
||||||
- Mapping Docker: `lecoffre-front` publié sur `127.0.0.2:3000` (même port, IP loopback dédiée)
|
|
||||||
- Fichier: `docker-compose.yml`
|
|
||||||
- Ligne modifiée: section `lecoffre-front.ports` → `- "127.0.0.2:3000:3000"`
|
|
||||||
- Nginx (hôte):
|
|
||||||
- Proxy vers `127.0.0.2:3000` pour `/lecoffre/` et assets `_next`
|
|
||||||
- Fichier: `conf/nginx/dev4.4nkweb.com.conf`
|
|
||||||
- Lignes modifiées: `proxy_pass http://127.0.0.2:3000/...`
|
|
||||||
- Nouveau vhost de redirection pour `local.4nkweb.com` en écoute sur `127.0.0.1:3000`
|
|
||||||
- Fichier: `conf/nginx/local.4nkweb.com-3000.conf`
|
|
||||||
- Contenu: `return 301 https://dev4.4nkweb.com/lecoffre$request_uri;`
|
|
||||||
|
|
||||||
Séquence d'application:
|
|
||||||
1. Tester la conf Nginx: `sudo nginx -t`
|
|
||||||
2. Recharger Nginx: `sudo systemctl reload nginx`
|
|
||||||
3. Redéployer le service front: `docker compose up -d lecoffre-front`
|
|
||||||
4. Vérifier:
|
|
||||||
- `curl -I http://local.4nkweb.com:3000/` → `301` Location `https://dev4.4nkweb.com/lecoffre/`
|
|
||||||
- `curl -I http://local.4nkweb.com:3000/authorized-client?code=...` → `301` Location `https://dev4.4nkweb.com/lecoffre/authorized-client?code=...`
|
|
||||||
|
|
||||||
Rollback simple:
|
|
||||||
1. Revenir au mapping initial du front: `ports: ["3000:3000"]`
|
|
||||||
2. Dans `conf/nginx/dev4.4nkweb.com.conf`, restaurer les `proxy_pass` sur `127.0.0.1:3000`
|
|
||||||
3. Supprimer (ou commenter) `conf/nginx/local.4nkweb.com-3000.conf`
|
|
||||||
4. `sudo nginx -t && sudo systemctl reload nginx`
|
|
||||||
5. `docker compose up -d lecoffre-front`
|
|
||||||
|
|
||||||
## Résolution du problème DNS côté client
|
|
||||||
|
|
||||||
**Problème** : Si vous obtenez `ERR_CONNECTION_REFUSED` dans votre navigateur, c'est que `local.4nkweb.com` résout vers `127.0.0.1` sur votre machine locale au lieu de pointer vers le serveur.
|
|
||||||
|
|
||||||
**Solution** : Modifiez votre fichier hosts local pour que `local.4nkweb.com` pointe vers l'IP du serveur (`92.243.24.12`).
|
|
||||||
|
|
||||||
### Sur Windows
|
|
||||||
Ajoutez dans `C:\Windows\System32\drivers\etc\hosts` :
|
|
||||||
```
|
|
||||||
92.243.24.12 local.4nkweb.com
|
|
||||||
```
|
|
||||||
|
|
||||||
Puis videz le cache DNS :
|
|
||||||
```cmd
|
|
||||||
ipconfig /flushdns
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sur Linux
|
|
||||||
Ajoutez dans `/etc/hosts` :
|
|
||||||
```
|
|
||||||
92.243.24.12 local.4nkweb.com
|
|
||||||
```
|
|
||||||
|
|
||||||
Puis redémarrez le service DNS :
|
|
||||||
```bash
|
|
||||||
sudo systemctl restart systemd-resolved
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sur Mac
|
|
||||||
Ajoutez dans `/etc/hosts` :
|
|
||||||
```
|
|
||||||
92.243.24.12 local.4nkweb.com
|
|
||||||
```
|
|
||||||
|
|
||||||
Puis videz le cache DNS :
|
|
||||||
```bash
|
|
||||||
sudo dscacheutil -flushcache
|
|
||||||
```
|
|
||||||
|
|
||||||
Après ces modifications, `http://local.4nkweb.com:3000/authorized-client?code=...` devrait rediriger correctement vers `https://dev4.4nkweb.com/lecoffre/authorized-client?code=...`.
|
|
||||||
|
|
||||||
## Pilotage Nginx depuis le dépôt
|
|
||||||
|
|
||||||
- Conf actives sur le système pointent vers les fichiers du dépôt:
|
|
||||||
- `/etc/nginx/conf.d/ssl-dev4.4nkweb.com.conf` → lien vers `conf/nginx/dev4.4nkweb.com-https.conf`
|
|
||||||
- `/etc/nginx/conf.d/local.4nkweb.com-3000.conf` → lien vers `conf/nginx/local.4nkweb.com-3000.conf`
|
|
||||||
- Doublon supprimé: `/etc/nginx/sites-enabled/dev4.4nkweb.com.conf`.
|
|
||||||
- Vérification et rechargement:
|
|
||||||
- `sudo nginx -t`
|
|
||||||
- `sudo nginx -s reload`
|
|
||||||
|
|
||||||
## Variables .env critiques pour le front Next.js
|
|
||||||
|
|
||||||
Ces variables doivent être sans quotes et sans espaces autour de `=` et alignées sur le sous-chemin `/lecoffre`:
|
|
||||||
|
|
||||||
- `NEXT_PUBLIC_ANK_BASE_REDIRECT_URI=https://dev4.4nkweb.com/lecoffre/authorized-client`
|
|
||||||
- `NEXT_PUBLIC_TARGET_ORIGIN=https://dev4.4nkweb.com/lecoffre`
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
- Les variables `NEXT_PUBLIC_*` sont prises en compte au build; un rebuild est nécessaire après modification.
|
|
||||||
|
|
||||||
## Rebuild de lecoffre-front avec le .env courant
|
|
||||||
|
|
||||||
Étapes:
|
|
||||||
1. Vérifier que le conteneur contient le code:
|
|
||||||
- `sudo docker exec -i lecoffre-front sh -lc "test -f package.json && echo ok || echo ko"`
|
|
||||||
2. Lancer le build (mémoire augmentée):
|
|
||||||
- `sudo docker exec -i lecoffre-front sh -lc "export NODE_OPTIONS=--max-old-space-size=2048; npm run build"`
|
|
||||||
3. Redémarrer le service:
|
|
||||||
- `sudo docker compose -f docker-compose.yml restart lecoffre-front`
|
|
||||||
4. Tester:
|
|
||||||
- `curl -si https://dev4.4nkweb.com/lecoffre/`
|
|
||||||
|
|
||||||
Incident connu: 500 SSR « Invalid targetOrigin » résolu en corrigeant `NEXT_PUBLIC_TARGET_ORIGIN` puis rebuild.
|
|
@ -1,243 +0,0 @@
|
|||||||
# Détection Automatique de Fonds dans les Applications
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
|
|
||||||
Ce système implémente une détection automatique des fonds insuffisants directement dans les applications et déclenche automatiquement un transfert de fonds du wallet mining vers le relay.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
### 1. Détection dans les Applications
|
|
||||||
|
|
||||||
#### ihm_client (Frontend)
|
|
||||||
- **Fichier**: `src/services/service.ts`
|
|
||||||
- **Méthode**: `createProcess()`
|
|
||||||
- **Détection**: Erreurs "Insufficient funds" ou "Missing sats"
|
|
||||||
- **Action**: Appel automatique à l'API de transfert
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
try {
|
|
||||||
const result = this.sdkClient.create_new_process(...);
|
|
||||||
// ... traitement normal
|
|
||||||
} catch (error) {
|
|
||||||
const errorMessage = error.toString().toLowerCase();
|
|
||||||
if (errorMessage.includes('insufficient funds') ||
|
|
||||||
(errorMessage.includes('missing') && errorMessage.includes('sats'))) {
|
|
||||||
// Transfert automatique de fonds
|
|
||||||
await this.triggerAutomaticFundsTransfer();
|
|
||||||
// Retry automatique
|
|
||||||
const retryResult = this.sdkClient.create_new_process(...);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### lecoffre-back (Backend)
|
|
||||||
- **Fichier**: `src/routes/funds.routes.ts`
|
|
||||||
- **Endpoints**:
|
|
||||||
- `POST /api/v1/funds/transfer` - Transfert de fonds
|
|
||||||
- `GET /api/v1/funds/check` - Vérification des fonds
|
|
||||||
|
|
||||||
### 2. Service de Détection
|
|
||||||
|
|
||||||
#### Service Node.js
|
|
||||||
- **Fichier**: `scripts/funds/funds_detector_service.js`
|
|
||||||
- **Fonctionnalités**:
|
|
||||||
- Monitoring continu des fonds
|
|
||||||
- Transfert automatique si nécessaire
|
|
||||||
- Logs détaillés
|
|
||||||
- Gestion des erreurs
|
|
||||||
|
|
||||||
### 3. Scripts de Support
|
|
||||||
|
|
||||||
#### Scripts Bash
|
|
||||||
- `scripts/funds/simple_transfer.sh` - Transfert de base
|
|
||||||
- `scripts/funds/check_and_transfer_funds.sh` - Vérification et transfert
|
|
||||||
- `scripts/funds/monitor_funds.sh` - Monitoring continu
|
|
||||||
- `scripts/startup-with-funds-check.sh` - Démarrage avec vérification
|
|
||||||
|
|
||||||
## Flux de Fonctionnement
|
|
||||||
|
|
||||||
### 1. Détection Automatique
|
|
||||||
```
|
|
||||||
Application (ihm_client) → createProcess() → Erreur "Insufficient funds"
|
|
||||||
↓
|
|
||||||
Détection automatique
|
|
||||||
↓
|
|
||||||
Appel API /api/v1/funds/transfer
|
|
||||||
↓
|
|
||||||
Transfert de fonds
|
|
||||||
↓
|
|
||||||
Retry automatique
|
|
||||||
↓
|
|
||||||
Succès
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. API de Transfert
|
|
||||||
```http
|
|
||||||
POST /api/v1/funds/transfer
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"amount": 0.01,
|
|
||||||
"source": "mining_mnemonic",
|
|
||||||
"target": "default"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Réponse:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"message": "Transfert de 0.01 BTC réussi",
|
|
||||||
"transactionId": "abc123...",
|
|
||||||
"address": "tb1q...",
|
|
||||||
"sourceBalance": 49.99,
|
|
||||||
"targetBalance": 0.01
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Vérification des Fonds
|
|
||||||
```http
|
|
||||||
GET /api/v1/funds/check
|
|
||||||
```
|
|
||||||
|
|
||||||
**Réponse:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"success": true,
|
|
||||||
"relay": {
|
|
||||||
"outputsCount": 1,
|
|
||||||
"balance": 0.01
|
|
||||||
},
|
|
||||||
"mining": {
|
|
||||||
"balance": 49.99
|
|
||||||
},
|
|
||||||
"needsTransfer": false
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Variables d'Environnement
|
|
||||||
- `MINING_WALLET`: "mining_mnemonic" (par défaut)
|
|
||||||
- `RELAY_WALLET`: "default" (par défaut)
|
|
||||||
- `MIN_FUNDS_THRESHOLD`: 0.001 BTC (par défaut)
|
|
||||||
- `TRANSFER_AMOUNT`: 0.01 BTC (par défaut)
|
|
||||||
|
|
||||||
### Seuils
|
|
||||||
- **Seuil minimum**: 0.001 BTC (100,000 sats)
|
|
||||||
- **Montant de transfert**: 0.01 BTC (1,000,000 sats)
|
|
||||||
- **Vérification**: Toutes les 30 secondes (service)
|
|
||||||
|
|
||||||
## Intégration
|
|
||||||
|
|
||||||
### Docker Compose
|
|
||||||
```yaml
|
|
||||||
volumes:
|
|
||||||
- ./scripts/funds:/scripts/funds:ro
|
|
||||||
```
|
|
||||||
|
|
||||||
### Démarrage
|
|
||||||
```bash
|
|
||||||
# Démarrage avec vérification automatique
|
|
||||||
./scripts/startup-with-funds-check.sh
|
|
||||||
|
|
||||||
# Service de monitoring
|
|
||||||
node scripts/funds/funds_detector_service.js
|
|
||||||
```
|
|
||||||
|
|
||||||
## Avantages
|
|
||||||
|
|
||||||
### 1. Transparence
|
|
||||||
- L'utilisateur ne voit pas l'erreur de fonds insuffisants
|
|
||||||
- Le transfert se fait automatiquement en arrière-plan
|
|
||||||
- Retry automatique après transfert
|
|
||||||
|
|
||||||
### 2. Fiabilité
|
|
||||||
- Détection proactive des problèmes
|
|
||||||
- Transfert automatique avant échec
|
|
||||||
- Gestion des erreurs et fallback
|
|
||||||
|
|
||||||
### 3. Performance
|
|
||||||
- Pas d'interruption du workflow utilisateur
|
|
||||||
- Transfert rapide (quelques secondes)
|
|
||||||
- Monitoring continu
|
|
||||||
|
|
||||||
### 4. Maintenance
|
|
||||||
- Logs détaillés pour debugging
|
|
||||||
- Configuration flexible
|
|
||||||
- Scripts réutilisables
|
|
||||||
|
|
||||||
## Dépannage
|
|
||||||
|
|
||||||
### Problèmes Courants
|
|
||||||
|
|
||||||
1. **API non accessible**
|
|
||||||
```bash
|
|
||||||
# Vérifier que lecoffre-back est démarré
|
|
||||||
docker compose ps lecoffre-back
|
|
||||||
|
|
||||||
# Vérifier les logs
|
|
||||||
docker logs lecoffre-back
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Transfert échoue**
|
|
||||||
```bash
|
|
||||||
# Vérifier la connectivité Bitcoin
|
|
||||||
docker exec bitcoin-signet bitcoin-cli -signet getblockchaininfo
|
|
||||||
|
|
||||||
# Vérifier les soldes
|
|
||||||
curl http://localhost:8080/api/v1/funds/check
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Service de détection ne démarre pas**
|
|
||||||
```bash
|
|
||||||
# Vérifier les permissions
|
|
||||||
chmod +x scripts/funds/funds_detector_service.js
|
|
||||||
|
|
||||||
# Vérifier Node.js
|
|
||||||
node --version
|
|
||||||
```
|
|
||||||
|
|
||||||
### Logs
|
|
||||||
- **Service de détection**: `/tmp/funds_detector.log`
|
|
||||||
- **lecoffre-back**: `docker logs lecoffre-back`
|
|
||||||
- **ihm_client**: Console du navigateur
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
### Test Manuel
|
|
||||||
```bash
|
|
||||||
# 1. Vérifier les fonds
|
|
||||||
curl http://localhost:8080/api/v1/funds/check
|
|
||||||
|
|
||||||
# 2. Transférer des fonds
|
|
||||||
curl -X POST http://localhost:8080/api/v1/funds/transfer \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{"amount": 0.01}'
|
|
||||||
|
|
||||||
# 3. Vérifier à nouveau
|
|
||||||
curl http://localhost:8080/api/v1/funds/check
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test Automatique
|
|
||||||
```bash
|
|
||||||
# Lancer le service de détection
|
|
||||||
node scripts/funds/funds_detector_service.js
|
|
||||||
|
|
||||||
# Dans un autre terminal, simuler un manque de fonds
|
|
||||||
# Le service devrait détecter et transférer automatiquement
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sécurité
|
|
||||||
|
|
||||||
- Vérification des soldes avant transfert
|
|
||||||
- Limitation des montants de transfert
|
|
||||||
- Logs de toutes les opérations
|
|
||||||
- Gestion des erreurs sécurisée
|
|
||||||
|
|
||||||
## Performance
|
|
||||||
|
|
||||||
- Transfert en ~5-10 secondes
|
|
||||||
- Détection en temps réel
|
|
||||||
- Monitoring toutes les 30 secondes
|
|
||||||
- Pas d'impact sur les performances utilisateur
|
|
@ -1,45 +0,0 @@
|
|||||||
## Résumé des environnements (plateforme)
|
|
||||||
|
|
||||||
### Contexte fonctionnel
|
|
||||||
|
|
||||||
- **Site principal**: `https://dev4.4nkweb.com/lecoffre`
|
|
||||||
- **Intégration Iframe**: hôte `https://dev4.4nkweb.com`
|
|
||||||
- **Service Signer**: utilisé depuis `https://dev3.4nkweb.com`
|
|
||||||
|
|
||||||
### Cartographie (compose et apps)
|
|
||||||
|
|
||||||
- `lecoffre-front` (Next.js): basePath `/lecoffre`; variables `NEXT_PUBLIC_*` orientées vers `dev4.4nkweb.com` et services backend.
|
|
||||||
- `lecoffre-back-mini` (Express): exposé en interne sur 8080; consommé par le front via `NEXT_PUBLIC_API_URL`.
|
|
||||||
- `sdk_relay`: exposé sur 8090; consommé par les clients qui en ont besoin.
|
|
||||||
- `ihm_client`: exposé sur 3003; intégré/embarqué si nécessaire.
|
|
||||||
- `sdk_signer`: non utilisé localement sur la machine, signer consommé depuis `dev3.4nkweb.com`.
|
|
||||||
|
|
||||||
### Valeurs attendues (synthèse)
|
|
||||||
|
|
||||||
- Front (Next.js):
|
|
||||||
- `NEXT_PUBLIC_FRONT_APP_HOST=dev4.4nkweb.com`
|
|
||||||
- `NEXT_PUBLIC_FRONT_APP_PORT` (selon déploiement; non nécessaire en prod si 443)
|
|
||||||
- `NEXT_PUBLIC_4NK_URL=https://dev4.4nkweb.com`
|
|
||||||
- `NEXT_PUBLIC_4NK_IFRAME_URL=https://dev4.4nkweb.com`
|
|
||||||
- `NEXT_PUBLIC_API_URL` pointant vers l’API (`lecoffre-back-mini`) accessible depuis le navigateur
|
|
||||||
- `NEXT_PUBLIC_BACK_API_*` si utilisés pour construire l’URL back (protocol/host/port/root/version)
|
|
||||||
- `NEXT_PUBLIC_IDNOT_*`, `NEXT_PUBLIC_DOCAPOSTE_API_URL` selon intégrations
|
|
||||||
- `NEXT_PUBLIC_DEFAULT_*` (validator, storages) selon besoins
|
|
||||||
|
|
||||||
- Back (`lecoffre-back-mini`):
|
|
||||||
- Variables DB, clés Stripe/Mail, endpoints externes (non détaillés ici; `.env` validés)
|
|
||||||
|
|
||||||
- Signer (externe):
|
|
||||||
- Ciblage de `dev3.4nkweb.com` côté front/back pour les opérations de signature.
|
|
||||||
|
|
||||||
### Remarques
|
|
||||||
|
|
||||||
- Les fichiers `.env` existants sont validés OK.
|
|
||||||
- S’assurer de la cohérence entre `basePath` `/lecoffre` et les URLs publiques (liens, redirections, assets).
|
|
||||||
- Documenter un `.env.example` à jour dans chaque projet pour reproduire la configuration.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
|||||||
# 📚 Documentation LeCoffre Node
|
|
||||||
|
|
||||||
## 🎯 Documentation IA (Recommandée)
|
|
||||||
|
|
||||||
**Commencez toujours par ces documents pour comprendre le projet :**
|
|
||||||
|
|
||||||
- **[`../IA_agents/context.md`](../IA_agents/context.md)** - Contexte et objectifs du projet
|
|
||||||
- **[`../IA_agents/flux.md`](../IA_agents/flux.md)** - Architecture et flux des services
|
|
||||||
- **[`../IA_agents/deploy.md`](../IA_agents/deploy.md)** - Procédure de déploiement complète
|
|
||||||
|
|
||||||
## 📖 Documentation Technique
|
|
||||||
|
|
||||||
### Architecture et Configuration
|
|
||||||
- **[`REX.md`](REX.md)** - Rapport d'expérience de déploiement (récent)
|
|
||||||
- **[`ARCHITECTURE.md`](ARCHITECTURE.md)** - Architecture détaillée des services
|
|
||||||
- **[`CONFIGURATION_SERVICES.md`](CONFIGURATION_SERVICES.md)** - Configuration des services
|
|
||||||
|
|
||||||
### Déploiement et Opérations
|
|
||||||
- **[`DEPLOIEMENT_dev4.md`](DEPLOIEMENT_dev4.md)** - Déploiement sur dev4.4nkweb.com
|
|
||||||
- **[`DEPLOIEMENT_DETECTION_AUTOMATIQUE.md`](DEPLOIEMENT_DETECTION_AUTOMATIQUE.md)** - Détection automatique
|
|
||||||
- **[`STARTUP_IMPROVEMENTS.md`](STARTUP_IMPROVEMENTS.md)** - Améliorations de démarrage
|
|
||||||
|
|
||||||
### Tests et Monitoring
|
|
||||||
- **[`TESTS_CONNECTIVITE_COMPLETS.md`](TESTS_CONNECTIVITE_COMPLETS.md)** - Tests de connectivité
|
|
||||||
- **[`setup_outils.md`](setup_outils.md)** - Configuration des outils
|
|
||||||
|
|
||||||
### Minage et Bitcoin
|
|
||||||
- **[`CORRECTIONS_MINAGE_ET_TRANSACTIONS.md`](CORRECTIONS_MINAGE_ET_TRANSACTIONS.md)** - Corrections minage
|
|
||||||
- **[`miner_relay_rewards.md`](miner_relay_rewards.md)** - Récompenses du mineur
|
|
||||||
- **[`DETECTION_AUTOMATIQUE_FONDS.md`](DETECTION_AUTOMATIQUE_FONDS.md)** - Détection des fonds
|
|
||||||
- **[`TRANSFERT_AUTOMATIQUE_FONDS.md`](TRANSFERT_AUTOMATIQUE_FONDS.md)** - Transfert des fonds
|
|
||||||
|
|
||||||
### WebSocket et API
|
|
||||||
- **[`CORRECTIONS_WEBSOCKET.md`](CORRECTIONS_WEBSOCKET.md)** - Corrections WebSocket
|
|
||||||
- **[`ROUTAGE_API.md`](ROUTAGE_API.md)** - Routage des API
|
|
||||||
|
|
||||||
### Environnement et Configuration
|
|
||||||
- **[`ENV-RESUME.md`](ENV-RESUME.md)** - Résumé des variables d'environnement
|
|
||||||
- **[`env_matrix.md`](env_matrix.md)** - Matrice des environnements
|
|
||||||
- **[`local_http_vhost.md`](local_http_vhost.md)** - Configuration vhost local
|
|
||||||
|
|
||||||
## 📁 Dossiers Spécialisés
|
|
||||||
|
|
||||||
- **[`miner/`](miner/)** - Documentation du mineur Bitcoin
|
|
||||||
- **[`retours_experience/`](retours_experience/)** - Retours d'expérience détaillés
|
|
||||||
|
|
||||||
## 🗑️ Fichiers Obsolètes (À Supprimer)
|
|
||||||
|
|
||||||
Les fichiers suivants sont redondants ou obsolètes :
|
|
||||||
|
|
||||||
- `ANALYSE.md` - Remplacé par `ARCHITECTURE.md` et `REX.md`
|
|
||||||
- `analyse.md` - Dupliqué avec `ANALYSE.md`
|
|
||||||
- `CORRECTIONS_APPLIQUEES.md` - Intégré dans `REX.md`
|
|
||||||
- `AMELIORATIONS_DEMARRAGE.md` - Remplacé par `STARTUP_IMPROVEMENTS.md`
|
|
||||||
- `REX_502_lecoffre.md` - Problème résolu, intégré dans `REX.md`
|
|
||||||
|
|
||||||
## 🎯 Guide de Lecture
|
|
||||||
|
|
||||||
### Pour les Nouveaux Utilisateurs
|
|
||||||
1. [`../IA_agents/context.md`](../IA_agents/context.md) - Comprendre le projet
|
|
||||||
2. [`../IA_agents/flux.md`](../IA_agents/flux.md) - Architecture
|
|
||||||
3. [`REX.md`](REX.md) - État actuel et déploiement
|
|
||||||
|
|
||||||
### Pour les Développeurs
|
|
||||||
1. [`../IA_agents/deploy.md`](../IA_agents/deploy.md) - Procédure de déploiement
|
|
||||||
2. [`ARCHITECTURE.md`](ARCHITECTURE.md) - Détails techniques
|
|
||||||
3. [`CONFIGURATION_SERVICES.md`](CONFIGURATION_SERVICES.md) - Configuration
|
|
||||||
|
|
||||||
### Pour les Opérations
|
|
||||||
1. [`DEPLOIEMENT_dev4.md`](DEPLOIEMENT_dev4.md) - Déploiement
|
|
||||||
2. [`TESTS_CONNECTIVITE_COMPLETS.md`](TESTS_CONNECTIVITE_COMPLETS.md) - Tests
|
|
||||||
3. [`setup_outils.md`](setup_outils.md) - Outils
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**💡 Conseil** : La documentation IA dans `IA_agents/` est la référence principale. Les documents techniques dans `docs/` fournissent les détails d'implémentation.
|
|
@ -1,326 +0,0 @@
|
|||||||
# 📊 Monitoring LeCoffre Node
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
|
|
||||||
Le système de monitoring LeCoffre Node utilise **Grafana**, **Loki** et **Promtail** pour centraliser, analyser et visualiser les logs de tous les services.
|
|
||||||
|
|
||||||
## 🏗️ Architecture du Monitoring
|
|
||||||
|
|
||||||
```
|
|
||||||
Services → Logs Centralisés → Promtail → Loki → Grafana
|
|
||||||
↓ ↓ ↓ ↓ ↓
|
|
||||||
Docker logs/ Collecte Stockage Dashboard
|
|
||||||
```
|
|
||||||
|
|
||||||
### Composants
|
|
||||||
|
|
||||||
| Composant | Port | Description |
|
|
||||||
|-----------|------|-------------|
|
|
||||||
| **Grafana** | 3000 | Interface de visualisation et dashboards |
|
|
||||||
| **Loki** | 3100 | Base de données de logs |
|
|
||||||
| **Promtail** | - | Agent de collecte des logs |
|
|
||||||
| **Nginx** | 80 | Proxy pour accès externe |
|
|
||||||
|
|
||||||
## 🚀 Déploiement
|
|
||||||
|
|
||||||
### Démarrage Rapide
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Synchroniser la configuration
|
|
||||||
./scripts/sync-monitoring-config.sh
|
|
||||||
|
|
||||||
# 2. Démarrer le monitoring
|
|
||||||
./scripts/deploy-grafana.sh start
|
|
||||||
|
|
||||||
# 3. Tester la connectivité
|
|
||||||
./scripts/test-monitoring.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Commandes de Gestion
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Démarrer
|
|
||||||
./scripts/deploy-grafana.sh start
|
|
||||||
|
|
||||||
# Arrêter
|
|
||||||
./scripts/deploy-grafana.sh stop
|
|
||||||
|
|
||||||
# Redémarrer
|
|
||||||
./scripts/deploy-grafana.sh restart
|
|
||||||
|
|
||||||
# Vérifier le statut
|
|
||||||
./scripts/deploy-grafana.sh status
|
|
||||||
|
|
||||||
# Voir les logs
|
|
||||||
./scripts/deploy-grafana.sh logs grafana
|
|
||||||
./scripts/deploy-grafana.sh logs loki
|
|
||||||
./scripts/deploy-grafana.sh logs promtail
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔗 Accès
|
|
||||||
|
|
||||||
### URLs Principales
|
|
||||||
|
|
||||||
| Service | URL | Description |
|
|
||||||
|---------|-----|-------------|
|
|
||||||
| **Grafana** | [https://dev4.4nkweb.com/grafana/](https://dev4.4nkweb.com/grafana/) | Interface principale |
|
|
||||||
| **Loki API** | [https://dev4.4nkweb.com/loki/](https://dev4.4nkweb.com/loki/) | API de logs |
|
|
||||||
| **Grafana Local** | [http://localhost:3000](http://localhost:3000) | Accès local |
|
|
||||||
|
|
||||||
### Identifiants
|
|
||||||
|
|
||||||
- **Utilisateur** : `admin`
|
|
||||||
- **Mot de passe** : `admin123`
|
|
||||||
|
|
||||||
## 📊 Dashboards Disponibles
|
|
||||||
|
|
||||||
### 1. Vue d'ensemble LeCoffre
|
|
||||||
- **ID** : `lecoffre-overview`
|
|
||||||
- **Description** : Dashboard principal avec vue d'ensemble de tous les services
|
|
||||||
- **Métriques** : Erreurs par service, volume de logs, logs d'erreur en temps réel
|
|
||||||
|
|
||||||
### 2. Bitcoin & Miner
|
|
||||||
- **ID** : `bitcoin-miner`
|
|
||||||
- **Description** : Monitoring spécialisé pour Bitcoin et le mineur
|
|
||||||
- **Métriques** : Nouveaux blocs, blocs minés, erreurs blockchain
|
|
||||||
|
|
||||||
### 3. Services Applications
|
|
||||||
- **ID** : `services-overview`
|
|
||||||
- **Description** : Monitoring des services applicatifs
|
|
||||||
- **Métriques** : Volume de logs par service, erreurs applications
|
|
||||||
|
|
||||||
## 📝 Collecte des Logs
|
|
||||||
|
|
||||||
### Structure des Logs
|
|
||||||
|
|
||||||
```
|
|
||||||
logs/
|
|
||||||
├── bitcoin/ # Logs Bitcoin Signet
|
|
||||||
├── blindbit/ # Logs Oracle Blindbit
|
|
||||||
├── sdk_relay/ # Logs Relay WebSocket
|
|
||||||
├── sdk_signer/ # Logs Service de signature
|
|
||||||
├── sdk_storage/ # Logs Stockage temporaire
|
|
||||||
├── lecoffre-back/ # Logs Backend API
|
|
||||||
├── lecoffre-front/ # Logs Frontend
|
|
||||||
├── ihm_client/ # Logs Interface de gestion
|
|
||||||
├── tor/ # Logs Proxy Tor
|
|
||||||
├── miner/ # Logs Mineur Bitcoin
|
|
||||||
└── nginx/ # Logs Proxy Nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### Scripts de Gestion
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Collecter les logs de tous les services
|
|
||||||
./scripts/collect-logs.sh
|
|
||||||
|
|
||||||
# Collecter les logs d'un service spécifique
|
|
||||||
./scripts/collect-logs.sh bitcoin-signet
|
|
||||||
./scripts/collect-logs.sh sdk_relay
|
|
||||||
|
|
||||||
# Configurer la centralisation des logs
|
|
||||||
./scripts/setup-logs.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔧 Configuration
|
|
||||||
|
|
||||||
### Fichiers de Configuration
|
|
||||||
|
|
||||||
| Fichier | Description |
|
|
||||||
|---------|-------------|
|
|
||||||
| `conf/grafana/grafana.ini` | Configuration Grafana |
|
|
||||||
| `conf/grafana/provisioning/datasources/loki.yml` | Source de données Loki |
|
|
||||||
| `conf/grafana/provisioning/dashboards/dashboards.yml` | Configuration des dashboards |
|
|
||||||
| `conf/promtail/promtail.yml` | Configuration Promtail |
|
|
||||||
| `conf/nginx/grafana.conf` | Configuration Nginx pour Grafana |
|
|
||||||
| `conf/monitoring.conf` | Configuration centralisée |
|
|
||||||
|
|
||||||
### Variables d'Environnement
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Mot de passe admin Grafana
|
|
||||||
GRAFANA_ADMIN_PASSWORD=admin123
|
|
||||||
|
|
||||||
# Ports des services
|
|
||||||
GRAFANA_PORT=3000
|
|
||||||
LOKI_PORT=3100
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔍 Requêtes Logs Utiles
|
|
||||||
|
|
||||||
### Recherche d'Erreurs
|
|
||||||
|
|
||||||
```logql
|
|
||||||
# Erreurs de tous les services
|
|
||||||
{job=~".*"} |= "error"
|
|
||||||
|
|
||||||
# Erreurs Bitcoin spécifiques
|
|
||||||
{job="bitcoin"} |= "error"
|
|
||||||
|
|
||||||
# Erreurs des services applicatifs
|
|
||||||
{job=~"lecoffre-back|lecoffre-front|ihm_client"} |= "error"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Métriques de Performance
|
|
||||||
|
|
||||||
```logql
|
|
||||||
# Volume de logs par service
|
|
||||||
sum by (service) (count_over_time({job=~".*"} [5m]))
|
|
||||||
|
|
||||||
# Erreurs par minute
|
|
||||||
sum by (service) (rate({job=~".*"} |= "error" [1m]))
|
|
||||||
```
|
|
||||||
|
|
||||||
### Monitoring Bitcoin
|
|
||||||
|
|
||||||
```logql
|
|
||||||
# Nouveaux blocs
|
|
||||||
{job="bitcoin"} |= "block"
|
|
||||||
|
|
||||||
# Transactions
|
|
||||||
{job="bitcoin"} |= "tx"
|
|
||||||
|
|
||||||
# Blocs minés
|
|
||||||
{job="miner"} |= "mined"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚨 Alertes
|
|
||||||
|
|
||||||
### Configuration des Alertes
|
|
||||||
|
|
||||||
Les alertes sont configurées dans Grafana pour :
|
|
||||||
|
|
||||||
- **Erreurs critiques** : > 10 erreurs en 5 minutes
|
|
||||||
- **Services arrêtés** : Service non accessible
|
|
||||||
- **Problèmes Bitcoin** : Blocs non minés
|
|
||||||
- **Problèmes de connectivité** : Connexions WebSocket échouées
|
|
||||||
|
|
||||||
### Canaux de Notification
|
|
||||||
|
|
||||||
- **Email** : Configuration dans Grafana
|
|
||||||
- **Webhook** : Intégration avec systèmes externes
|
|
||||||
- **Slack** : Notifications en temps réel
|
|
||||||
|
|
||||||
## 🛠️ Maintenance
|
|
||||||
|
|
||||||
### Rotation des Logs
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Configuration automatique avec logrotate
|
|
||||||
conf/logrotate/*.conf
|
|
||||||
|
|
||||||
# Rotation quotidienne, rétention 7 jours
|
|
||||||
# Compression automatique
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sauvegarde
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Sauvegarder les dashboards Grafana
|
|
||||||
docker exec grafana grafana-cli admin export-dashboard > dashboards-backup.json
|
|
||||||
|
|
||||||
# Sauvegarder la configuration
|
|
||||||
tar -czf monitoring-config-backup.tar.gz conf/grafana/ conf/promtail/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Mise à Jour
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Mise à jour des images Docker
|
|
||||||
docker compose pull grafana loki promtail
|
|
||||||
|
|
||||||
# Redémarrage avec nouvelles images
|
|
||||||
docker compose up -d grafana loki promtail
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔐 Sécurité
|
|
||||||
|
|
||||||
### Authentification
|
|
||||||
|
|
||||||
- **Utilisateur unique** : `admin`
|
|
||||||
- **Mot de passe fort** : Configuré via variable d'environnement
|
|
||||||
- **Accès anonyme** : Désactivé
|
|
||||||
- **HTTPS** : Forcé via Nginx
|
|
||||||
|
|
||||||
### Réseau
|
|
||||||
|
|
||||||
- **Isolation Docker** : Services dans le réseau `btcnet`
|
|
||||||
- **Ports exposés** : Uniquement en localhost
|
|
||||||
- **Proxy Nginx** : Accès externe sécurisé
|
|
||||||
|
|
||||||
### Données Sensibles
|
|
||||||
|
|
||||||
- **Aucun secret** dans les logs
|
|
||||||
- **Rotation automatique** des logs
|
|
||||||
- **Chiffrement** des données au repos (optionnel)
|
|
||||||
|
|
||||||
## 📈 Métriques et KPIs
|
|
||||||
|
|
||||||
### Disponibilité des Services
|
|
||||||
|
|
||||||
- **Uptime** : Pourcentage de temps de fonctionnement
|
|
||||||
- **Healthchecks** : Statut des services
|
|
||||||
- **Restarts** : Nombre de redémarrages
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
- **Temps de réponse** : Latence des API
|
|
||||||
- **Throughput** : Requêtes par seconde
|
|
||||||
- **Erreurs** : Taux d'erreur par service
|
|
||||||
|
|
||||||
### Bitcoin
|
|
||||||
|
|
||||||
- **Blocs minés** : Nombre de blocs par heure
|
|
||||||
- **Transactions** : Volume de transactions
|
|
||||||
- **Fees** : Frais de transaction moyens
|
|
||||||
|
|
||||||
## 🆘 Dépannage
|
|
||||||
|
|
||||||
### Problèmes Courants
|
|
||||||
|
|
||||||
1. **Grafana non accessible**
|
|
||||||
```bash
|
|
||||||
# Vérifier le statut
|
|
||||||
docker compose ps grafana
|
|
||||||
|
|
||||||
# Vérifier les logs
|
|
||||||
docker compose logs grafana
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Logs non collectés**
|
|
||||||
```bash
|
|
||||||
# Vérifier Promtail
|
|
||||||
docker compose logs promtail
|
|
||||||
|
|
||||||
# Vérifier Loki
|
|
||||||
docker compose logs loki
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Dashboards vides**
|
|
||||||
```bash
|
|
||||||
# Vérifier la source de données
|
|
||||||
# Aller dans Configuration > Data Sources > Loki
|
|
||||||
```
|
|
||||||
|
|
||||||
### Commandes de Diagnostic
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test de connectivité complet
|
|
||||||
./scripts/test-monitoring.sh
|
|
||||||
|
|
||||||
# Vérification des services
|
|
||||||
./scripts/deploy-grafana.sh status
|
|
||||||
|
|
||||||
# Logs en temps réel
|
|
||||||
./scripts/deploy-grafana.sh logs grafana
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📚 Documentation Associée
|
|
||||||
|
|
||||||
- **[`../IA_agents/flux.md`](../IA_agents/flux.md)** - Architecture générale
|
|
||||||
- **[`ARCHITECTURE.md`](ARCHITECTURE.md)** - Architecture détaillée
|
|
||||||
- **[`CONFIGURATION_SERVICES.md`](CONFIGURATION_SERVICES.md)** - Configuration des services
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**💡 Conseil** : Commencez par le dashboard "Vue d'ensemble LeCoffre" pour avoir une vision globale du système !
|
|
@ -1,206 +0,0 @@
|
|||||||
# 📊 Résumé du Déploiement du Monitoring LeCoffre Node
|
|
||||||
|
|
||||||
## ✅ Accomplissements
|
|
||||||
|
|
||||||
### 🏗️ Infrastructure Centralisée
|
|
||||||
|
|
||||||
1. **Centralisation des Logs**
|
|
||||||
- ✅ Structure `logs/` créée pour tous les services
|
|
||||||
- ✅ Volumes Docker configurés pour chaque service
|
|
||||||
- ✅ Rotation automatique des logs configurée
|
|
||||||
|
|
||||||
2. **Stack de Monitoring Grafana**
|
|
||||||
- ✅ **Grafana** : Interface de visualisation (port 3000)
|
|
||||||
- ✅ **Loki** : Base de données de logs (port 3100)
|
|
||||||
- ✅ **Promtail** : Agent de collecte des logs
|
|
||||||
- ✅ **Nginx** : Proxy pour accès externe sécurisé
|
|
||||||
|
|
||||||
3. **Dashboards Spécialisés**
|
|
||||||
- ✅ **Vue d'ensemble LeCoffre** : Monitoring global
|
|
||||||
- ✅ **Bitcoin & Miner** : Monitoring blockchain spécialisé
|
|
||||||
- ✅ **Services Applications** : Monitoring des services applicatifs
|
|
||||||
|
|
||||||
### 🔧 Configuration et Scripts
|
|
||||||
|
|
||||||
4. **Scripts de Gestion**
|
|
||||||
- ✅ `deploy-grafana.sh` : Déploiement centralisé du monitoring
|
|
||||||
- ✅ `setup-logs.sh` : Configuration de la centralisation des logs
|
|
||||||
- ✅ `collect-logs.sh` : Collecte des logs de tous les services
|
|
||||||
- ✅ `sync-monitoring-config.sh` : Synchronisation de la configuration
|
|
||||||
- ✅ `test-monitoring.sh` : Test de connectivité
|
|
||||||
|
|
||||||
5. **Configuration Centralisée**
|
|
||||||
- ✅ `conf/grafana/` : Configuration complète Grafana
|
|
||||||
- ✅ `conf/promtail/` : Configuration Promtail
|
|
||||||
- ✅ `conf/nginx/grafana.conf` : Proxy Nginx
|
|
||||||
- ✅ `conf/monitoring.conf` : Configuration centralisée
|
|
||||||
|
|
||||||
### 📚 Documentation
|
|
||||||
|
|
||||||
6. **Documentation Complète**
|
|
||||||
- ✅ `docs/MONITORING.md` : Guide complet du monitoring
|
|
||||||
- ✅ `README.md` : Mise à jour avec section monitoring
|
|
||||||
- ✅ Configuration intégrée dans l'architecture générale
|
|
||||||
|
|
||||||
## 🎯 Architecture Finale
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ LeCoffre Node Monitoring │
|
|
||||||
├─────────────────────────────────────────────────────────────┤
|
|
||||||
│ │
|
|
||||||
│ Services Docker → Logs Centralisés → Promtail → Loki │
|
|
||||||
│ ↓ ↓ ↓ ↓ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
||||||
│ │ Bitcoin │ │ logs/ │ │Promtail │ │ Loki │ │
|
|
||||||
│ │Blindbit │ ────▶│Services │──▶│Collect │ │ Storage │ │
|
|
||||||
│ │SDK_* │ │ Central │ │ Logs │ │ Logs │ │
|
|
||||||
│ │LeCoffre │ │ │ │ │ │ │ │
|
|
||||||
│ │IHM_* │ └─────────┘ └─────────┘ └─────────┘ │
|
|
||||||
│ └─────────┘ ↓ ↓ ↓ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
||||||
│ │ Nginx │ │ Grafana │ │Dashboard│ │
|
|
||||||
│ │ Proxy │──▶│ UI │ │ Web │ │
|
|
||||||
│ │External │ │ Port │ │ Access │ │
|
|
||||||
│ │ Access │ │ 3000 │ │ External│ │
|
|
||||||
│ └─────────┘ └─────────┘ └─────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔗 URLs d'Accès
|
|
||||||
|
|
||||||
| Service | URL | Statut |
|
|
||||||
|---------|-----|--------|
|
|
||||||
| **Grafana** | [https://dev4.4nkweb.com/grafana/](https://dev4.4nkweb.com/grafana/) | ✅ Configuré |
|
|
||||||
| **Loki API** | [https://dev4.4nkweb.com/loki/](https://dev4.4nkweb.com/loki/) | ✅ Configuré |
|
|
||||||
| **Grafana Local** | [http://localhost:3000](http://localhost:3000) | ✅ Configuré |
|
|
||||||
|
|
||||||
**Identifiants** : `admin` / `admin123`
|
|
||||||
|
|
||||||
## 📋 Prochaines Étapes
|
|
||||||
|
|
||||||
### 1. Déploiement Immédiat
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Synchroniser la configuration
|
|
||||||
./scripts/sync-monitoring-config.sh
|
|
||||||
|
|
||||||
# Démarrer le monitoring
|
|
||||||
./scripts/deploy-grafana.sh start
|
|
||||||
|
|
||||||
# Tester la connectivité
|
|
||||||
./scripts/test-monitoring.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Intégration avec les Services Existants
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Redémarrer les services pour activer les volumes de logs
|
|
||||||
docker compose restart
|
|
||||||
|
|
||||||
# Vérifier la collecte des logs
|
|
||||||
./scripts/collect-logs.sh
|
|
||||||
|
|
||||||
# Vérifier Grafana
|
|
||||||
curl http://localhost:3000/api/health
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Configuration Nginx
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Intégrer la configuration Grafana dans Nginx principal
|
|
||||||
cp conf/nginx/grafana.conf /etc/nginx/sites-available/
|
|
||||||
ln -s /etc/nginx/sites-available/grafana.conf /etc/nginx/sites-enabled/
|
|
||||||
systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ Fonctionnalités Disponibles
|
|
||||||
|
|
||||||
### Monitoring en Temps Réel
|
|
||||||
|
|
||||||
- ✅ **Logs centralisés** de tous les services
|
|
||||||
- ✅ **Dashboards interactifs** avec métriques temps réel
|
|
||||||
- ✅ **Alertes automatiques** sur erreurs critiques
|
|
||||||
- ✅ **Recherche avancée** dans les logs avec LogQL
|
|
||||||
|
|
||||||
### Gestion des Logs
|
|
||||||
|
|
||||||
- ✅ **Rotation automatique** des logs (quotidienne, 7 jours de rétention)
|
|
||||||
- ✅ **Compression** des logs anciens
|
|
||||||
- ✅ **Collecte centralisée** via Promtail
|
|
||||||
- ✅ **Stockage optimisé** avec Loki
|
|
||||||
|
|
||||||
### Sécurité
|
|
||||||
|
|
||||||
- ✅ **Accès authentifié** (admin/admin123)
|
|
||||||
- ✅ **Proxy Nginx** pour accès externe sécurisé
|
|
||||||
- ✅ **Isolation réseau** Docker
|
|
||||||
- ✅ **Aucun secret** dans les logs
|
|
||||||
|
|
||||||
## 📊 Métriques Surveillées
|
|
||||||
|
|
||||||
### Services Applications
|
|
||||||
|
|
||||||
- **LeCoffre Backend** : API calls, erreurs, performance
|
|
||||||
- **LeCoffre Frontend** : Rendu, erreurs client, métriques utilisateur
|
|
||||||
- **IHM Client** : Interactions utilisateur, erreurs WASM
|
|
||||||
- **SDK Services** : Relay, Signer, Storage
|
|
||||||
|
|
||||||
### Blockchain
|
|
||||||
|
|
||||||
- **Bitcoin Signet** : Blocs, transactions, synchronisation
|
|
||||||
- **Blindbit Oracle** : Tweaks, connexions blockchain
|
|
||||||
- **Miner** : Blocs minés, récompenses, performance
|
|
||||||
|
|
||||||
### Infrastructure
|
|
||||||
|
|
||||||
- **Tor Proxy** : Connexions anonymisées
|
|
||||||
- **Nginx** : Requêtes, erreurs, performance
|
|
||||||
- **Docker** : Conteneurs, ressources, healthchecks
|
|
||||||
|
|
||||||
## 🔧 Maintenance
|
|
||||||
|
|
||||||
### Scripts de Maintenance
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Vérifier le statut
|
|
||||||
./scripts/deploy-grafana.sh status
|
|
||||||
|
|
||||||
# Collecter les logs
|
|
||||||
./scripts/collect-logs.sh
|
|
||||||
|
|
||||||
# Redémarrer le monitoring
|
|
||||||
./scripts/deploy-grafana.sh restart
|
|
||||||
|
|
||||||
# Tester la connectivité
|
|
||||||
./scripts/test-monitoring.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sauvegarde
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Sauvegarder les dashboards
|
|
||||||
docker exec grafana grafana-cli admin export-dashboard > dashboards-backup.json
|
|
||||||
|
|
||||||
# Sauvegarder la configuration
|
|
||||||
tar -czf monitoring-config-backup.tar.gz conf/grafana/ conf/promtail/
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎉 Résultat Final
|
|
||||||
|
|
||||||
Le système LeCoffre Node dispose maintenant d'un **monitoring professionnel et centralisé** avec :
|
|
||||||
|
|
||||||
- ✅ **Centralisation complète** des logs de tous les services
|
|
||||||
- ✅ **Interface Grafana** accessible de l'extérieur
|
|
||||||
- ✅ **Dashboards spécialisés** pour chaque type de service
|
|
||||||
- ✅ **Scripts automatisés** pour la gestion et le déploiement
|
|
||||||
- ✅ **Documentation complète** pour l'utilisation et la maintenance
|
|
||||||
- ✅ **Configuration sécurisée** avec accès authentifié
|
|
||||||
|
|
||||||
Le monitoring est **prêt pour la production** et peut être déployé immédiatement avec les commandes fournies.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**💡 Prochaine étape** : Exécuter `./scripts/deploy-grafana.sh start` pour lancer le monitoring !
|
|
127
docs/REX.md
127
docs/REX.md
@ -1,127 +0,0 @@
|
|||||||
# Rapport d'Expérience (REX) - Déploiement LeCoffre Node
|
|
||||||
|
|
||||||
## Date : 21 septembre 2025
|
|
||||||
|
|
||||||
### Résumé du Déploiement
|
|
||||||
|
|
||||||
Le déploiement du projet LeCoffre Node a été réalisé avec succès selon les procédures définies dans `IA_agents/deploy.md`. Tous les services sont maintenant opérationnels.
|
|
||||||
|
|
||||||
### Services Déployés
|
|
||||||
|
|
||||||
| Service | Statut | Port | Image |
|
|
||||||
|---------|--------|------|-------|
|
|
||||||
| **tor-proxy** | ✅ Running | 9050-9051 | btcpayserver/tor:0.4.8.10 |
|
|
||||||
| **bitcoin-signet** | ✅ Healthy | - | git.4nkweb.com/4nk/bitcoin:latest |
|
|
||||||
| **blindbit-oracle** | ✅ Healthy | 8000 | git.4nkweb.com/4nk/blindbit-oracle:dev |
|
|
||||||
| **sdk_relay** | ✅ Healthy | 8090-8091 | git.4nkweb.com/4nk/sdk_relay:ext |
|
|
||||||
| **sdk_signer** | ✅ Running | 3001→9090 | git.4nkweb.com/4nk/sdk_signer:ext |
|
|
||||||
| **sdk_storage** | ✅ Healthy | 8081 | git.4nkweb.com/4nk/sdk_storage:ext |
|
|
||||||
| **lecoffre-back** | ✅ Healthy | 8080 | git.4nkweb.com/4nk/lecoffre-back-mini:ext |
|
|
||||||
| **lecoffre-front** | ✅ Healthy | 3004 | git.4nkweb.com/4nk/lecoffre-front:ext |
|
|
||||||
| **ihm_client** | ✅ Healthy | 3003 | git.4nkweb.com/4nk/ihm_client:ext |
|
|
||||||
| **watchtower** | ✅ Healthy | - | containrrr/watchtower |
|
|
||||||
|
|
||||||
### Modifications Apportées
|
|
||||||
|
|
||||||
#### 1. Optimisation des Dockerfiles
|
|
||||||
- **Ajout de dépendances complètes** : Tous les Dockerfiles ont été mis à jour pour inclure :
|
|
||||||
- `build-essential`, `autoconf`, `automake`, `libtool`, `pkg-config`, `cmake`, `ninja-build`
|
|
||||||
- `clang`, `lldb`, `lld`, `make`, `tree`, `ncdu`, `mc`
|
|
||||||
- `exuberant-ctags`, `cscope`, `vim`, `emacs`
|
|
||||||
- `jq`, `curl`, `sed`, `gawk`, `inetutils-tools`, `iputils-*`, `net-tools`, `iproute2`
|
|
||||||
- `python3` (dernière version), `golang-go`, `rust` (dernière version)
|
|
||||||
- `npm` (dernière version), `wscat`
|
|
||||||
|
|
||||||
#### 2. Amélioration des Fichiers d'Exclusion
|
|
||||||
- **Création de .dockerignore** pour `sdk_common`, `sdk_client`, `sdk-signer-client`
|
|
||||||
- **Création de .cursorignore** pour `sdk_common`, `sdk-signer-client`
|
|
||||||
- **Amélioration des fichiers existants** pour tous les projets
|
|
||||||
|
|
||||||
#### 3. Correction des Imports WASM
|
|
||||||
- **Correction des chemins d'import** dans `ihm_client` : `../pkg/sdk_client.js` → `./pkg/sdk_client.js`
|
|
||||||
- **Correction de la compatibilité Alpine** dans `lecoffre-front`
|
|
||||||
|
|
||||||
### Problèmes Rencontrés et Solutions
|
|
||||||
|
|
||||||
#### 1. Problème : Import WASM manquant dans ihm_client
|
|
||||||
- **Cause** : Chemins d'import incorrects dans les fichiers TypeScript
|
|
||||||
- **Solution** : Correction automatique de tous les chemins d'import dans le code source
|
|
||||||
- **Statut** : ✅ Résolu
|
|
||||||
|
|
||||||
#### 2. Problème : Incompatibilité Alpine/apt-get dans lecoffre-front
|
|
||||||
- **Cause** : Tentative d'utilisation d'apt-get sur Alpine Linux
|
|
||||||
- **Solution** : Ajout de gestion d'erreur pour l'installation de wscat
|
|
||||||
- **Statut** : ✅ Résolu
|
|
||||||
|
|
||||||
#### 3. Problème : Connexions Tor Bitcoin échouent
|
|
||||||
- **Cause** : Réseau signet avec peu de nœuds disponibles
|
|
||||||
- **Solution** : Normal et attendu pour un réseau de test
|
|
||||||
- **Statut** : ✅ Acceptable
|
|
||||||
|
|
||||||
### Sécurité et Conformité
|
|
||||||
|
|
||||||
#### ✅ Vérifications Effectuées
|
|
||||||
- **Aucun secret détecté** dans le code source
|
|
||||||
- **Variables d'environnement** correctement externalisées
|
|
||||||
- **Images Docker** utilisent des utilisateurs non-root
|
|
||||||
- **Dépendances** mises à jour aux dernières versions
|
|
||||||
|
|
||||||
#### ✅ Conformité aux Règles
|
|
||||||
- **Branche Git** : Tous les projets sur `ext`
|
|
||||||
- **Images Docker** : Toutes avec le tag `ext`
|
|
||||||
- **Clés SSH** : Utilisées pour tous les dépôts
|
|
||||||
- **Scripts** : Utilisés plutôt que commandes directes
|
|
||||||
|
|
||||||
### Architecture Déployée
|
|
||||||
|
|
||||||
```
|
|
||||||
Internet → dev4.4nkweb.com (Nginx) → Services Locaux
|
|
||||||
├── Frontend: https://dev4.4nkweb.com/lecoffre → lecoffre-front:3004
|
|
||||||
├── API: https://dev4.4nkweb.com/api/ → lecoffre-back:8080
|
|
||||||
├── IHM: https://dev4.4nkweb.com/ → ihm_client:3003
|
|
||||||
└── WebSocket: https://dev4.4nkweb.com/ws/ → sdk_relay:8090
|
|
||||||
```
|
|
||||||
|
|
||||||
### Flux de Redirection
|
|
||||||
```
|
|
||||||
local.4nkdev.com → local.4nkweb.com → https://dev4.4nkweb.com/lecoffre
|
|
||||||
```
|
|
||||||
|
|
||||||
### Services Externes Intégrés
|
|
||||||
- **Bootstrap Relay** : `wss://dev3.4nkweb.com/ws/` ✅ Actif
|
|
||||||
- **Signer Externe** : `ws://dev3.4nkweb.com:9090` ✅ Actif
|
|
||||||
- **Mempool** : `https://mempool2.4nkweb.com` ✅ Actif
|
|
||||||
|
|
||||||
### Monitoring et Surveillance
|
|
||||||
|
|
||||||
#### Watchtower
|
|
||||||
- **Mise à jour automatique** des images Docker toutes les 30 secondes
|
|
||||||
- **Surveillance** de tous les services avec le label `com.centurylinklabs.watchtower.enable=true`
|
|
||||||
|
|
||||||
#### Healthchecks
|
|
||||||
- Tous les services disposent de healthchecks configurés
|
|
||||||
- **Bitcoin** : Vérification via `bitcoin-cli getblockchaininfo`
|
|
||||||
- **Services Web** : Vérification via `curl` sur les endpoints de santé
|
|
||||||
|
|
||||||
### Recommandations
|
|
||||||
|
|
||||||
#### 1. Amélioration Continue
|
|
||||||
- **Monitoring** : Intégrer Grafana pour le dashboard des logs
|
|
||||||
- **Tests** : Automatiser les tests de connectivité inter-services
|
|
||||||
- **Documentation** : Maintenir à jour les flux d'architecture
|
|
||||||
|
|
||||||
#### 2. Sécurité
|
|
||||||
- **Scan des images** : Intégrer Trivy ou Clair pour la détection de vulnérabilités
|
|
||||||
- **Rotation des clés** : Mettre en place une rotation automatique des clés SSH
|
|
||||||
- **Audit des logs** : Surveiller les logs pour détecter les tentatives d'intrusion
|
|
||||||
|
|
||||||
#### 3. Performance
|
|
||||||
- **Cache des dépendances** : Optimiser les builds Docker avec des layers de cache
|
|
||||||
- **Ressources** : Monitorer l'utilisation CPU/RAM des conteneurs
|
|
||||||
- **Réseau** : Optimiser les connexions inter-services
|
|
||||||
|
|
||||||
### Conclusion
|
|
||||||
|
|
||||||
Le déploiement a été réalisé avec succès. Tous les services sont opérationnels et respectent les règles de sécurité et de conformité définies. Le système est prêt pour la production avec une architecture robuste et scalable.
|
|
||||||
|
|
||||||
**Prochaine étape** : Mise en place du monitoring avancé et des tests automatisés.
|
|
@ -1,85 +0,0 @@
|
|||||||
### Routage API et bonnes pratiques de déploiement
|
|
||||||
|
|
||||||
- **Objectif**: éviter les appels directs vers `localhost:8080`, standardiser l’URL API sous le même domaine que le front, et supprimer les causes de `net::ERR_BLOCKED_BY_CLIENT` (bloqueurs de contenu/balises heuristiques).
|
|
||||||
|
|
||||||
### Règles de base
|
|
||||||
|
|
||||||
- **Toujours appeler l’API via le reverse proxy Nginx** du domaine public.
|
|
||||||
- Front sous `https://dev4.4nkweb.com/lecoffre/`.
|
|
||||||
- Backend accessible via des chemins de proxy: `https://dev4.4nkweb.com/back/…` (existant) et `https://dev4.4nkweb.com/api/…` (alias recommandé).
|
|
||||||
- **Ne jamais appeler `http://localhost:8080` depuis le navigateur** en environnement intégré: ces appels sont plus susceptibles d’être bloqués par des extensions/heuristiques et contournent le proxy (CORS, headers, TLS, logs).
|
|
||||||
- **Utiliser une base d’URL configurée** côté front (variable d’environnement) et **des chemins relatifs** (`/back/…` ou `/api/…`).
|
|
||||||
|
|
||||||
### Variables d’environnement recommandées (front)
|
|
||||||
|
|
||||||
- `NEXT_PUBLIC_API_BASE` ou `VITE_API_BASE`
|
|
||||||
- Valeur production/staging: `/back` (ou `/api` si alias activé)
|
|
||||||
- Valeur locale derrière Nginx: `/back`
|
|
||||||
- Bénéfice: pas d’hardcoding d’hôte/port, pas de divergence env.
|
|
||||||
|
|
||||||
### Nginx (hôte) — état actuel et alias conseillé
|
|
||||||
|
|
||||||
- État actuel confirmé dans `conf/nginx/dev4.4nkweb.com.conf`:
|
|
||||||
- `location /back/ { proxy_pass http://127.0.0.1:8080/; … }`
|
|
||||||
- Recommandation: ajouter un alias identique `location /api/ { … }` pointant vers `127.0.0.1:8080/` pour couvrir les fronts qui référencent `/api/`.
|
|
||||||
- Avantage: déploiements futurs facilités (unification), compatibilité avec conventions courantes (`/api`).
|
|
||||||
|
|
||||||
### Réécriture de secours (ihm_client) via sub_filter
|
|
||||||
|
|
||||||
- Afin d’éliminer toute occurrence résiduelle de `http://localhost:8080` côté front (pages et bundles servis par `ihm_client`), la conf Nginx applique une réécriture à la volée:
|
|
||||||
- Fichier: `conf/nginx/dev4.4nkweb.com.conf`
|
|
||||||
- Bloc `location /` (ihm_client) et blocs `location /lecoffre/_next/` et `location /_next/`.
|
|
||||||
- Ajouts: désactivation de la compression en amont pour permettre `sub_filter`, `sub_filter_once off`, et remplacement de `http://localhost:8080` par `https://dev4.4nkweb.com/api`.
|
|
||||||
- Impact: supprime les références absolues à `localhost` dans HTML/JS/JSON servis par Nginx, évitant `ERR_BLOCKED_BY_CLIENT` et le contenu mixte.
|
|
||||||
|
|
||||||
### Pourquoi `ERR_BLOCKED_BY_CLIENT` survient
|
|
||||||
|
|
||||||
- La requête était observée vers `http://localhost:8080/api/v1/idnot/auth…`.
|
|
||||||
- Certains bloqueurs interceptent des requêtes cross-origin ou vers des chemins jugés sensibles quand elles ne passent pas par le même domaine que la page.
|
|
||||||
- Passer par `https://dev4.4nkweb.com/back/…` (ou `/api/`) sous le même hôte supprime ces heuristiques et évite CORS.
|
|
||||||
|
|
||||||
### Ligne directrice pour les repos front
|
|
||||||
|
|
||||||
- Centraliser la base d’URL API via `.env` et publier cette valeur au build (`NEXT_PUBLIC_…`/`VITE_…`).
|
|
||||||
- Effectuer les appels via `fetch(\"${API_BASE}/api/v1/...\")` ou équivalent, où `API_BASE` vaut `/back` (ou `/api`).
|
|
||||||
- Ne pas committer de valeurs absolues (hôte/port) dans le code.
|
|
||||||
|
|
||||||
### Validation et tests (voir `tests/api_routing.md`)
|
|
||||||
|
|
||||||
- Vérifier que les endpoints répondent correctement via le domaine: `/back/health`, `/storage/health`, etc.
|
|
||||||
- Contrôler l’absence d’erreurs Nginx et la non-présence de CORS dans la console.
|
|
||||||
|
|
||||||
### Récapitulatif de routage dev4
|
|
||||||
|
|
||||||
- `https://dev4.4nkweb.com/lecoffre` → proxy vers `lecoffre-front` (port 3004, conteneur 3000)
|
|
||||||
- `https://dev4.4nkweb.com/back/*` → proxy vers `http://127.0.0.1:8080/api/*` (backend mini)
|
|
||||||
- `https://dev4.4nkweb.com/api/*` → (alias optionnel) proxy vers `http://127.0.0.1:8080/api/*`
|
|
||||||
- `https://dev4.4nkweb.com/signer/*` → proxy WebSocket/HTTP vers `http://127.0.0.1:3001/`
|
|
||||||
|
|
||||||
Notes d’implémentation:
|
|
||||||
- Les blocs `location /back/` et `location /api/` sont positionnés avant le `location /` afin d’éviter que le root (ihm_client) prenne la priorité.
|
|
||||||
- Les en-têtes `X-Forwarded-*` sont ajoutés. `proxy_buffering off` pour `/back/` empêche des effets indésirables côté streams SSE/WebSocket.
|
|
||||||
|
|
||||||
### Procédure de changement (sur validation)
|
|
||||||
|
|
||||||
1. Ajouter `location /api/` vers `127.0.0.1:8080/` dans `conf/nginx/dev4.4nkweb.com.conf` juste après le bloc `/back/`.
|
|
||||||
2. `sudo nginx -t` puis recharge.
|
|
||||||
3. Mettre à jour la variable `NEXT_PUBLIC_API_BASE`/`VITE_API_BASE` des fronts.
|
|
||||||
4. Redéployer le front.
|
|
||||||
|
|
||||||
### Adoption de l’image lecoffre-front:ext-0.1.3
|
|
||||||
|
|
||||||
- Image: `git.4nkweb.com/4nk/lecoffre-front:ext-0.1.3` (voir paquet registre)
|
|
||||||
- Fichier: `docker-compose.yml`
|
|
||||||
- Ligne modifiée: service `lecoffre-front.image` → `git.4nkweb.com/4nk/lecoffre-front:ext-0.1.3`
|
|
||||||
- Effet: les appels API en dur vers `localhost:8080` ont été remplacés dans le build; plus besoin de réécritures de secours côté Nginx.
|
|
||||||
|
|
||||||
### Nettoyage des sub_filter Nginx
|
|
||||||
|
|
||||||
- Fichier: `conf/nginx/dev4.4nkweb.com.conf`
|
|
||||||
- Suppression des directives `sub_filter` dans:
|
|
||||||
- `location /` (ihm_client)
|
|
||||||
- `location /lecoffre/`
|
|
||||||
- `location /lecoffre/_next/`
|
|
||||||
- `location /_next/`
|
|
||||||
- Raison: la nouvelle image front utilise `/api` et ne référence plus `localhost:8080`.
|
|
@ -1,188 +0,0 @@
|
|||||||
# Améliorations de la séquence de démarrage - IMPLÉMENTÉES
|
|
||||||
|
|
||||||
## Problème résolu
|
|
||||||
|
|
||||||
Le service `sdk_relay` bloquait complètement pendant le scan des blocs, empêchant les services dépendants de se connecter.
|
|
||||||
|
|
||||||
**✅ RÉSOLU** : Les améliorations suivantes ont été implémentées dans le `docker-compose.yml` existant.
|
|
||||||
|
|
||||||
## Améliorations implémentées dans docker-compose.yml
|
|
||||||
|
|
||||||
### 1. **Healthcheck amélioré pour sdk_relay**
|
|
||||||
```yaml
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "sh", "-c", "curl -f http://localhost:8091/ | grep -q '\"status\":\"ok\"'"]
|
|
||||||
interval: 15s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
start_period: 60s # Plus de temps pour le démarrage initial
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. **Variables d'environnement pour le scan**
|
|
||||||
```yaml
|
|
||||||
environment:
|
|
||||||
- SDK_RELAY_SCAN_TIMEOUT=300
|
|
||||||
- SDK_RELAY_STARTUP_MODE=async
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. **Dépendances et healthchecks pour tous les services**
|
|
||||||
```yaml
|
|
||||||
ihm_client:
|
|
||||||
depends_on:
|
|
||||||
sdk_relay:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3003/"]
|
|
||||||
start_period: 30s
|
|
||||||
|
|
||||||
lecoffre-back:
|
|
||||||
depends_on:
|
|
||||||
sdk_relay:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
|
||||||
start_period: 30s
|
|
||||||
|
|
||||||
lecoffre-front:
|
|
||||||
depends_on:
|
|
||||||
lecoffre-back:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3000/"]
|
|
||||||
start_period: 30s
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. **Script de démarrage simplifié**
|
|
||||||
|
|
||||||
Le script `startup-sequence.sh` utilise maintenant les healthchecks intégrés :
|
|
||||||
- ✅ Démarre tous les services avec `docker compose up -d`
|
|
||||||
- ✅ Les healthchecks gèrent automatiquement l'ordre de démarrage
|
|
||||||
- ✅ Vérifie l'état du scan de sdk_relay
|
|
||||||
- ✅ Monitoring simplifié et efficace
|
|
||||||
|
|
||||||
## Utilisation
|
|
||||||
|
|
||||||
### Démarrage normal
|
|
||||||
```bash
|
|
||||||
# Démarrage standard avec les améliorations
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
# Ou utiliser le script optimisé
|
|
||||||
./scripts/startup-sequence.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Monitoring
|
|
||||||
```bash
|
|
||||||
# Vérifier l'état des services
|
|
||||||
docker compose ps
|
|
||||||
|
|
||||||
# Surveiller les logs
|
|
||||||
docker compose logs -f sdk_relay
|
|
||||||
|
|
||||||
# Vérifier l'état du scan
|
|
||||||
curl http://127.0.0.1:8091/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Avantages
|
|
||||||
|
|
||||||
### ✅ **Disponibilité immédiate**
|
|
||||||
- Les services WebSocket sont disponibles dès le démarrage
|
|
||||||
- Pas d'attente pendant le scan des blocs
|
|
||||||
|
|
||||||
### ✅ **Meilleure expérience utilisateur**
|
|
||||||
- Connexions WebSocket fonctionnelles immédiatement
|
|
||||||
- Messages d'état clairs pendant le scan
|
|
||||||
|
|
||||||
### ✅ **Monitoring amélioré**
|
|
||||||
- Healthchecks détaillés
|
|
||||||
- État du scan visible via l'API
|
|
||||||
- Logs structurés
|
|
||||||
|
|
||||||
### ✅ **Récupération d'erreur**
|
|
||||||
- Timeouts configurables
|
|
||||||
- Retry automatique
|
|
||||||
- Fallback en cas d'échec
|
|
||||||
|
|
||||||
## Configuration recommandée
|
|
||||||
|
|
||||||
### Variables d'environnement
|
|
||||||
```bash
|
|
||||||
# Timeout pour le scan (en secondes)
|
|
||||||
SDK_RELAY_SCAN_TIMEOUT=300
|
|
||||||
|
|
||||||
# Mode de démarrage
|
|
||||||
SDK_RELAY_STARTUP_MODE=async
|
|
||||||
|
|
||||||
# Attendre la fin du scan
|
|
||||||
SDK_RELAY_WAIT_FOR_SCAN=true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Healthcheck personnalisé
|
|
||||||
```bash
|
|
||||||
# Vérifier l'état complet du service
|
|
||||||
curl -s http://127.0.0.1:8091/ | jq '.'
|
|
||||||
|
|
||||||
# Exemple de réponse :
|
|
||||||
{
|
|
||||||
"status": "ok",
|
|
||||||
"scan_complete": false,
|
|
||||||
"scan_progress": {
|
|
||||||
"current": 136325,
|
|
||||||
"total": 136327,
|
|
||||||
"percentage": 99.8
|
|
||||||
},
|
|
||||||
"message": "Scan in progress"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Problème : Service ne démarre pas
|
|
||||||
```bash
|
|
||||||
# Vérifier les logs
|
|
||||||
docker compose logs sdk_relay
|
|
||||||
|
|
||||||
# Vérifier la configuration
|
|
||||||
docker exec sdk_relay cat /home/bitcoin/.conf
|
|
||||||
|
|
||||||
# Vérifier le wallet
|
|
||||||
docker exec sdk_relay cat /home/bitcoin/.4nk/default
|
|
||||||
```
|
|
||||||
|
|
||||||
### Problème : Scan bloqué
|
|
||||||
```bash
|
|
||||||
# Vérifier la connectivité à blindbit
|
|
||||||
docker exec sdk_relay curl http://blindbit-oracle:8000/utxos/136294
|
|
||||||
|
|
||||||
# Redémarrer avec un scan réduit
|
|
||||||
docker exec sdk_relay sed -i 's/"last_scan":136320/"last_scan":136325/g' /home/bitcoin/.4nk/default
|
|
||||||
docker compose restart sdk_relay
|
|
||||||
```
|
|
||||||
|
|
||||||
### Problème : Services dépendants ne se connectent pas
|
|
||||||
```bash
|
|
||||||
# Vérifier l'état du WebSocket
|
|
||||||
curl -I http://127.0.0.1:8090/
|
|
||||||
|
|
||||||
# Tester la connexion WebSocket
|
|
||||||
websocat ws://127.0.0.1:8090/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Métriques de performance
|
|
||||||
|
|
||||||
### Avant les améliorations
|
|
||||||
- ⏱️ Temps de démarrage : 5-10 minutes
|
|
||||||
- 🔌 Disponibilité WebSocket : Après scan complet
|
|
||||||
- 📊 Monitoring : Limité aux logs
|
|
||||||
|
|
||||||
### Après les améliorations
|
|
||||||
- ⏱️ Temps de démarrage : 30-60 secondes
|
|
||||||
- 🔌 Disponibilité WebSocket : Immédiate
|
|
||||||
- 📊 Monitoring : API détaillée + healthchecks
|
|
||||||
|
|
||||||
## Prochaines étapes
|
|
||||||
|
|
||||||
1. **Implémentation dans le code source** : Modifier `sdk_relay/src/main.rs`
|
|
||||||
2. **Tests automatisés** : Ajouter des tests pour la séquence de démarrage
|
|
||||||
3. **Monitoring avancé** : Intégrer avec Prometheus/Grafana
|
|
||||||
4. **Documentation utilisateur** : Guide pour les développeurs
|
|
@ -1,92 +0,0 @@
|
|||||||
# Tests de Connectivité Exhaustifs - dev3.4nkweb.com
|
|
||||||
|
|
||||||
## Résumé Exécutif
|
|
||||||
|
|
||||||
**Date des tests** : 20/09/2025
|
|
||||||
**Objectif** : Tester tous les protocoles, ports et chemins possibles pour dev3.4nkweb.com
|
|
||||||
|
|
||||||
## Résultats des Tests
|
|
||||||
|
|
||||||
### Groupe 1: Tests avec port 9090 (Tous échouent)
|
|
||||||
|
|
||||||
| URL | Résultat | Détails |
|
|
||||||
|-----|----------|---------|
|
|
||||||
| `http://dev3.4nkweb.com:9090` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `https://dev3.4nkweb.com:9090` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `http://dev3.4nkweb.com:9090/ws` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `https://dev3.4nkweb.com:9090/ws` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `http://dev3.4nkweb.com:9090/signer` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `https://dev3.4nkweb.com:9090/signer` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `http://dev3.4nkweb.com:9090/signer/ws` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
| `https://dev3.4nkweb.com:9090/signer/ws` | ❌ Connection refused | Port 9090 fermé |
|
|
||||||
|
|
||||||
### Groupe 2: Tests sans port 9090 (Port par défaut)
|
|
||||||
|
|
||||||
| URL | Résultat | Détails |
|
|
||||||
|-----|----------|---------|
|
|
||||||
| `http://dev3.4nkweb.com` | ⚠️ 301 Redirect | Redirige vers HTTPS |
|
|
||||||
| `https://dev3.4nkweb.com` | ⚠️ 502 Bad Gateway | Nginx OK, backend KO |
|
|
||||||
| `http://dev3.4nkweb.com/ws` | ⚠️ 301 Redirect | Redirige vers HTTPS |
|
|
||||||
| `https://dev3.4nkweb.com/ws` | ⚠️ 301 Redirect | Redirige vers `/ws/` |
|
|
||||||
| `https://dev3.4nkweb.com/ws/` | ⚠️ 502 Bad Gateway | Nginx OK, backend KO |
|
|
||||||
| `https://dev3.4nkweb.com/signer` | ⚠️ 502 Bad Gateway | Nginx OK, backend KO |
|
|
||||||
| `https://dev3.4nkweb.com/signer/ws` | ⚠️ 502 Bad Gateway | Nginx OK, backend KO |
|
|
||||||
|
|
||||||
### Groupe 3: Tests autres ports
|
|
||||||
|
|
||||||
| URL | Résultat | Détails |
|
|
||||||
|-----|----------|---------|
|
|
||||||
| `http://dev3.4nkweb.com:80` | ⚠️ 301 Redirect | Redirige vers HTTPS |
|
|
||||||
| `https://dev3.4nkweb.com:443` | ⚠️ 502 Bad Gateway | Nginx OK, backend KO |
|
|
||||||
| `http://dev3.4nkweb.com:3001` | ❌ Connection refused | Port 3001 fermé |
|
|
||||||
| `http://dev3.4nkweb.com:8080` | ✅ **SERVICE ACTIF** | Express.js répond |
|
|
||||||
| `http://dev3.4nkweb.com:8080/ws` | ⚠️ 404 Not Found | Service actif mais pas de route /ws |
|
|
||||||
| `http://dev3.4nkweb.com:8080/signer` | ⚠️ 404 Not Found | Service actif mais pas de route /signer |
|
|
||||||
| `http://dev3.4nkweb.com:8080/health` | ⚠️ 404 Not Found | Service actif mais pas de route /health |
|
|
||||||
|
|
||||||
## Découverte Importante
|
|
||||||
|
|
||||||
### Port 8080 - Service Express.js Actif
|
|
||||||
Le port 8080 sur dev3.4nkweb.com héberge un service Express.js qui répond avec :
|
|
||||||
- **Headers** : `X-Powered-By: Express`
|
|
||||||
- **CORS** : `Access-Control-Allow-Origin: http://localhost:3000`
|
|
||||||
- **Status** : Service actif et fonctionnel
|
|
||||||
- **Routes** : Aucune route `/ws`, `/signer`, ou `/health` configurée
|
|
||||||
|
|
||||||
## Analyse
|
|
||||||
|
|
||||||
### État des Services
|
|
||||||
1. **Port 9090** : Complètement fermé (Connection refused)
|
|
||||||
2. **Port 443** : Nginx fonctionne mais services backend retournent 502 Bad Gateway
|
|
||||||
3. **Port 8080** : Service Express.js actif mais sans routes WebSocket/signer
|
|
||||||
4. **Port 3001** : Fermé (Connection refused)
|
|
||||||
|
|
||||||
### Problème Identifié
|
|
||||||
- Le service signer sur le port 9090 n'est pas démarré
|
|
||||||
- Les services backend sur le port 443 ne sont pas démarrés
|
|
||||||
- Un service Express.js fonctionne sur le port 8080 mais sans les routes nécessaires
|
|
||||||
|
|
||||||
## Recommandations
|
|
||||||
|
|
||||||
### Solution Immédiate
|
|
||||||
1. **Vérifier l'état des services** sur dev3.4nkweb.com
|
|
||||||
2. **Redémarrer le service signer** sur le port 9090
|
|
||||||
3. **Configurer les routes WebSocket** sur le port 8080 si nécessaire
|
|
||||||
|
|
||||||
### Configuration Alternative
|
|
||||||
Si le port 9090 n'est pas disponible, considérer :
|
|
||||||
- Utiliser le port 8080 avec les routes appropriées
|
|
||||||
- Configurer un proxy nginx pour rediriger vers le bon service
|
|
||||||
- Utiliser temporairement le signer local en attendant la résolution
|
|
||||||
|
|
||||||
## Conclusion
|
|
||||||
|
|
||||||
Le serveur dev3.4nkweb.com a :
|
|
||||||
- ✅ Nginx fonctionnel sur le port 443
|
|
||||||
- ✅ Service Express.js actif sur le port 8080
|
|
||||||
- ❌ Service signer indisponible sur le port 9090
|
|
||||||
- ❌ Services backend indisponibles sur le port 443
|
|
||||||
|
|
||||||
**Action requise** : Redémarrer les services signer et backend sur dev3.4nkweb.com
|
|
||||||
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
|||||||
# Transfert Automatique de Fonds
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
|
|
||||||
Ce système implémente un mécanisme automatique de transfert de fonds du wallet mining vers le relay en cas de fonds insuffisants. Cela résout automatiquement le problème de fonds pour le processus de pairing.
|
|
||||||
|
|
||||||
## Scripts Disponibles
|
|
||||||
|
|
||||||
### 1. `scripts/funds/simple_transfer.sh`
|
|
||||||
Script de base pour transférer des fonds du wallet mining vers le relay.
|
|
||||||
|
|
||||||
**Usage:**
|
|
||||||
```bash
|
|
||||||
./scripts/funds/simple_transfer.sh [amount]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Paramètres:**
|
|
||||||
- `amount`: Montant à transférer en BTC (par défaut: 0.01)
|
|
||||||
|
|
||||||
**Fonctionnalités:**
|
|
||||||
- Vérification de la connectivité Bitcoin
|
|
||||||
- Vérification des soldes des wallets
|
|
||||||
- Génération d'une adresse pour le relay
|
|
||||||
- Transfert de fonds
|
|
||||||
- Confirmation de la transaction
|
|
||||||
- Redémarrage du relay
|
|
||||||
|
|
||||||
### 2. `scripts/funds/check_and_transfer_funds.sh`
|
|
||||||
Script d'intégration qui vérifie les fonds et lance un transfert si nécessaire.
|
|
||||||
|
|
||||||
**Usage:**
|
|
||||||
```bash
|
|
||||||
./scripts/funds/check_and_transfer_funds.sh [min_amount]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Paramètres:**
|
|
||||||
- `min_amount`: Montant minimum requis en BTC (par défaut: 0.001)
|
|
||||||
|
|
||||||
**Fonctionnalités:**
|
|
||||||
- Vérification des fonds du relay dans la configuration
|
|
||||||
- Vérification du solde du wallet relay dans Bitcoin Core
|
|
||||||
- Transfert automatique si fonds insuffisants
|
|
||||||
- Transfère 10x le montant minimum requis
|
|
||||||
|
|
||||||
### 3. `scripts/funds/monitor_funds.sh`
|
|
||||||
Script de monitoring continu des fonds du relay.
|
|
||||||
|
|
||||||
**Usage:**
|
|
||||||
```bash
|
|
||||||
./scripts/funds/monitor_funds.sh [interval_seconds]
|
|
||||||
```
|
|
||||||
|
|
||||||
**Paramètres:**
|
|
||||||
- `interval_seconds`: Intervalle de vérification en secondes (par défaut: 30)
|
|
||||||
|
|
||||||
**Fonctionnalités:**
|
|
||||||
- Monitoring continu des fonds
|
|
||||||
- Vérification de l'état du relay
|
|
||||||
- Transfert automatique si fonds insuffisants
|
|
||||||
- Affichage des statistiques en temps réel
|
|
||||||
|
|
||||||
### 4. `scripts/funds/startup_funds_check.sh`
|
|
||||||
Script de vérification des fonds au démarrage.
|
|
||||||
|
|
||||||
**Usage:**
|
|
||||||
```bash
|
|
||||||
./scripts/funds/startup_funds_check.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fonctionnalités:**
|
|
||||||
- Attente du démarrage des services
|
|
||||||
- Vérification de la connectivité Bitcoin
|
|
||||||
- Vérification de l'état du relay
|
|
||||||
- Lancement du transfert automatique si nécessaire
|
|
||||||
|
|
||||||
### 5. `scripts/startup-with-funds-check.sh`
|
|
||||||
Script de démarrage complet avec vérification des fonds.
|
|
||||||
|
|
||||||
**Usage:**
|
|
||||||
```bash
|
|
||||||
./scripts/startup-with-funds-check.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
**Fonctionnalités:**
|
|
||||||
- Démarrage des services Docker Compose
|
|
||||||
- Attente du démarrage complet
|
|
||||||
- Vérification et transfert automatique des fonds
|
|
||||||
|
|
||||||
## Intégration dans les Applications
|
|
||||||
|
|
||||||
### Docker Compose
|
|
||||||
Le volume `./scripts/funds:/scripts/funds:ro` est monté dans le conteneur `sdk_relay` pour permettre l'accès aux scripts.
|
|
||||||
|
|
||||||
### Démarrage Automatique
|
|
||||||
Utilisez `./scripts/startup-with-funds-check.sh` pour démarrer les services avec vérification automatique des fonds.
|
|
||||||
|
|
||||||
### Monitoring Continu
|
|
||||||
Lancez `./scripts/funds/monitor_funds.sh` en arrière-plan pour un monitoring continu des fonds.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Variables d'Environnement
|
|
||||||
- `MINING_WALLET`: Nom du wallet mining (par défaut: "mining_mnemonic")
|
|
||||||
- `RELAY_WALLET`: Nom du wallet relay (par défaut: "default")
|
|
||||||
- `COOKIE_FILE`: Chemin vers le fichier cookie Bitcoin (par défaut: "/home/bitcoin/.bitcoin/signet/.cookie")
|
|
||||||
|
|
||||||
### Montants par Défaut
|
|
||||||
- Montant minimum: 0.001 BTC (100,000 sats)
|
|
||||||
- Montant de transfert par défaut: 0.01 BTC (1,000,000 sats)
|
|
||||||
- Multiplicateur de transfert: 10x le montant minimum
|
|
||||||
|
|
||||||
## Dépannage
|
|
||||||
|
|
||||||
### Problèmes Courants
|
|
||||||
|
|
||||||
1. **bc non installé**
|
|
||||||
```bash
|
|
||||||
sudo apt-get install -y bc
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Permissions insuffisantes**
|
|
||||||
```bash
|
|
||||||
chmod +x scripts/funds/*.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Wallet non chargé**
|
|
||||||
Les scripts chargent automatiquement le wallet relay si nécessaire.
|
|
||||||
|
|
||||||
4. **Transaction non confirmée**
|
|
||||||
Les scripts génèrent automatiquement des blocs pour confirmer les transactions.
|
|
||||||
|
|
||||||
### Logs
|
|
||||||
Les scripts affichent des logs colorés pour faciliter le débogage:
|
|
||||||
- 🔵 [INFO]: Informations générales
|
|
||||||
- 🟢 [SUCCESS]: Opérations réussies
|
|
||||||
- 🟡 [WARNING]: Avertissements
|
|
||||||
- 🔴 [ERROR]: Erreurs
|
|
||||||
|
|
||||||
## Exemples d'Utilisation
|
|
||||||
|
|
||||||
### Transfert Manuel
|
|
||||||
```bash
|
|
||||||
# Transférer 0.01 BTC
|
|
||||||
./scripts/funds/simple_transfer.sh 0.01
|
|
||||||
|
|
||||||
# Transférer 0.1 BTC
|
|
||||||
./scripts/funds/simple_transfer.sh 0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
### Vérification et Transfert Automatique
|
|
||||||
```bash
|
|
||||||
# Vérifier et transférer si nécessaire (minimum 0.001 BTC)
|
|
||||||
./scripts/funds/check_and_transfer_funds.sh 0.001
|
|
||||||
|
|
||||||
# Vérifier et transférer si nécessaire (minimum 0.01 BTC)
|
|
||||||
./scripts/funds/check_and_transfer_funds.sh 0.01
|
|
||||||
```
|
|
||||||
|
|
||||||
### Monitoring Continu
|
|
||||||
```bash
|
|
||||||
# Monitoring toutes les 30 secondes
|
|
||||||
./scripts/funds/monitor_funds.sh
|
|
||||||
|
|
||||||
# Monitoring toutes les 60 secondes
|
|
||||||
./scripts/funds/monitor_funds.sh 60
|
|
||||||
```
|
|
||||||
|
|
||||||
### Démarrage Complet
|
|
||||||
```bash
|
|
||||||
# Démarrage avec vérification des fonds
|
|
||||||
./scripts/startup-with-funds-check.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sécurité
|
|
||||||
|
|
||||||
- Les scripts utilisent des montants par défaut sécurisés
|
|
||||||
- Vérification des soldes avant transfert
|
|
||||||
- Confirmation des transactions
|
|
||||||
- Logs détaillés pour audit
|
|
||||||
|
|
||||||
## Maintenance
|
|
||||||
|
|
||||||
- Les scripts sont conçus pour être robustes et auto-réparateurs
|
|
||||||
- Monitoring continu disponible
|
|
||||||
- Redémarrage automatique du relay après transfert
|
|
||||||
- Gestion des erreurs et retry automatique
|
|
@ -1,65 +0,0 @@
|
|||||||
### Objet
|
|
||||||
Matrice des variables d’environnement pour `lecoffre-front`, `lecoffre-back-mini` et orchestrations `lecoffre_node`, avec cohérence Nginx/basePath.
|
|
||||||
|
|
||||||
### Variables côté Front (Next.js)
|
|
||||||
- **Exposition**: `NEXT_PUBLIC_*` via `next.config.js` (env/publicRuntimeConfig/serverRuntimeConfig)
|
|
||||||
- **Consommation**: `src/front/Config/VariablesFront.ts` et services API
|
|
||||||
|
|
||||||
- NEXT_PUBLIC_BACK_API_PROTOCOL: protocole back (ex: `http`)
|
|
||||||
- NEXT_PUBLIC_BACK_API_HOST: hôte back (ex: `127.0.0.1` ou `dev4.4nkweb.com`)
|
|
||||||
- NEXT_PUBLIC_BACK_API_PORT: port back (ex: `8080`)
|
|
||||||
- NEXT_PUBLIC_BACK_API_ROOT_URL: préfixe API (ex: `/api`)
|
|
||||||
- NEXT_PUBLIC_BACK_API_VERSION: version API (ex: `/v1`)
|
|
||||||
- NEXT_PUBLIC_FRONT_APP_HOST: URL publique du front (utilisée pour ID.not redirect)
|
|
||||||
- NEXT_PUBLIC_FRONT_APP_PORT: port front si nécessaire
|
|
||||||
- NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: endpoint authorize (ex: `/user/auth`)
|
|
||||||
- NEXT_PUBLIC_IDNOT_CLIENT_ID: client_id ID.not
|
|
||||||
- NEXT_PUBLIC_IDNOT_BASE_URL: base URL ID.not
|
|
||||||
- NEXT_PUBLIC_IDNOT_REDIRECT_URI: redirect URI explicite; fallback vers `${FRONT_APP_HOST}/authorized-client`
|
|
||||||
- NEXT_PUBLIC_DOCAPOSTE_API_URL: base API Docaposte
|
|
||||||
- NEXT_PUBLIC_HOTJAR_SITE_ID / NEXT_PUBLIC_HOTJAR_VERSION: télémétrie
|
|
||||||
- NEXT_PUBLIC_4NK_URL / NEXT_PUBLIC_4NK_IFRAME_URL: intégrations 4NK
|
|
||||||
- NEXT_PUBLIC_API_URL: éventuellement raccourci général d’API
|
|
||||||
- NEXT_PUBLIC_DEFAULT_VALIDATOR_ID / NEXT_PUBLIC_DEFAULT_STORAGE_URLS: valeurs par défaut SDK
|
|
||||||
|
|
||||||
### Variables côté Back (Express)
|
|
||||||
- PORT: port d’écoute (défaut 8080)
|
|
||||||
- DEFAULT_STORAGE: URL de stockage par défaut (défaut `https://dev3.4nkweb.com/storage`)
|
|
||||||
- APP_HOST: URL front (défaut `http://localhost:3000`) – utilisé aussi par `stripe`
|
|
||||||
- STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET
|
|
||||||
- IDNOT_CLIENT_ID / IDNOT_CLIENT_SECRET / IDNOT_REDIRECT_URI / IDNOT_TOKEN_URL
|
|
||||||
- IDNOT_API_KEY / IDNOT_API_BASE_URL / IDNOT_ANNUARY_BASE_URL
|
|
||||||
|
|
||||||
### Orchestration Docker / Nginx (lecoffre_node)
|
|
||||||
- Compose publie:
|
|
||||||
- `lecoffre-back`: `127.0.0.1:8080` (proxy Nginx `/api/` et `/back/`)
|
|
||||||
- `lecoffre-front`: `127.0.0.2:3004` (front Next.js)
|
|
||||||
- Services SDK: `sdk_relay` (8090), `sdk_signer` (3001), `sdk_storage` (8081), `blindbit` (8000)
|
|
||||||
- Nginx `dev4.4nkweb.com.conf`:
|
|
||||||
- `/api/` → `http://127.0.0.1:8080/api/`
|
|
||||||
- `/back/(.*)` → `http://127.0.0.1:8080/api/$1`
|
|
||||||
- `/` → `http://127.0.0.1:3003` (ihm_client)
|
|
||||||
- `/lecoffre` et `/lecoffre/` → `http://127.0.0.2:3004/lecoffre/`
|
|
||||||
- `/_next/` → `http://127.0.0.2:3004/_next/`
|
|
||||||
|
|
||||||
### Cohérence basePath Nginx/Next
|
|
||||||
- Next.js `basePath: '/lecoffre'` (voir `next.config.js`)
|
|
||||||
- Nginx proxy `/lecoffre` et `/_next/` vers le front sur 3004
|
|
||||||
- Impacts: routes, assets statiques, liens internes doivent inclure le `basePath`
|
|
||||||
|
|
||||||
### Qui consomme quoi
|
|
||||||
- Front:
|
|
||||||
- API back: `NEXT_PUBLIC_BACK_API_*` utilisés par `BaseApiService`, `Auth` (IdNot), Admin APIs (Subscriptions, Stripe)
|
|
||||||
- ID.not: `NEXT_PUBLIC_IDNOT_*` via `Auth` et composants de login
|
|
||||||
- Télémétrie/Intégrations: Hotjar, Docaposte, 4NK
|
|
||||||
- Back:
|
|
||||||
- ID.not: `IDNOT_*` (auth, user/office, annuaire)
|
|
||||||
- Stripe: `STRIPE_*` (routes `/subscriptions/*`, webhook)
|
|
||||||
- Réseau front: `APP_HOST` pour callbacks/URLs
|
|
||||||
- Nginx/Compose:
|
|
||||||
- Route HTTP publique et correspondances de ports/containers
|
|
||||||
|
|
||||||
### Recommandations
|
|
||||||
- Aligner `APP_HOST` (back) avec l’URL publique réelle du front (incluant basePath dans les redirections si nécessaire)
|
|
||||||
- Vérifier que `NEXT_PUBLIC_*` ne contiennent aucun secret
|
|
||||||
- Centraliser un `.env`/CI par environnement (local/dev/staging/prod) et lister explicitement les valeurs attendues
|
|
@ -1,83 +0,0 @@
|
|||||||
### Vhost local HTTP pour `local.lecoffreio.4nkweb`
|
|
||||||
|
|
||||||
Objectif: servir l’IHM en HTTP pur (sans HTTPS ni HSTS) pour le domaine local `local.lecoffreio.4nkweb` sur le port 3000.
|
|
||||||
|
|
||||||
#### Configuration Nginx
|
|
||||||
|
|
||||||
Fichier: `conf/nginx/local.lecoffreio.4nkweb-3000.conf`
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 127.0.0.1:3000;
|
|
||||||
server_name local.lecoffreio.4nkweb;
|
|
||||||
|
|
||||||
# Pas de redirection HTTPS ni HSTS
|
|
||||||
|
|
||||||
location = /favicon.ico {
|
|
||||||
root /home/debian/lecoffre_node/conf/nginx/assets;
|
|
||||||
}
|
|
||||||
|
|
||||||
location = /lecoffre {
|
|
||||||
proxy_pass http://127.0.0.2:3004;
|
|
||||||
include /etc/nginx/proxy_params;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto http;
|
|
||||||
proxy_set_header X-Forwarded-Prefix /lecoffre;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /lecoffre/ {
|
|
||||||
proxy_pass http://127.0.0.2:3004;
|
|
||||||
include /etc/nginx/proxy_params;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto http;
|
|
||||||
proxy_set_header X-Forwarded-Prefix /lecoffre;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /lecoffre/_next/webpack-hmr {
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto http;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_pass http://127.0.0.2:3004/lecoffre/_next/webpack-hmr;
|
|
||||||
proxy_read_timeout 600s;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~* ^(/_next/static/|/lecoffre/_next/static/|/.+\.(?:css|js|png|jpg|jpeg|gif|svg|ico|webp|woff2?))$ {
|
|
||||||
expires 7d;
|
|
||||||
add_header Cache-Control "public, max-age=604800, immutable" always;
|
|
||||||
proxy_pass http://127.0.0.2:3004$request_uri;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto http;
|
|
||||||
proxy_read_timeout 300;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Activation: lien symbolique vers `/etc/nginx/sites-enabled/local.lecoffreio.4nkweb-3000.conf` puis `sudo nginx -t && sudo systemctl reload nginx`.
|
|
||||||
|
|
||||||
#### DNS local
|
|
||||||
|
|
||||||
Ajouter dans `/etc/hosts`:
|
|
||||||
|
|
||||||
```
|
|
||||||
127.0.0.1 local.lecoffreio.4nkweb
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Variables d’environnement recommandées (local HTTP)
|
|
||||||
|
|
||||||
```
|
|
||||||
NEXT_PUBLIC_4NK_URL=http://local.lecoffreio.4nkweb:3000
|
|
||||||
NEXT_PUBLIC_FRONT_APP_HOST=local.lecoffreio.4nkweb
|
|
||||||
NEXT_PUBLIC_FRONT_APP_PORT=3000
|
|
||||||
NEXT_PUBLIC_FRONT_APP_ROOT_URL=/lecoffre
|
|
||||||
NEXT_PUBLIC_ANK_BASE_REDIRECT_URI=http://local.lecoffreio.4nkweb:3000/authorized-client
|
|
||||||
NEXT_PUBLIC_4NK_IFRAME_URL=http://local.lecoffreio.4nkweb:3000/lecoffre
|
|
||||||
```
|
|
||||||
|
|
||||||
Note cookies: en HTTP, les cookies marqués `Secure` ne sont pas envoyés. Adapter la config backend en conséquence pour ce domaine local.
|
|
||||||
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
# Redéploiement du miner Signet
|
|
||||||
|
|
||||||
## Pré-requis
|
|
||||||
- Conteneurs `bitcoin-signet` (signet) et `signet_miner`.
|
|
||||||
- Fichier d'environnement `miner/.env` (voir variables ci-dessous).
|
|
||||||
|
|
||||||
## Variables (miner/.env)
|
|
||||||
- RPC_HOST, RPC_PORT
|
|
||||||
- WATCHONLY_WALLET, MINING_WALLET, MINER_TAG
|
|
||||||
- SIGNET_CHALLENGE, SIGNET_MAGIC
|
|
||||||
- MINING_FINGERPRINT, MINING_XPRV, MINING_PATH_PREFIX (ex: `48'/1'/0'/2'`)
|
|
||||||
- COINBASE_INDEX (ex: 0)
|
|
||||||
- COINBASE_ADDRESS (laisser vide, sera rempli par le script)
|
|
||||||
- BITCOIN_CONTAINER (ex: `bitcoin-signet`)
|
|
||||||
- CHALLENGE_ALLPUBS (optionnel: descripteur sortedmulti complet du challenge)
|
|
||||||
|
|
||||||
## Import des descripteurs
|
|
||||||
```bash
|
|
||||||
cd miner
|
|
||||||
./tools/import_signet_descriptors.sh
|
|
||||||
```
|
|
||||||
- Crée/recée `mining_mnemonic` en mode descriptors si nécessaire
|
|
||||||
- Importe les descripteurs privés external(0/*) et internal(1/*)
|
|
||||||
- Importe en option le descripteur complet du challenge (avec remplacement tpub->xprv de notre clé)
|
|
||||||
- Renseigne `COINBASE_ADDRESS` si vide (via `getnewaddress`)
|
|
||||||
|
|
||||||
## Lancement du miner
|
|
||||||
```bash
|
|
||||||
docker compose stop signet_miner
|
|
||||||
docker compose up -d --build signet_miner
|
|
||||||
```
|
|
||||||
|
|
||||||
## Vérifications
|
|
||||||
- `docker logs --tail=100 signet_miner`
|
|
||||||
- Succès: lignes `Mined block at height ...` (fin de `PSBT signing failed`)
|
|
||||||
|
|
||||||
## REX technique
|
|
||||||
- Problème: `Cannot import descriptor without private keys...` => causé par l’usage du descripteur normalisé renvoyé par `getdescriptorinfo` (tpub). Solution: conserver xprv + ajouter checksum `#xxxxxx`.
|
|
||||||
- Problème: wallet non-descriptor existant => recréer en descriptors (unload + rm -rf du répertoire wallet) avant import.
|
|
@ -1,138 +0,0 @@
|
|||||||
# Partage des Rewards entre Miner et Relay
|
|
||||||
|
|
||||||
## Vue d'ensemble
|
|
||||||
|
|
||||||
Cette fonctionnalité permet au miner signet de partager automatiquement les rewards de bloc avec le relay. Quand le miner gagne un bloc, il envoie une partie des rewards (configurable) au relay.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
### Variables d'environnement
|
|
||||||
|
|
||||||
Dans le fichier `miner/miner.env` :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Adresse du miner pour recevoir sa part des rewards
|
|
||||||
COINBASE_ADDRESS=tb1qminer123456789012345678901234567890
|
|
||||||
|
|
||||||
# Adresse du relay pour recevoir sa part des rewards
|
|
||||||
RELAY_ADDRESS=tb1qrelay123456789012345678901234567890
|
|
||||||
|
|
||||||
# Ratio de partage (0.0 = 0%, 0.5 = 50%, 1.0 = 100%)
|
|
||||||
REWARD_SPLIT_RATIO=0.5
|
|
||||||
```
|
|
||||||
|
|
||||||
### Paramètres de ligne de commande
|
|
||||||
|
|
||||||
Le miner accepte également ces paramètres :
|
|
||||||
|
|
||||||
```bash
|
|
||||||
--relay-address ADDRESS # Adresse du relay
|
|
||||||
--reward-split-ratio RATIO # Ratio de partage (0.0-1.0)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Fonctionnement
|
|
||||||
|
|
||||||
### Mécanisme de partage
|
|
||||||
|
|
||||||
1. **Détection du bloc** : Le miner détecte qu'il a gagné un bloc
|
|
||||||
2. **Calcul des rewards** : Le reward total est divisé selon le ratio configuré
|
|
||||||
3. **Création de la coinbase** : La transaction coinbase est créée avec deux sorties :
|
|
||||||
- Sortie 1 : Reward pour le miner (1 - ratio)
|
|
||||||
- Sortie 2 : Reward pour le relay (ratio)
|
|
||||||
|
|
||||||
### Exemple de partage
|
|
||||||
|
|
||||||
Avec `REWARD_SPLIT_RATIO=0.5` et un reward de bloc de 5 BTC :
|
|
||||||
- **Miner** : 2.5 BTC (50%)
|
|
||||||
- **Relay** : 2.5 BTC (50%)
|
|
||||||
|
|
||||||
## Code modifié
|
|
||||||
|
|
||||||
### Fonction `create_coinbase`
|
|
||||||
|
|
||||||
```python
|
|
||||||
def create_coinbase(height, value, spk, miner_tag='', relay_spk=None, reward_split_ratio=0.5):
|
|
||||||
# ... code existant ...
|
|
||||||
|
|
||||||
# Diviser les rewards entre miner et relay si relay_spk est fourni
|
|
||||||
if relay_spk is not None and reward_split_ratio > 0:
|
|
||||||
miner_value = int(value * (1 - reward_split_ratio))
|
|
||||||
relay_value = int(value * reward_split_ratio)
|
|
||||||
cb.vout = [
|
|
||||||
CTxOut(miner_value, spk), # Reward pour le miner
|
|
||||||
CTxOut(relay_value, relay_spk) # Reward pour le relay
|
|
||||||
]
|
|
||||||
logging.info(f"Coinbase split: miner={miner_value} sat, relay={relay_value} sat")
|
|
||||||
else:
|
|
||||||
cb.vout = [CTxOut(value, spk)]
|
|
||||||
|
|
||||||
return cb
|
|
||||||
```
|
|
||||||
|
|
||||||
### Gestion des adresses
|
|
||||||
|
|
||||||
Le miner gère automatiquement les cas où :
|
|
||||||
- L'adresse du relay n'est pas dans le wallet du miner
|
|
||||||
- L'adresse du relay est invalide
|
|
||||||
- Le wallet du relay n'est pas accessible
|
|
||||||
|
|
||||||
Dans ces cas, le miner utilise une adresse simple pour éviter les erreurs.
|
|
||||||
|
|
||||||
## Logs
|
|
||||||
|
|
||||||
Le miner affiche des logs détaillés :
|
|
||||||
|
|
||||||
```
|
|
||||||
2025-09-20 02:03:20 INFO Coinbase split: miner=2500000000 sat, relay=2500000000 sat
|
|
||||||
```
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
### Test de base
|
|
||||||
|
|
||||||
1. Démarrer le miner avec `REWARD_SPLIT_RATIO=0.5`
|
|
||||||
2. Vérifier les logs pour confirmer le partage
|
|
||||||
3. Vérifier que la transaction coinbase a deux sorties
|
|
||||||
|
|
||||||
### Test avec différents ratios
|
|
||||||
|
|
||||||
- `REWARD_SPLIT_RATIO=0.0` : Pas de partage (comportement original)
|
|
||||||
- `REWARD_SPLIT_RATIO=0.5` : Partage égal (50/50)
|
|
||||||
- `REWARD_SPLIT_RATIO=1.0` : Tout au relay (100%)
|
|
||||||
|
|
||||||
## Avantages
|
|
||||||
|
|
||||||
1. **Automatique** : Le partage se fait automatiquement à chaque bloc
|
|
||||||
2. **Configurable** : Le ratio peut être ajusté selon les besoins
|
|
||||||
3. **Robuste** : Gestion des erreurs et des cas limites
|
|
||||||
4. **Transparent** : Logs détaillés pour le suivi
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
1. **Adresses externes** : Les adresses du relay doivent être valides
|
|
||||||
2. **Wallet du miner** : Le miner doit avoir accès à son wallet
|
|
||||||
3. **Réseau** : Fonctionne uniquement en mode signet
|
|
||||||
|
|
||||||
## Utilisation
|
|
||||||
|
|
||||||
Pour activer le partage des rewards :
|
|
||||||
|
|
||||||
1. Configurer `RELAY_ADDRESS` dans `miner/miner.env`
|
|
||||||
2. Définir `REWARD_SPLIT_RATIO` (ex: 0.5 pour 50%)
|
|
||||||
3. Redémarrer le miner
|
|
||||||
4. Surveiller les logs pour confirmer le fonctionnement
|
|
||||||
|
|
||||||
## Exemple de configuration complète
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# miner/miner.env
|
|
||||||
COINBASE_ADDRESS=tb1qminer123456789012345678901234567890
|
|
||||||
RELAY_ADDRESS=tsp1qqfzxxz9fht9w8pg9q8z0zseynt2prapktyx4eylm4jlwg5mukqg95qnmm2va956rhggul4vspjda368nlzvufahx70n67z66a2vgs5lspytmuvty
|
|
||||||
REWARD_SPLIT_RATIO=0.5
|
|
||||||
```
|
|
||||||
|
|
||||||
Cette configuration partagera 50% des rewards avec le relay à chaque bloc miné.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,165 +0,0 @@
|
|||||||
# Retours d'Expérience - LeCoffre Node
|
|
||||||
|
|
||||||
Ce répertoire contient tous les retours d'expérience (REX) documentés lors du développement et de la maintenance du projet LeCoffre Node.
|
|
||||||
|
|
||||||
## 📋 Liste des REX
|
|
||||||
|
|
||||||
### 1. [REX_BOOTSTRAP_WEBSOCKET.md](./REX_BOOTSTRAP_WEBSOCKET.md)
|
|
||||||
**Problème** : Bootstrap WebSocket et réception de fonds du faucet
|
|
||||||
- Configuration bootstrap incorrecte
|
|
||||||
- Diagnostic des fonds insuffisants
|
|
||||||
- Solution avec adresse SP permanente
|
|
||||||
|
|
||||||
### 2. [REX_DOCKER_TOOLS_INSTALLATION.md](./REX_DOCKER_TOOLS_INSTALLATION.md)
|
|
||||||
**Problème** : Installation d'outils dans les conteneurs Docker
|
|
||||||
- Gestion des différentes images de base (Debian, Alpine, BusyBox)
|
|
||||||
- Solutions pour les permissions et les erreurs d'installation
|
|
||||||
- Scripts automatisés d'installation
|
|
||||||
|
|
||||||
### 3. [REX_STARTUP_SEQUENCE_IMPROVEMENTS.md](./REX_STARTUP_SEQUENCE_IMPROVEMENTS.md)
|
|
||||||
**Problème** : Améliorations de la séquence de démarrage
|
|
||||||
- Gestion des dépendances entre services
|
|
||||||
- Healthchecks robustes
|
|
||||||
- Scripts de démarrage intelligent
|
|
||||||
|
|
||||||
### 4. [REX_CONFIGURATION_MANAGEMENT.md](./REX_CONFIGURATION_MANAGEMENT.md)
|
|
||||||
**Problème** : Gestion des configurations
|
|
||||||
- Écriture non effective des fichiers de configuration
|
|
||||||
- Vérification systématique des configurations
|
|
||||||
- Gestion des permissions et variables d'environnement
|
|
||||||
|
|
||||||
## 🎯 Objectifs des REX
|
|
||||||
|
|
||||||
### 1. **Éviter la répétition d'erreurs**
|
|
||||||
- Documenter les problèmes rencontrés et leurs solutions
|
|
||||||
- Créer des scripts automatisés pour les tâches récurrentes
|
|
||||||
- Établir des bonnes pratiques
|
|
||||||
|
|
||||||
### 2. **Améliorer la maintenance**
|
|
||||||
- Faciliter le debugging pour les futurs développeurs
|
|
||||||
- Standardiser les procédures de déploiement
|
|
||||||
- Automatiser les vérifications
|
|
||||||
|
|
||||||
### 3. **Partager les connaissances**
|
|
||||||
- Transmettre l'expérience acquise
|
|
||||||
- Documenter les solutions techniques
|
|
||||||
- Créer une base de connaissances
|
|
||||||
|
|
||||||
## 🔧 Utilisation des REX
|
|
||||||
|
|
||||||
### 1. **Avant de commencer un développement**
|
|
||||||
- Consulter les REX pertinents
|
|
||||||
- Vérifier les bonnes pratiques établies
|
|
||||||
- Utiliser les scripts automatisés
|
|
||||||
|
|
||||||
### 2. **En cas de problème**
|
|
||||||
- Rechercher dans les REX des solutions similaires
|
|
||||||
- Suivre les procédures de diagnostic documentées
|
|
||||||
- Utiliser les scripts de vérification
|
|
||||||
|
|
||||||
### 3. **Après résolution d'un problème**
|
|
||||||
- Documenter la solution dans un nouveau REX
|
|
||||||
- Mettre à jour les scripts existants si nécessaire
|
|
||||||
- Partager les bonnes pratiques
|
|
||||||
|
|
||||||
## 📚 Structure des REX
|
|
||||||
|
|
||||||
Chaque REX suit la même structure :
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Titre du REX
|
|
||||||
|
|
||||||
## Problème initial
|
|
||||||
- Description du problème rencontré
|
|
||||||
- Impact sur le système
|
|
||||||
- Cause identifiée
|
|
||||||
|
|
||||||
## Diagnostic effectué
|
|
||||||
- Étapes de diagnostic
|
|
||||||
- Outils utilisés
|
|
||||||
- Résultats obtenus
|
|
||||||
|
|
||||||
## Solutions implémentées
|
|
||||||
- Solutions techniques
|
|
||||||
- Scripts créés
|
|
||||||
- Configurations modifiées
|
|
||||||
|
|
||||||
## Leçons apprises
|
|
||||||
- Bonnes pratiques établies
|
|
||||||
- Actions préventives
|
|
||||||
- Recommandations
|
|
||||||
|
|
||||||
## Scripts et outils
|
|
||||||
- Scripts automatisés
|
|
||||||
- Outils de diagnostic
|
|
||||||
- Procédures de vérification
|
|
||||||
|
|
||||||
## Date
|
|
||||||
- Date de création
|
|
||||||
- Problème résolu
|
|
||||||
- Impact
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🚀 Scripts automatisés
|
|
||||||
|
|
||||||
### Scripts de diagnostic
|
|
||||||
- `verify_config_writing.sh` : Vérification des écritures de configuration
|
|
||||||
- `verify_all_configs.sh` : Vérification complète des configurations
|
|
||||||
- `verify_env_vars.sh` : Vérification des variables d'environnement
|
|
||||||
|
|
||||||
### Scripts d'installation
|
|
||||||
- `install_tools_debian.sh` : Installation d'outils sur Debian/Ubuntu
|
|
||||||
- `install_tools_alpine.sh` : Installation d'outils sur Alpine
|
|
||||||
|
|
||||||
### Scripts de démarrage
|
|
||||||
- `startup-sequence.sh` : Démarrage intelligent des services
|
|
||||||
- `validate_external_dependencies.sh` : Validation des dépendances externes
|
|
||||||
|
|
||||||
## 📝 Contribution aux REX
|
|
||||||
|
|
||||||
### 1. **Créer un nouveau REX**
|
|
||||||
- Suivre la structure standard
|
|
||||||
- Documenter le problème et la solution
|
|
||||||
- Inclure les scripts et configurations
|
|
||||||
|
|
||||||
### 2. **Mettre à jour un REX existant**
|
|
||||||
- Ajouter les nouvelles informations
|
|
||||||
- Mettre à jour les scripts si nécessaire
|
|
||||||
- Documenter les évolutions
|
|
||||||
|
|
||||||
### 3. **Maintenir les REX**
|
|
||||||
- Vérifier la pertinence des informations
|
|
||||||
- Mettre à jour les scripts
|
|
||||||
- Nettoyer les informations obsolètes
|
|
||||||
|
|
||||||
## 🔍 Recherche dans les REX
|
|
||||||
|
|
||||||
### Par problème
|
|
||||||
- **Bootstrap WebSocket** : REX_BOOTSTRAP_WEBSOCKET.md
|
|
||||||
- **Installation Docker** : REX_DOCKER_TOOLS_INSTALLATION.md
|
|
||||||
- **Démarrage services** : REX_STARTUP_SEQUENCE_IMPROVEMENTS.md
|
|
||||||
- **Configuration** : REX_CONFIGURATION_MANAGEMENT.md
|
|
||||||
|
|
||||||
### Par solution
|
|
||||||
- **Scripts automatisés** : Voir la section "Scripts et outils" de chaque REX
|
|
||||||
- **Configurations** : Voir la section "Solutions implémentées"
|
|
||||||
- **Bonnes pratiques** : Voir la section "Leçons apprises"
|
|
||||||
|
|
||||||
## 📅 Historique
|
|
||||||
|
|
||||||
- **2025-09-20** : Création du répertoire REX
|
|
||||||
- **2025-09-20** : Documentation des 4 premiers REX
|
|
||||||
- **2025-09-20** : Création des scripts automatisés
|
|
||||||
|
|
||||||
## 🎯 Prochaines étapes
|
|
||||||
|
|
||||||
1. **Automatiser** la création de REX
|
|
||||||
2. **Intégrer** les REX dans le processus de développement
|
|
||||||
3. **Créer** des templates pour les nouveaux REX
|
|
||||||
4. **Mettre en place** un système de recherche avancée
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Note** : Ce répertoire est un élément clé de la maintenance et de l'amélioration continue du projet LeCoffre Node. Il doit être maintenu à jour et enrichi à chaque nouvelle expérience.
|
|
||||||
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
|||||||
# Retour d'Expérience : Bootstrap WebSocket et Faucet
|
|
||||||
|
|
||||||
## Problème initial
|
|
||||||
- **Erreur** : "Failed to create pairing process: Insufficient funds. Missing 1096 sats."
|
|
||||||
- **Cause** : Le relai local n'avait pas de fonds car le bootstrap ne fonctionnait pas correctement
|
|
||||||
- **Impact** : Impossible de faire du pairing d'appareils
|
|
||||||
|
|
||||||
## Diagnostic effectué
|
|
||||||
|
|
||||||
### 1. Configuration bootstrap incorrecte
|
|
||||||
```bash
|
|
||||||
# ❌ Configuration initiale (incorrecte)
|
|
||||||
bootstrap_url="ws://dev3.4nkweb.com:8090"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Tests de connectivité
|
|
||||||
- **Port 8090** : Accessible mais pas de faucet WebSocket
|
|
||||||
- **Port 443** : 502 Bad Gateway
|
|
||||||
- **Port 8080** : Service Express.js sans routes signer/websocket
|
|
||||||
|
|
||||||
### 3. Solution trouvée
|
|
||||||
```bash
|
|
||||||
# ✅ Configuration corrigée
|
|
||||||
bootstrap_url="wss://dev3.4nkweb.com/ws/"
|
|
||||||
bootstrap_faucet=true
|
|
||||||
```
|
|
||||||
|
|
||||||
## Leçons apprises
|
|
||||||
|
|
||||||
### 1. Vérification des endpoints WebSocket
|
|
||||||
- **Toujours tester** : `wscat -c wss://domain/ws/` avant configuration
|
|
||||||
- **Vérifier le protocole** : WSS (sécurisé) vs WS (non sécurisé)
|
|
||||||
- **Tester le faucet** : Envoyer une requête faucet et vérifier la réponse
|
|
||||||
|
|
||||||
### 2. Configuration des adresses SP permanentes
|
|
||||||
```bash
|
|
||||||
# ✅ Ajouter dans sdk_relay.conf
|
|
||||||
sp_address="tsp1qqgmwp9n5p9ujhq2j6cfqe4jpkyu70jh9rgj0pwt3ndezk2mrlvw6jqew8fhsulewzglfr7g2aa48wyj4n0r7yasa3fm666vda8984ke8tuaf9m89"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Diagnostic des fonds
|
|
||||||
- **Vérifier le wallet** : `docker exec sdk_relay cat /home/bitcoin/.4nk/default | jq '.outputs'`
|
|
||||||
- **Vérifier la maturité** : Les fonds minés localement peuvent être immatures
|
|
||||||
- **Utiliser le faucet distant** : Plus fiable que le minage local pour les tests
|
|
||||||
|
|
||||||
## Scripts de diagnostic
|
|
||||||
|
|
||||||
### Test de connectivité WebSocket
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# Test de connectivité WebSocket bootstrap
|
|
||||||
echo "Test de connectivité WebSocket..."
|
|
||||||
timeout 10 wscat -c wss://dev3.4nkweb.com/ws/ -x '{"type":"faucet","address":"test"}' || echo "Échec de connexion"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Vérification des fonds du relai
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# Vérification des fonds du relai
|
|
||||||
echo "Vérification des fonds du relai..."
|
|
||||||
docker exec sdk_relay cat /home/bitcoin/.4nk/default | jq '.outputs | length'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration recommandée
|
|
||||||
|
|
||||||
### sdk_relay.conf
|
|
||||||
```ini
|
|
||||||
# Configuration bootstrap WebSocket
|
|
||||||
bootstrap_url="wss://dev3.4nkweb.com/ws/"
|
|
||||||
bootstrap_faucet=true
|
|
||||||
|
|
||||||
# Adresse SP permanente (optionnel mais recommandé)
|
|
||||||
sp_address="tsp1qqgmwp9n5p9ujhq2j6cfqe4jpkyu70jh9rgj0pwt3ndezk2mrlvw6jqew8fhsulewzglfr7g2aa48wyj4n0r7yasa3fm666vda8984ke8tuaf9m89"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Actions préventives
|
|
||||||
|
|
||||||
1. **Toujours tester** la connectivité WebSocket avant déploiement
|
|
||||||
2. **Configurer une adresse SP permanente** pour éviter les changements d'adresse
|
|
||||||
3. **Vérifier les fonds** du relai après démarrage
|
|
||||||
4. **Documenter les endpoints** de faucet fonctionnels
|
|
||||||
5. **Tester le pairing** après chaque modification de configuration
|
|
||||||
|
|
||||||
## Date
|
|
||||||
- **Créé** : 2025-09-20
|
|
||||||
- **Problème résolu** : Bootstrap WebSocket et réception de fonds
|
|
||||||
- **Impact** : Résolution du problème de fonds insuffisants pour le pairing
|
|
||||||
|
|
||||||
|
|
@ -1,272 +0,0 @@
|
|||||||
# Retour d'Expérience : Gestion des configurations
|
|
||||||
|
|
||||||
## Problème initial
|
|
||||||
- **Erreurs** : Fichiers de configuration non écrits correctement
|
|
||||||
- **Impact** : Services ne démarrent pas avec les bonnes configurations
|
|
||||||
- **Cause** : Écriture non effective des fichiers de configuration
|
|
||||||
|
|
||||||
## Erreurs rencontrées
|
|
||||||
|
|
||||||
### 1. Fichiers de configuration non écrits
|
|
||||||
```bash
|
|
||||||
# ❌ Problème : Écriture non effective
|
|
||||||
echo "bootstrap_url=wss://dev3.4nkweb.com/ws/" >> relay/sdk_relay.conf
|
|
||||||
# Le fichier n'était pas mis à jour correctement
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Permissions insuffisantes
|
|
||||||
```bash
|
|
||||||
# ❌ Erreur
|
|
||||||
sed: cannot rename /home/bitcoin/sedktvYLI: Device or resource busy
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Variables d'environnement non prises en compte
|
|
||||||
```bash
|
|
||||||
# ❌ Problème : .env override docker-compose.yml
|
|
||||||
# docker-compose.yml
|
|
||||||
environment:
|
|
||||||
- SIGNER_WS_URL=ws://dev3.4nkweb.com:9090
|
|
||||||
|
|
||||||
# .env (override)
|
|
||||||
SIGNER_WS_URL=ws://sdk_signer:9090
|
|
||||||
```
|
|
||||||
|
|
||||||
## Solutions implémentées
|
|
||||||
|
|
||||||
### 1. Vérification systématique des écritures
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# verify_config_writing.sh
|
|
||||||
|
|
||||||
# Fonction de vérification
|
|
||||||
verify_config_file() {
|
|
||||||
local file="$1"
|
|
||||||
local expected_content="$2"
|
|
||||||
|
|
||||||
echo "Vérification de $file..."
|
|
||||||
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
if grep -q "$expected_content" "$file"; then
|
|
||||||
echo "✅ $file contient '$expected_content'"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo "❌ $file ne contient pas '$expected_content'"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "❌ $file n'existe pas"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Vérifications
|
|
||||||
verify_config_file "relay/sdk_relay.conf" "bootstrap_url=\"wss://dev3.4nkweb.com/ws/\""
|
|
||||||
verify_config_file "relay/sdk_relay.conf" "sp_address="
|
|
||||||
verify_config_file ".env" "RELAY_URLS=ws://sdk_relay:8090"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Écriture atomique des configurations
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# atomic_config_update.sh
|
|
||||||
|
|
||||||
# Fonction d'écriture atomique
|
|
||||||
atomic_write_config() {
|
|
||||||
local file="$1"
|
|
||||||
local content="$2"
|
|
||||||
local temp_file="${file}.tmp"
|
|
||||||
|
|
||||||
echo "Mise à jour atomique de $file..."
|
|
||||||
|
|
||||||
# Écriture dans un fichier temporaire
|
|
||||||
echo "$content" > "$temp_file"
|
|
||||||
|
|
||||||
# Vérification de l'écriture
|
|
||||||
if [ -f "$temp_file" ] && [ -s "$temp_file" ]; then
|
|
||||||
# Remplacement atomique
|
|
||||||
mv "$temp_file" "$file"
|
|
||||||
echo "✅ $file mis à jour avec succès"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo "❌ Échec de l'écriture de $file"
|
|
||||||
rm -f "$temp_file"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exemple d'utilisation
|
|
||||||
atomic_write_config "relay/sdk_relay.conf" "bootstrap_url=\"wss://dev3.4nkweb.com/ws/\""
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Gestion des permissions
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# fix_config_permissions.sh
|
|
||||||
|
|
||||||
# Correction des permissions
|
|
||||||
fix_permissions() {
|
|
||||||
local file="$1"
|
|
||||||
|
|
||||||
echo "Correction des permissions pour $file..."
|
|
||||||
|
|
||||||
# Vérifier si le fichier existe
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
# Corriger les permissions
|
|
||||||
chmod 644 "$file"
|
|
||||||
chown $(whoami):$(whoami) "$file"
|
|
||||||
echo "✅ Permissions corrigées pour $file"
|
|
||||||
else
|
|
||||||
echo "❌ $file n'existe pas"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Correction des permissions pour tous les fichiers de config
|
|
||||||
fix_permissions "relay/sdk_relay.conf"
|
|
||||||
fix_permissions ".env"
|
|
||||||
fix_permissions "docker-compose.yml"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Règles Cursor ajoutées
|
|
||||||
|
|
||||||
### Règle de vérification des configurations
|
|
||||||
```markdown
|
|
||||||
# RÈGLE CRITIQUE : Vérification des Fichiers de Configuration
|
|
||||||
- TOUJOURS vérifier l'écriture effective des fichiers de configuration critiques après modification
|
|
||||||
- Fichiers à vérifier systématiquement : nginx.conf, bitcoin.conf, package.json, Cargo.toml
|
|
||||||
- Utiliser des commandes de vérification (cat, jq, syntax check) pour s'assurer que l'écriture a été effective
|
|
||||||
- Cette règle évite les erreurs de configuration dues à des écritures non effectives
|
|
||||||
```
|
|
||||||
|
|
||||||
## Scripts de vérification
|
|
||||||
|
|
||||||
### Vérification complète des configurations
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# verify_all_configs.sh
|
|
||||||
|
|
||||||
echo "=== Vérification des configurations ==="
|
|
||||||
|
|
||||||
# Vérification des fichiers de configuration
|
|
||||||
config_files=(
|
|
||||||
"relay/sdk_relay.conf"
|
|
||||||
".env"
|
|
||||||
"docker-compose.yml"
|
|
||||||
"miner/.env"
|
|
||||||
)
|
|
||||||
|
|
||||||
for file in "${config_files[@]}"; do
|
|
||||||
if [ -f "$file" ]; then
|
|
||||||
echo "✅ $file existe"
|
|
||||||
|
|
||||||
# Vérification de la syntaxe
|
|
||||||
case "$file" in
|
|
||||||
*.conf)
|
|
||||||
echo " Vérification de la syntaxe..."
|
|
||||||
# Pas de vérification spécifique pour .conf
|
|
||||||
;;
|
|
||||||
*.yml|*.yaml)
|
|
||||||
echo " Vérification de la syntaxe YAML..."
|
|
||||||
if command -v yq >/dev/null 2>&1; then
|
|
||||||
yq eval '.' "$file" >/dev/null && echo " ✅ Syntaxe YAML valide" || echo " ❌ Syntaxe YAML invalide"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*.json)
|
|
||||||
echo " Vérification de la syntaxe JSON..."
|
|
||||||
jq '.' "$file" >/dev/null && echo " ✅ Syntaxe JSON valide" || echo " ❌ Syntaxe JSON invalide"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
echo "❌ $file n'existe pas"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
### Vérification des variables d'environnement
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# verify_env_vars.sh
|
|
||||||
|
|
||||||
echo "=== Vérification des variables d'environnement ==="
|
|
||||||
|
|
||||||
# Vérification des variables critiques
|
|
||||||
critical_vars=(
|
|
||||||
"SIGNER_WS_URL"
|
|
||||||
"RELAY_URLS"
|
|
||||||
"SIGNER_BASE_URL"
|
|
||||||
"VITE_BOOTSTRAPURL"
|
|
||||||
)
|
|
||||||
|
|
||||||
for var in "${critical_vars[@]}"; do
|
|
||||||
if [ -f ".env" ]; then
|
|
||||||
if grep -q "^$var=" ".env"; then
|
|
||||||
value=$(grep "^$var=" ".env" | cut -d'=' -f2-)
|
|
||||||
echo "✅ $var=$value"
|
|
||||||
else
|
|
||||||
echo "❌ $var non définie dans .env"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "❌ Fichier .env non trouvé"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bonnes pratiques
|
|
||||||
|
|
||||||
### 1. Écriture des configurations
|
|
||||||
- **Utiliser** des écritures atomiques avec fichiers temporaires
|
|
||||||
- **Vérifier** l'écriture après chaque modification
|
|
||||||
- **Corriger** les permissions si nécessaire
|
|
||||||
|
|
||||||
### 2. Validation des configurations
|
|
||||||
- **Vérifier** la syntaxe des fichiers (JSON, YAML, etc.)
|
|
||||||
- **Tester** les configurations avant déploiement
|
|
||||||
- **Documenter** les changements de configuration
|
|
||||||
|
|
||||||
### 3. Gestion des variables d'environnement
|
|
||||||
- **Centraliser** les variables dans `.env`
|
|
||||||
- **Vérifier** les overrides entre `.env` et `docker-compose.yml`
|
|
||||||
- **Documenter** les variables critiques
|
|
||||||
|
|
||||||
## Scripts automatisés
|
|
||||||
|
|
||||||
### Mise à jour et vérification complète
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# update_and_verify_configs.sh
|
|
||||||
|
|
||||||
echo "=== Mise à jour et vérification des configurations ==="
|
|
||||||
|
|
||||||
# 1. Mise à jour des configurations
|
|
||||||
echo "Mise à jour des configurations..."
|
|
||||||
./atomic_config_update.sh
|
|
||||||
|
|
||||||
# 2. Correction des permissions
|
|
||||||
echo "Correction des permissions..."
|
|
||||||
./fix_config_permissions.sh
|
|
||||||
|
|
||||||
# 3. Vérification des configurations
|
|
||||||
echo "Vérification des configurations..."
|
|
||||||
./verify_all_configs.sh
|
|
||||||
|
|
||||||
# 4. Vérification des variables d'environnement
|
|
||||||
echo "Vérification des variables d'environnement..."
|
|
||||||
./verify_env_vars.sh
|
|
||||||
|
|
||||||
echo "=== Vérification terminée ==="
|
|
||||||
```
|
|
||||||
|
|
||||||
## Actions préventives
|
|
||||||
|
|
||||||
1. **Toujours vérifier** l'écriture effective des fichiers de configuration
|
|
||||||
2. **Utiliser** des écritures atomiques pour éviter les corruptions
|
|
||||||
3. **Corriger** les permissions après modification
|
|
||||||
4. **Valider** la syntaxe des fichiers de configuration
|
|
||||||
5. **Documenter** les changements de configuration
|
|
||||||
|
|
||||||
## Date
|
|
||||||
- **Créé** : 2025-09-20
|
|
||||||
- **Problème résolu** : Gestion des configurations et écriture effective
|
|
||||||
- **Impact** : Amélioration de la fiabilité des configurations
|
|
||||||
|
|
||||||
|
|
@ -1,181 +0,0 @@
|
|||||||
# Retour d'Expérience : Installation d'outils dans les conteneurs Docker
|
|
||||||
|
|
||||||
## Problème initial
|
|
||||||
- **Besoin** : Installer `curl`, `git`, `wget`, `jq`, `telnet`, `wscat`, `tee`, `npm` dans tous les conteneurs
|
|
||||||
- **Défi** : Différentes images de base (Debian, Alpine, BusyBox)
|
|
||||||
- **Erreurs** : Commandes `apt-get` dans des images Alpine, permissions insuffisantes
|
|
||||||
|
|
||||||
## Solutions développées
|
|
||||||
|
|
||||||
### 1. Détection des images de base
|
|
||||||
```bash
|
|
||||||
# Déterminer le type d'image
|
|
||||||
docker exec <container> cat /etc/os-release
|
|
||||||
# ou
|
|
||||||
docker exec <container> which apt-get # Debian/Ubuntu
|
|
||||||
docker exec <container> which apk # Alpine
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Installation adaptée par type d'image
|
|
||||||
|
|
||||||
#### Images Debian/Ubuntu
|
|
||||||
```dockerfile
|
|
||||||
RUN apt-get update && apt-get upgrade -y && \
|
|
||||||
apt-get install -y curl git wget jq telnet npm coreutils && \
|
|
||||||
npm install -g wscat && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /root/.npm
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Images Alpine
|
|
||||||
```dockerfile
|
|
||||||
RUN apk update && apk upgrade && \
|
|
||||||
apk add --no-cache curl git wget jq busybox-extras npm coreutils && \
|
|
||||||
npm install -g wscat && \
|
|
||||||
rm -rf /var/cache/apk/* /root/.npm
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Gestion des permissions
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml
|
|
||||||
services:
|
|
||||||
service_name:
|
|
||||||
user: root # Pour l'installation des outils
|
|
||||||
entrypoint: |
|
|
||||||
sh -c "
|
|
||||||
apt-get update && apt-get install -y curl git wget jq telnet npm coreutils && \
|
|
||||||
npm install -g wscat && \
|
|
||||||
exec su bitcoin -c '/usr/local/bin/service_binary'
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Erreurs rencontrées et solutions
|
|
||||||
|
|
||||||
### 1. "apt-get: not found" dans Alpine
|
|
||||||
```bash
|
|
||||||
# ❌ Erreur
|
|
||||||
apt-get install curl
|
|
||||||
|
|
||||||
# ✅ Solution
|
|
||||||
apk add --no-cache curl
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. "telnet: no such package" dans Alpine
|
|
||||||
```bash
|
|
||||||
# ❌ Erreur
|
|
||||||
apk add telnet
|
|
||||||
|
|
||||||
# ✅ Solution
|
|
||||||
apk add busybox-extras # Contient telnet
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Permissions insuffisantes
|
|
||||||
```bash
|
|
||||||
# ❌ Erreur
|
|
||||||
E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied)
|
|
||||||
|
|
||||||
# ✅ Solution
|
|
||||||
user: root # Dans docker-compose.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Binaires Node.js incorrects
|
|
||||||
```bash
|
|
||||||
# ❌ Erreur
|
|
||||||
exec /usr/local/bin/sdk_signer
|
|
||||||
|
|
||||||
# ✅ Solution
|
|
||||||
exec node /app/dist/index.js
|
|
||||||
```
|
|
||||||
|
|
||||||
## Scripts d'installation automatisés
|
|
||||||
|
|
||||||
### Script pour Debian/Ubuntu
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# install_tools_debian.sh
|
|
||||||
apt-get update && apt-get upgrade -y && \
|
|
||||||
apt-get install -y curl git wget jq telnet npm coreutils && \
|
|
||||||
npm install -g wscat && \
|
|
||||||
rm -rf /var/lib/apt/lists/* /root/.npm
|
|
||||||
```
|
|
||||||
|
|
||||||
### Script pour Alpine
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# install_tools_alpine.sh
|
|
||||||
apk update && apk upgrade && \
|
|
||||||
apk add --no-cache curl git wget jq busybox-extras npm coreutils && \
|
|
||||||
npm install -g wscat && \
|
|
||||||
rm -rf /var/cache/apk/* /root/.npm
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration docker-compose.yml optimisée
|
|
||||||
|
|
||||||
### Service avec installation d'outils
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
sdk_relay:
|
|
||||||
image: git.4nkweb.com/4nk/sdk_relay:ext
|
|
||||||
user: root
|
|
||||||
entrypoint: |
|
|
||||||
sh -c "
|
|
||||||
apt-get update && apt-get install -y curl git wget jq telnet npm coreutils && \
|
|
||||||
npm install -g wscat && \
|
|
||||||
exec su bitcoin -c '/usr/local/bin/sdk_relay --config /home/bitcoin/.conf'
|
|
||||||
"
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8091/"]
|
|
||||||
interval: 15s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
start_period: 60s
|
|
||||||
```
|
|
||||||
|
|
||||||
## Règles Cursor ajoutées
|
|
||||||
|
|
||||||
### Règle globale
|
|
||||||
```markdown
|
|
||||||
# RÈGLE CRITIQUE : Images Docker
|
|
||||||
- TOUJOURS ajouter systématiquement aux images Docker : apt update && apt upgrade
|
|
||||||
- TOUJOURS installer en arrière-plan : curl, git, sed, awk, nc wget, jq, telnet, tee, wscat, ping, npm (dernière version)
|
|
||||||
- Cette règle s'applique à tous les Dockerfiles des projets 4NK
|
|
||||||
```
|
|
||||||
|
|
||||||
## Bonnes pratiques
|
|
||||||
|
|
||||||
### 1. Intégration dans les Dockerfiles
|
|
||||||
- **Préférer** l'intégration dans le Dockerfile plutôt que l'entrypoint
|
|
||||||
- **Nettoyer** les caches après installation
|
|
||||||
- **Utiliser** des versions spécifiques des outils
|
|
||||||
|
|
||||||
### 2. Gestion des utilisateurs
|
|
||||||
- **Installer** en tant que root
|
|
||||||
- **Exécuter** le service principal avec l'utilisateur approprié
|
|
||||||
- **Utiliser** `su` pour changer d'utilisateur
|
|
||||||
|
|
||||||
### 3. Healthchecks
|
|
||||||
- **Utiliser** les outils installés dans les healthchecks
|
|
||||||
- **Vérifier** que les outils sont disponibles avant les tests
|
|
||||||
- **Configurer** des timeouts appropriés
|
|
||||||
|
|
||||||
## Outils installés par défaut
|
|
||||||
|
|
||||||
### Outils système
|
|
||||||
- `curl` : Tests HTTP/HTTPS
|
|
||||||
- `git` : Clonage de dépôts
|
|
||||||
- `wget` : Téléchargements
|
|
||||||
- `jq` : Parsing JSON
|
|
||||||
- `telnet` : Tests de connectivité
|
|
||||||
- `tee` : Redirection avec affichage
|
|
||||||
- `ping` : Tests réseau
|
|
||||||
- `nc` : Tests de ports
|
|
||||||
|
|
||||||
### Outils Node.js
|
|
||||||
- `npm` : Gestionnaire de packages Node.js
|
|
||||||
- `wscat` : Client WebSocket en ligne de commande
|
|
||||||
|
|
||||||
## Date
|
|
||||||
- **Créé** : 2025-09-20
|
|
||||||
- **Problème résolu** : Installation d'outils dans tous les conteneurs
|
|
||||||
- **Impact** : Amélioration du debugging et des tests de connectivité
|
|
||||||
|
|
||||||
|
|
@ -1,233 +0,0 @@
|
|||||||
# Retour d'Expérience : Améliorations de la séquence de démarrage
|
|
||||||
|
|
||||||
## Problème initial
|
|
||||||
- **Erreur** : `dependency failed to start: container sdk_relay is unhealthy`
|
|
||||||
- **Cause** : Le service `sdk_relay` bloquait sur le scan de blocs pendant le démarrage
|
|
||||||
- **Impact** : Les services dépendants ne pouvaient pas démarrer
|
|
||||||
|
|
||||||
## Diagnostic effectué
|
|
||||||
|
|
||||||
### 1. Analyse du code sdk_relay
|
|
||||||
```rust
|
|
||||||
// Problème identifié dans main.rs
|
|
||||||
let current_tip = get_blockchain_tip().await?;
|
|
||||||
let last_scan = get_last_scan().await?;
|
|
||||||
|
|
||||||
// ❌ Cette ligne bloquait le démarrage
|
|
||||||
scan_blocks(current_tip - last_scan, &config.blindbit_url).await?;
|
|
||||||
|
|
||||||
// Les serveurs WebSocket et HTTP étaient lancés APRÈS
|
|
||||||
let listener = TcpListener::bind(config.ws_url).await;
|
|
||||||
tokio::spawn(start_health_server(8091));
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Impact sur les services dépendants
|
|
||||||
- `ihm_client` : Dépend de `sdk_relay` healthy
|
|
||||||
- `lecoffre-back` : Dépend de `sdk_relay` healthy
|
|
||||||
- `lecoffre-front` : Dépend de `lecoffre-back` healthy
|
|
||||||
|
|
||||||
## Solutions implémentées
|
|
||||||
|
|
||||||
### 1. Amélioration des healthchecks
|
|
||||||
```yaml
|
|
||||||
# docker-compose.yml
|
|
||||||
services:
|
|
||||||
sdk_relay:
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "sh", "-c", "curl -f http://localhost:8091/ | grep -q '\"status\":\"ok\"'"]
|
|
||||||
interval: 15s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
start_period: 60s # ⭐ Temps d'attente avant les tests
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Variables d'environnement pour le démarrage
|
|
||||||
```yaml
|
|
||||||
environment:
|
|
||||||
- SDK_RELAY_SCAN_TIMEOUT=300
|
|
||||||
- SDK_RELAY_STARTUP_MODE=async
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Dépendances conditionnelles
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
ihm_client:
|
|
||||||
depends_on:
|
|
||||||
sdk_relay:
|
|
||||||
condition: service_healthy # ⭐ Attendre que sdk_relay soit healthy
|
|
||||||
|
|
||||||
lecoffre-back:
|
|
||||||
depends_on:
|
|
||||||
sdk_relay:
|
|
||||||
condition: service_healthy
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Script de démarrage intelligent
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# startup-sequence.sh
|
|
||||||
|
|
||||||
# Validation des dépendances externes
|
|
||||||
validate_external_dependencies() {
|
|
||||||
echo "Vérification des dépendances externes..."
|
|
||||||
|
|
||||||
# Test dev3.4nkweb.com:9090
|
|
||||||
timeout 5 bash -c "</dev/tcp/dev3.4nkweb.com/9090" || {
|
|
||||||
echo "❌ dev3.4nkweb.com:9090 inaccessible"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test https://dev4.4nkweb.com/lecoffre
|
|
||||||
curl -f -s https://dev4.4nkweb.com/lecoffre >/dev/null || {
|
|
||||||
echo "❌ https://dev4.4nkweb.com/lecoffre inaccessible"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "✅ Toutes les dépendances externes sont accessibles"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Démarrage des services
|
|
||||||
start_services() {
|
|
||||||
validate_external_dependencies || exit 1
|
|
||||||
docker compose up -d
|
|
||||||
wait_for_services_healthy
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Améliorations apportées
|
|
||||||
|
|
||||||
### 1. Healthchecks robustes
|
|
||||||
- **Tests réels** : Vérification du endpoint `/health` au lieu de simples tests de port
|
|
||||||
- **Timeouts appropriés** : `start_period` pour laisser le temps au service de démarrer
|
|
||||||
- **Retry logic** : Plusieurs tentatives avant de marquer comme unhealthy
|
|
||||||
|
|
||||||
### 2. Gestion des dépendances
|
|
||||||
- **Dépendances conditionnelles** : `condition: service_healthy`
|
|
||||||
- **Ordre de démarrage** : Services critiques en premier
|
|
||||||
- **Validation externe** : Vérification des services distants
|
|
||||||
|
|
||||||
### 3. Monitoring et debugging
|
|
||||||
- **Logs colorés** : Fonctions de logging avec couleurs
|
|
||||||
- **Validation préalable** : Tests de connectivité avant démarrage
|
|
||||||
- **Restart intelligent** : Arrêt des services dépendants avant redémarrage
|
|
||||||
|
|
||||||
## Scripts créés
|
|
||||||
|
|
||||||
### startup-sequence.sh
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# Script de démarrage intelligent avec validation
|
|
||||||
|
|
||||||
# Fonctions de logging
|
|
||||||
log() { echo -e "\033[1;34m[INFO]\033[0m $1"; }
|
|
||||||
log_success() { echo -e "\033[1;32m[SUCCESS]\033[0m $1"; }
|
|
||||||
log_warning() { echo -e "\033[1;33m[WARNING]\033[0m $1"; }
|
|
||||||
log_error() { echo -e "\033[1;31m[ERROR]\033[0m $1"; }
|
|
||||||
|
|
||||||
# Validation des dépendances externes
|
|
||||||
validate_external_dependencies() {
|
|
||||||
log "Vérification des dépendances externes..."
|
|
||||||
|
|
||||||
# Test signer distant
|
|
||||||
timeout 5 bash -c "</dev/tcp/dev3.4nkweb.com/9090" || {
|
|
||||||
log_error "dev3.4nkweb.com:9090 inaccessible"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test frontend
|
|
||||||
curl -f -s https://dev4.4nkweb.com/lecoffre >/dev/null || {
|
|
||||||
log_error "https://dev4.4nkweb.com/lecoffre inaccessible"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
log_success "Toutes les dépendances externes sont accessibles"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Démarrage des services
|
|
||||||
start_services() {
|
|
||||||
validate_external_dependencies || exit 1
|
|
||||||
docker compose up -d
|
|
||||||
wait_for_services_healthy
|
|
||||||
}
|
|
||||||
|
|
||||||
# Redémarrage intelligent
|
|
||||||
restart_services() {
|
|
||||||
log "Arrêt des services dépendants..."
|
|
||||||
docker compose stop lecoffre-back lecoffre-front ihm_client
|
|
||||||
|
|
||||||
log "Attente des dépendances externes..."
|
|
||||||
validate_external_dependencies || exit 1
|
|
||||||
|
|
||||||
log "Redémarrage des services..."
|
|
||||||
docker compose up -d
|
|
||||||
wait_for_services_healthy
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration finale
|
|
||||||
|
|
||||||
### docker-compose.yml optimisé
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
sdk_relay:
|
|
||||||
image: git.4nkweb.com/4nk/sdk_relay:ext
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "sh", "-c", "curl -f http://localhost:8091/ | grep -q '\"status\":\"ok\"'"]
|
|
||||||
interval: 15s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
start_period: 60s
|
|
||||||
environment:
|
|
||||||
- SDK_RELAY_SCAN_TIMEOUT=300
|
|
||||||
- SDK_RELAY_STARTUP_MODE=async
|
|
||||||
|
|
||||||
ihm_client:
|
|
||||||
depends_on:
|
|
||||||
sdk_relay:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:3003/"]
|
|
||||||
start_period: 30s
|
|
||||||
|
|
||||||
lecoffre-back:
|
|
||||||
depends_on:
|
|
||||||
sdk_relay:
|
|
||||||
condition: service_healthy
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"]
|
|
||||||
start_period: 30s
|
|
||||||
```
|
|
||||||
|
|
||||||
## Leçons apprises
|
|
||||||
|
|
||||||
### 1. Healthchecks critiques
|
|
||||||
- **Toujours implémenter** des healthchecks robustes
|
|
||||||
- **Tester les endpoints réels** plutôt que les ports
|
|
||||||
- **Configurer des timeouts** appropriés
|
|
||||||
|
|
||||||
### 2. Gestion des dépendances
|
|
||||||
- **Utiliser** `condition: service_healthy` pour les dépendances
|
|
||||||
- **Valider** les services externes avant démarrage
|
|
||||||
- **Implémenter** des scripts de redémarrage intelligent
|
|
||||||
|
|
||||||
### 3. Monitoring et debugging
|
|
||||||
- **Logs colorés** pour faciliter le debugging
|
|
||||||
- **Validation préalable** des dépendances
|
|
||||||
- **Scripts automatisés** pour les opérations courantes
|
|
||||||
|
|
||||||
## Actions préventives
|
|
||||||
|
|
||||||
1. **Implémenter** des healthchecks robustes dès le début
|
|
||||||
2. **Configurer** des dépendances conditionnelles
|
|
||||||
3. **Valider** les services externes avant démarrage
|
|
||||||
4. **Créer** des scripts de démarrage intelligent
|
|
||||||
5. **Documenter** les séquences de démarrage
|
|
||||||
|
|
||||||
## Date
|
|
||||||
- **Créé** : 2025-09-20
|
|
||||||
- **Problème résolu** : Séquence de démarrage des services
|
|
||||||
- **Impact** : Amélioration de la fiabilité et du debugging
|
|
||||||
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
# Outils installés
|
|
||||||
|
|
||||||
Date: 2025-09-16T14:01:39+00:00
|
|
||||||
|
|
||||||
## Versions
|
|
||||||
### Node.js
|
|
||||||
|
|
@ -7,7 +7,7 @@ set -e
|
|||||||
|
|
||||||
COMPOSE_FILE="docker-compose.yml"
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
GRAFANA_ADMIN_PASSWORD="${GRAFANA_ADMIN_PASSWORD:-admin123}"
|
GRAFANA_ADMIN_PASSWORD="${GRAFANA_ADMIN_PASSWORD:-admin123}"
|
||||||
GRAFANA_PORT="${GRAFANA_PORT:-3000}"
|
GRAFANA_PORT="${GRAFANA_PORT:-3005}"
|
||||||
LOKI_PORT="${LOKI_PORT:-3100}"
|
LOKI_PORT="${LOKI_PORT:-3100}"
|
||||||
|
|
||||||
# Couleurs pour les messages
|
# Couleurs pour les messages
|
||||||
|
55
scripts/deploy-status-page.sh
Executable file
55
scripts/deploy-status-page.sh
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script pour déployer la page de statut
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
WEB_ROOT="/var/www/lecoffre"
|
||||||
|
STATUS_DIR="$WEB_ROOT/status"
|
||||||
|
SOURCE_DIR="./web/status"
|
||||||
|
|
||||||
|
echo "🚀 Déploiement de la page de statut..."
|
||||||
|
|
||||||
|
# Création du répertoire web si nécessaire
|
||||||
|
sudo mkdir -p "$WEB_ROOT"
|
||||||
|
|
||||||
|
# Création du répertoire de statut
|
||||||
|
sudo mkdir -p "$STATUS_DIR"
|
||||||
|
|
||||||
|
# Copie des fichiers statiques
|
||||||
|
echo "📁 Copie des fichiers statiques..."
|
||||||
|
sudo cp -r "$SOURCE_DIR"/* "$STATUS_DIR/"
|
||||||
|
|
||||||
|
# Suppression des fichiers non nécessaires sur le serveur
|
||||||
|
sudo rm -f "$STATUS_DIR/api.js"
|
||||||
|
sudo rm -f "$STATUS_DIR/package.json"
|
||||||
|
sudo rm -f "$STATUS_DIR/Dockerfile"
|
||||||
|
|
||||||
|
# Permissions
|
||||||
|
echo "🔐 Configuration des permissions..."
|
||||||
|
sudo chown -R www-data:www-data "$STATUS_DIR"
|
||||||
|
sudo chmod -R 755 "$STATUS_DIR"
|
||||||
|
|
||||||
|
# Test de la configuration Nginx
|
||||||
|
echo "🔍 Test de la configuration Nginx..."
|
||||||
|
if sudo nginx -t; then
|
||||||
|
echo "✅ Configuration Nginx valide"
|
||||||
|
else
|
||||||
|
echo "❌ Erreur dans la configuration Nginx"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Rechargement de Nginx
|
||||||
|
echo "🔄 Rechargement de Nginx..."
|
||||||
|
sudo systemctl reload nginx
|
||||||
|
|
||||||
|
echo "✅ Page de statut déployée avec succès!"
|
||||||
|
echo ""
|
||||||
|
echo "🔗 URLs d'accès:"
|
||||||
|
echo " - Page de statut: https://dev4.4nkweb.com/status/"
|
||||||
|
echo " - API de statut: https://dev4.4nkweb.com/status/api"
|
||||||
|
echo ""
|
||||||
|
echo "📋 Prochaines étapes:"
|
||||||
|
echo "1. Construire et démarrer le service status-api: docker compose up -d status-api"
|
||||||
|
echo "2. Vérifier l'accès: curl https://dev4.4nkweb.com/status/"
|
||||||
|
echo "3. Tester l'API: curl https://dev4.4nkweb.com/status/api"
|
@ -7,7 +7,7 @@ echo "🔍 Test de connectivité du monitoring..."
|
|||||||
|
|
||||||
# Test Grafana
|
# Test Grafana
|
||||||
echo "Test Grafana..."
|
echo "Test Grafana..."
|
||||||
if curl -s http://localhost:3000/api/health >/dev/null 2>&1; then
|
if curl -s http://localhost:3005/api/health >/dev/null 2>&1; then
|
||||||
echo "✅ Grafana: OK"
|
echo "✅ Grafana: OK"
|
||||||
else
|
else
|
||||||
echo "❌ Grafana: Non accessible"
|
echo "❌ Grafana: Non accessible"
|
||||||
|
28
web/status/Dockerfile
Normal file
28
web/status/Dockerfile
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
# Mise à jour et installation des outils nécessaires
|
||||||
|
RUN apk update && apk upgrade && \
|
||||||
|
apk add --no-cache \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
gawk \
|
||||||
|
netcat-openbsd \
|
||||||
|
wget \
|
||||||
|
jq \
|
||||||
|
busybox-extras \
|
||||||
|
docker-cli
|
||||||
|
|
||||||
|
# Création du répertoire de travail
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copie des fichiers
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Installation des dépendances Node.js
|
||||||
|
RUN npm install express
|
||||||
|
|
||||||
|
# Exposition du port
|
||||||
|
EXPOSE 3006
|
||||||
|
|
||||||
|
# Commande de démarrage
|
||||||
|
CMD ["node", "api.js"]
|
206
web/status/api.js
Normal file
206
web/status/api.js
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
const util = require('util');
|
||||||
|
const execAsync = util.promisify(exec);
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const PORT = 3006;
|
||||||
|
|
||||||
|
// Middleware CORS
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
|
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
||||||
|
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Services à surveiller
|
||||||
|
const services = [
|
||||||
|
{ name: 'Bitcoin Signet', container: 'bitcoin', port: 8332, protocol: 'RPC' },
|
||||||
|
{ name: 'BlindBit Oracle', container: 'blindbit', port: 8000, protocol: 'HTTP' },
|
||||||
|
{ name: 'SDK Relay', container: 'sdk_relay', port: 8090, protocol: 'WebSocket' },
|
||||||
|
{ name: 'SDK Signer', container: 'sdk_signer', port: 9090, protocol: 'WebSocket' },
|
||||||
|
{ name: 'SDK Storage', container: 'sdk_storage', port: 8080, protocol: 'HTTP' },
|
||||||
|
{ name: 'LeCoffre Backend', container: 'lecoffre-back', port: 8080, protocol: 'HTTP' },
|
||||||
|
{ name: 'LeCoffre Frontend', container: 'lecoffre-front', port: 3000, protocol: 'HTTP' },
|
||||||
|
{ name: 'IHM Client', container: 'ihm_client', port: 3001, protocol: 'HTTP' },
|
||||||
|
{ name: 'Tor Proxy', container: 'tor-proxy', port: 9050, protocol: 'SOCKS' },
|
||||||
|
{ name: 'Grafana', container: 'grafana', port: 3000, protocol: 'HTTP' },
|
||||||
|
{ name: 'Loki', container: 'loki', port: 3100, protocol: 'HTTP' },
|
||||||
|
{ name: 'Promtail', container: 'promtail', port: 9080, protocol: 'HTTP' },
|
||||||
|
{ name: 'Miner Signet', container: 'signet_miner', port: null, protocol: 'Bitcoin' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const externalServices = [
|
||||||
|
{ name: 'Mempool Signet', url: 'https://mempool2.4nkweb.com', protocol: 'HTTPS' },
|
||||||
|
{ name: 'Relay Bootstrap', url: 'wss://dev3.4nkweb.com/ws/', protocol: 'WebSocket' },
|
||||||
|
{ name: 'Signer Bootstrap', url: 'https://dev3.4nkweb.com', protocol: 'HTTPS' },
|
||||||
|
{ name: 'Git Repository', url: 'git.4nkweb.com', protocol: 'SSH' }
|
||||||
|
];
|
||||||
|
|
||||||
|
async function getDockerContainers() {
|
||||||
|
try {
|
||||||
|
const { stdout } = await execAsync('docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"');
|
||||||
|
return stdout;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la récupération des conteneurs:', error);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getContainerInfo(containerName) {
|
||||||
|
try {
|
||||||
|
const { stdout } = await execAsync(`docker inspect ${containerName} --format '{{.State.Status}}|{{.State.StartedAt}}|{{.Config.Image}}|{{.NetworkSettings.IPAddress}}|{{range $port, $binding := .NetworkSettings.Ports}}{{$port}}={{range $binding}}{{.HostIP}}:{{.HostPort}} {{end}}{{end}}'`);
|
||||||
|
return stdout.trim();
|
||||||
|
} catch (error) {
|
||||||
|
return 'stopped||N/A|N/A|';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getServiceHealth(containerName, port) {
|
||||||
|
if (!port) return 'unknown';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { stdout } = await execAsync(`docker exec ${containerName} wget -q --spider -O- http://localhost:${port}/health 2>/dev/null || echo "unhealthy"`);
|
||||||
|
return stdout.trim() === 'unhealthy' ? 'unhealthy' : 'healthy';
|
||||||
|
} catch (error) {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkExternalService(url) {
|
||||||
|
const start = Date.now();
|
||||||
|
try {
|
||||||
|
// Skip WebSocket URLs for now
|
||||||
|
if (url.startsWith('wss://') || url.startsWith('ws://')) {
|
||||||
|
return {
|
||||||
|
status: 'running',
|
||||||
|
response_time: 'N/A (WebSocket)'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const http = require('http');
|
||||||
|
const https = require('https');
|
||||||
|
const urlObj = new URL(url);
|
||||||
|
const client = urlObj.protocol === 'https:' ? https : http;
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const req = client.get(url, { timeout: 5000 }, (res) => {
|
||||||
|
resolve({
|
||||||
|
status: 'running',
|
||||||
|
response_time: `${Date.now() - start}ms`
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('error', () => {
|
||||||
|
resolve({
|
||||||
|
status: 'error',
|
||||||
|
response_time: 'N/A'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('timeout', () => {
|
||||||
|
resolve({
|
||||||
|
status: 'timeout',
|
||||||
|
response_time: '>5s'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: 'error',
|
||||||
|
response_time: 'N/A'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateUptime(startedAt) {
|
||||||
|
if (!startedAt || startedAt === 'N/A') return 'N/A';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const start = new Date(startedAt);
|
||||||
|
const now = new Date();
|
||||||
|
const diff = now - start;
|
||||||
|
|
||||||
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||||
|
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||||
|
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
|
||||||
|
if (days > 0) return `${days}j ${hours}h ${minutes}m`;
|
||||||
|
if (hours > 0) return `${hours}h ${minutes}m`;
|
||||||
|
return `${minutes}m`;
|
||||||
|
} catch (error) {
|
||||||
|
return 'N/A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getServicesStatus() {
|
||||||
|
const servicesStatus = [];
|
||||||
|
|
||||||
|
for (const service of services) {
|
||||||
|
const containerInfo = await getContainerInfo(service.container);
|
||||||
|
const [status, startedAt, image, ip, ports] = containerInfo.split('|');
|
||||||
|
|
||||||
|
const portsArray = ports ? ports.split(' ').filter(p => p.trim()) : [];
|
||||||
|
const health = await getServiceHealth(service.container, service.port);
|
||||||
|
const uptime = calculateUptime(startedAt);
|
||||||
|
|
||||||
|
servicesStatus.push({
|
||||||
|
name: service.name,
|
||||||
|
status: status === 'running' ? 'running' : 'stopped',
|
||||||
|
image: image || 'N/A',
|
||||||
|
ip: ip || 'N/A',
|
||||||
|
ports: portsArray,
|
||||||
|
uptime: uptime,
|
||||||
|
health: health,
|
||||||
|
protocol: service.protocol,
|
||||||
|
port: service.port
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return servicesStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getExternalServicesStatus() {
|
||||||
|
const externalStatus = [];
|
||||||
|
|
||||||
|
for (const service of externalServices) {
|
||||||
|
const status = await checkExternalService(service.url);
|
||||||
|
externalStatus.push({
|
||||||
|
name: service.name,
|
||||||
|
url: service.url,
|
||||||
|
protocol: service.protocol,
|
||||||
|
...status
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return externalStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
app.get('/api', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const services = await getServicesStatus();
|
||||||
|
const external = await getExternalServicesStatus();
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
services: services,
|
||||||
|
external: external
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur API:', error);
|
||||||
|
res.status(500).json({ error: 'Erreur interne du serveur' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/health', (req, res) => {
|
||||||
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, '0.0.0.0', () => {
|
||||||
|
console.log(`🚀 API Status démarrée sur http://0.0.0.0:${PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
456
web/status/index.html
Normal file
456
web/status/index.html
Normal file
@ -0,0 +1,456 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>LeCoffre Node - Status des Services</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
border-radius: 15px;
|
||||||
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
|
||||||
|
color: white;
|
||||||
|
padding: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2.5em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header p {
|
||||||
|
font-size: 1.1em;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn {
|
||||||
|
background: #27ae60;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 12px 24px;
|
||||||
|
border-radius: 25px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-btn:hover {
|
||||||
|
background: #229954;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.last-update {
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.services-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-header {
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-name {
|
||||||
|
font-size: 1.3em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-running {
|
||||||
|
background: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-stopped {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-error {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-unknown {
|
||||||
|
background: #fff3cd;
|
||||||
|
color: #856404;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-details {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px solid #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-label {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-value {
|
||||||
|
color: #6c757d;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-info {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-title {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #495057;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.external-services {
|
||||||
|
background: #e8f4fd;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-left: 5px solid #3498db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.external-title {
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.external-service {
|
||||||
|
background: white;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spinner {
|
||||||
|
border: 4px solid #f3f3f3;
|
||||||
|
border-top: 4px solid #3498db;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
animation: spin 2s linear infinite;
|
||||||
|
margin: 0 auto 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% { transform: rotate(0deg); }
|
||||||
|
100% { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background: #2c3e50;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.services-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1>🚀 LeCoffre Node</h1>
|
||||||
|
<p>Status des Services et Connexions</p>
|
||||||
|
<button class="refresh-btn" onclick="refreshStatus()">🔄 Actualiser</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="last-update" id="lastUpdate">
|
||||||
|
Dernière mise à jour: <span id="updateTime">Chargement...</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="loading" class="loading">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<p>Chargement des informations des services...</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="errorMessage" class="error-message" style="display: none;">
|
||||||
|
Erreur lors du chargement des données
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="servicesContainer" class="services-grid" style="display: none;">
|
||||||
|
<!-- Les services seront injectés ici -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="external-services">
|
||||||
|
<div class="external-title">🌐 Services Externes Connectés</div>
|
||||||
|
<div id="externalServices">
|
||||||
|
<!-- Les services externes seront injectés ici -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<p>LeCoffre Node - Monitoring en temps réel | <span id="footerTime"></span></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Configuration des services à surveiller
|
||||||
|
const services = [
|
||||||
|
{ name: 'Bitcoin Signet', container: 'bitcoin', port: 8332, protocol: 'RPC', description: 'Nœud Bitcoin Signet' },
|
||||||
|
{ name: 'BlindBit Oracle', container: 'blindbit', port: 8000, protocol: 'HTTP', description: 'Oracle pour les Silent Payments' },
|
||||||
|
{ name: 'SDK Relay', container: 'sdk_relay', port: 8090, protocol: 'WebSocket', description: 'Relais des transactions' },
|
||||||
|
{ name: 'SDK Signer', container: 'sdk_signer', port: 9090, protocol: 'WebSocket', description: 'Service de signature' },
|
||||||
|
{ name: 'SDK Storage', container: 'sdk_storage', port: 8080, protocol: 'HTTP', description: 'Stockage temporaire' },
|
||||||
|
{ name: 'LeCoffre Backend', container: 'lecoffre-back', port: 8080, protocol: 'HTTP', description: 'API Backend' },
|
||||||
|
{ name: 'LeCoffre Frontend', container: 'lecoffre-front', port: 3000, protocol: 'HTTP', description: 'Interface utilisateur' },
|
||||||
|
{ name: 'IHM Client', container: 'ihm_client', port: 3001, protocol: 'HTTP', description: 'Interface de gestion des clés' },
|
||||||
|
{ name: 'Tor Proxy', container: 'tor-proxy', port: 9050, protocol: 'SOCKS', description: 'Proxy anonyme' },
|
||||||
|
{ name: 'Grafana', container: 'grafana', port: 3000, protocol: 'HTTP', description: 'Monitoring et dashboards' },
|
||||||
|
{ name: 'Loki', container: 'loki', port: 3100, protocol: 'HTTP', description: 'Agrégation des logs' },
|
||||||
|
{ name: 'Promtail', container: 'promtail', port: 9080, protocol: 'HTTP', description: 'Collecteur de logs' },
|
||||||
|
{ name: 'Miner Signet', container: 'signet_miner', port: null, protocol: 'Bitcoin', description: 'Mineur de blocs' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const externalServices = [
|
||||||
|
{ name: 'Mempool Signet', url: 'https://mempool2.4nkweb.com', protocol: 'HTTPS', description: 'Explorateur de blockchain' },
|
||||||
|
{ name: 'Relay Bootstrap', url: 'wss://dev3.4nkweb.com/ws/', protocol: 'WebSocket', description: 'Relais de bootstrap' },
|
||||||
|
{ name: 'Signer Bootstrap', url: 'https://dev3.4nkweb.com', protocol: 'HTTPS', description: 'Signer de bootstrap' },
|
||||||
|
{ name: 'Git Repository', url: 'git.4nkweb.com', protocol: 'SSH', description: 'Dépôt de code' }
|
||||||
|
];
|
||||||
|
|
||||||
|
async function refreshStatus() {
|
||||||
|
document.getElementById('loading').style.display = 'block';
|
||||||
|
document.getElementById('errorMessage').style.display = 'none';
|
||||||
|
document.getElementById('servicesContainer').style.display = 'none';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/status/api');
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
displayServices(data.services);
|
||||||
|
displayExternalServices(data.external);
|
||||||
|
updateTime();
|
||||||
|
|
||||||
|
document.getElementById('loading').style.display = 'none';
|
||||||
|
document.getElementById('servicesContainer').style.display = 'grid';
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur:', error);
|
||||||
|
document.getElementById('loading').style.display = 'none';
|
||||||
|
document.getElementById('errorMessage').style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayServices(servicesData) {
|
||||||
|
const container = document.getElementById('servicesContainer');
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
services.forEach(service => {
|
||||||
|
const serviceData = servicesData.find(s => s.name === service.name) || {
|
||||||
|
status: 'unknown',
|
||||||
|
image: 'N/A',
|
||||||
|
ip: 'N/A',
|
||||||
|
ports: [],
|
||||||
|
uptime: 'N/A',
|
||||||
|
health: 'unknown'
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusClass = `status-${serviceData.status}`;
|
||||||
|
const statusText = getStatusText(serviceData.status);
|
||||||
|
|
||||||
|
const serviceCard = document.createElement('div');
|
||||||
|
serviceCard.className = 'service-card';
|
||||||
|
serviceCard.innerHTML = `
|
||||||
|
<div class="service-header">
|
||||||
|
<div class="service-name">${service.name}</div>
|
||||||
|
<div class="status-badge ${statusClass}">${statusText}</div>
|
||||||
|
</div>
|
||||||
|
<div class="service-details">
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Description:</span>
|
||||||
|
<span class="detail-value">${service.description}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Image Docker:</span>
|
||||||
|
<span class="detail-value">${serviceData.image}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Protocole:</span>
|
||||||
|
<span class="detail-value">${service.protocol}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Port:</span>
|
||||||
|
<span class="detail-value">${service.port || 'N/A'}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">IP d'écoute:</span>
|
||||||
|
<span class="detail-value">${serviceData.ip}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Uptime:</span>
|
||||||
|
<span class="detail-value">${serviceData.uptime}</span>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<span class="detail-label">Santé:</span>
|
||||||
|
<span class="detail-value">${serviceData.health}</span>
|
||||||
|
</div>
|
||||||
|
${serviceData.ports && serviceData.ports.length > 0 ? `
|
||||||
|
<div class="network-info">
|
||||||
|
<div class="network-title">Ports exposés:</div>
|
||||||
|
${serviceData.ports.map(port => `<div>${port}</div>`).join('')}
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
container.appendChild(serviceCard);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayExternalServices(externalData) {
|
||||||
|
const container = document.getElementById('externalServices');
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
externalServices.forEach(service => {
|
||||||
|
const serviceData = externalData.find(s => s.name === service.name) || {
|
||||||
|
status: 'unknown',
|
||||||
|
response_time: 'N/A'
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusClass = `status-${serviceData.status}`;
|
||||||
|
const statusText = getStatusText(serviceData.status);
|
||||||
|
|
||||||
|
const serviceDiv = document.createElement('div');
|
||||||
|
serviceDiv.className = 'external-service';
|
||||||
|
serviceDiv.innerHTML = `
|
||||||
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
|
<div style="font-weight: bold; color: #2c3e50;">${service.name}</div>
|
||||||
|
<div class="status-badge ${statusClass}">${statusText}</div>
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom: 8px;">
|
||||||
|
<strong>URL:</strong> ${service.url}
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom: 8px;">
|
||||||
|
<strong>Protocole:</strong> ${service.protocol}
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom: 8px;">
|
||||||
|
<strong>Description:</strong> ${service.description}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Temps de réponse:</strong> ${serviceData.response_time}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
container.appendChild(serviceDiv);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStatusText(status) {
|
||||||
|
switch(status) {
|
||||||
|
case 'running': return '🟢 En cours';
|
||||||
|
case 'stopped': return '🔴 Arrêté';
|
||||||
|
case 'error': return '⚠️ Erreur';
|
||||||
|
case 'healthy': return '✅ Sain';
|
||||||
|
case 'unhealthy': return '❌ Malsain';
|
||||||
|
default: return '❓ Inconnu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTime() {
|
||||||
|
const now = new Date();
|
||||||
|
const timeString = now.toLocaleString('fr-FR');
|
||||||
|
document.getElementById('updateTime').textContent = timeString;
|
||||||
|
document.getElementById('footerTime').textContent = timeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-refresh toutes les 30 secondes
|
||||||
|
setInterval(refreshStatus, 30000);
|
||||||
|
|
||||||
|
// Chargement initial
|
||||||
|
refreshStatus();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
24
web/status/package.json
Normal file
24
web/status/package.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "lecoffre-status-api",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "API de statut pour LeCoffre Node",
|
||||||
|
"main": "api.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node api.js",
|
||||||
|
"dev": "nodemon api.js"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.18.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^3.0.1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"lecoffre",
|
||||||
|
"status",
|
||||||
|
"monitoring",
|
||||||
|
"docker"
|
||||||
|
],
|
||||||
|
"author": "LeCoffre Team",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
50
web/status/simple-api.js
Normal file
50
web/status/simple-api.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const express = require('express');
|
||||||
|
const { exec } = require('child_process');
|
||||||
|
const util = require('util');
|
||||||
|
const execAsync = util.promisify(exec);
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
const PORT = 3006;
|
||||||
|
|
||||||
|
// Middleware CORS
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.header('Access-Control-Allow-Origin', '*');
|
||||||
|
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
||||||
|
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Route de test simple
|
||||||
|
app.get('/api', async (req, res) => {
|
||||||
|
try {
|
||||||
|
// Test simple avec docker ps
|
||||||
|
const { stdout } = await execAsync('docker ps --format "{{.Names}}\t{{.Status}}"');
|
||||||
|
const containers = stdout.trim().split('\n').map(line => {
|
||||||
|
const [name, status] = line.split('\t');
|
||||||
|
return { name, status: status.includes('Up') ? 'running' : 'stopped' };
|
||||||
|
});
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
services: containers,
|
||||||
|
external: [
|
||||||
|
{ name: 'Test External', status: 'running', response_time: '100ms' }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur API:', error);
|
||||||
|
res.status(500).json({ error: 'Erreur interne du serveur', details: error.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/health', (req, res) => {
|
||||||
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, '0.0.0.0', () => {
|
||||||
|
console.log(`🚀 API Status démarrée sur http://0.0.0.0:${PORT}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
Loading…
x
Reference in New Issue
Block a user