ci: docker_tag=ext - Update for 4NK_env integration
This commit is contained in:
parent
66479e38ce
commit
87734937df
14
.cursor/config.json
Normal file
14
.cursor/config.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"language": "fr",
|
||||
"shell": "/usr/bin/bash",
|
||||
"formatting": {
|
||||
"markdown": {
|
||||
"lint_strict": true
|
||||
}
|
||||
},
|
||||
"ci": {
|
||||
"trigger_commit_prefix": "ci: docker_tag=",
|
||||
"default_tag": "ext",
|
||||
"branch": "dev4"
|
||||
}
|
||||
}
|
20
.cursor/nginx_fix.conf
Normal file
20
.cursor/nginx_fix.conf
Normal file
@ -0,0 +1,20 @@
|
||||
# API backend - route /back/ vers /api/ du backend
|
||||
location ~* ^/back/(.*)$ {
|
||||
proxy_pass http://127.0.0.1:8080/api/$1;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
# API direct - route /api/ vers le backend
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8080/api/;
|
||||
include /etc/nginx/proxy_params;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
10
.cursor/rules.md
Normal file
10
.cursor/rules.md
Normal file
@ -0,0 +1,10 @@
|
||||
# Règles Cursor pour ce projet
|
||||
|
||||
- Toujours répondre en français.
|
||||
- Commandes simples, une par une.
|
||||
- CI front/back: déclenchement par commit `ci: docker_tag=ext` sur `dev4`.
|
||||
- Nginx local obligatoire. Confs dans `conf/nginx/`. Pas de Docker pour Nginx.
|
||||
- Avant modification Nginx: vérifier `-w` sur fichier, backup horodatée vers `.cursor/backup/`, édition atomique (temp + mv), `nginx -t`, reload.
|
||||
- Docker images: utiliser le tag `docker-support-v2` si spécifié par projet, sinon `ext`.
|
||||
- Toujours mettre à jour `docs/` et `tests/` après modifications.
|
||||
- Ne jamais exposer de secrets dans les `.env.example` côté front.
|
@ -48,3 +48,4 @@ volumes/
|
||||
conf/nginx/*bak*
|
||||
conf/nginx/*.tmp
|
||||
conf/nginx/*.clean
|
||||
|
||||
|
91
.gitignore
vendored
91
.gitignore
vendored
@ -1,13 +1,82 @@
|
||||
# Secrets et fichiers sensibles
|
||||
.env
|
||||
miner/.env
|
||||
miner/signet/priv_key.json
|
||||
.env.*
|
||||
!.env.example
|
||||
!.env.exemple
|
||||
env.master
|
||||
*.key
|
||||
*.pem
|
||||
*.p12
|
||||
*.pfx
|
||||
secrets/
|
||||
keys/
|
||||
|
||||
# Sensibles et générés
|
||||
.cursor/
|
||||
log/*.log
|
||||
miner/.env.signet
|
||||
miner/tools/*.json
|
||||
conf/nginx/*bak*
|
||||
conf/nginx/*.tmp
|
||||
conf/nginx/*.clean
|
||||
.env.bak
|
||||
# Logs
|
||||
logs/
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Données et volumes
|
||||
data/
|
||||
volumes/
|
||||
bitcoin_data/
|
||||
sdk_data/
|
||||
grafana_data/
|
||||
loki_data/
|
||||
blindbit_data/
|
||||
|
||||
# Backups
|
||||
backup/
|
||||
*.backup
|
||||
*.bak
|
||||
|
||||
# Docker
|
||||
.dockerignore
|
||||
docker-compose.override.yml
|
||||
|
||||
# Node.js
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.npm
|
||||
.yarn-integrity
|
||||
|
||||
# Next.js
|
||||
.next/
|
||||
out/
|
||||
build/
|
||||
dist/
|
||||
|
||||
# Rust
|
||||
target/
|
||||
Cargo.lock
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Temporary files
|
||||
tmp/
|
||||
temp/
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# SSL certificates
|
||||
*.crt
|
||||
*.csr
|
||||
ssl/
|
||||
|
||||
# Configuration locale
|
||||
local.conf
|
||||
local.yml
|
||||
local.json
|
87
Dockerfile.master
Normal file
87
Dockerfile.master
Normal file
@ -0,0 +1,87 @@
|
||||
# Dockerfile Master pour lecoffre_node - Architecture autonome complète
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
# Métadonnées
|
||||
LABEL maintainer="4NK Team" \
|
||||
description="LeCoffre Node - Master Container avec Nginx intégré" \
|
||||
version="1.0.0"
|
||||
|
||||
# Variables d'environnement
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
TZ=Europe/Paris \
|
||||
NGINX_VERSION=1.22.1 \
|
||||
DOCKER_COMPOSE_VERSION=2.21.0
|
||||
|
||||
# Installation des dépendances système
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
jq \
|
||||
python3 \
|
||||
python3-pip \
|
||||
docker.io \
|
||||
docker-compose \
|
||||
nginx \
|
||||
supervisor \
|
||||
cron \
|
||||
logrotate \
|
||||
openssl \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Installation de Docker Compose
|
||||
RUN curl -L "https://github.com/docker/compose/releases/download/v${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
|
||||
-o /usr/local/bin/docker-compose && \
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
# Création des utilisateurs
|
||||
RUN useradd -m -u 1000 appuser && \
|
||||
useradd -m -u 10000 lecoffreuser && \
|
||||
usermod -aG docker appuser
|
||||
|
||||
# Répertoire de travail
|
||||
WORKDIR /app
|
||||
|
||||
# Copie des fichiers de configuration
|
||||
COPY conf/nginx/ /etc/nginx/sites-available/
|
||||
COPY conf/nginx/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY conf/supervisor/ /etc/supervisor/conf.d/
|
||||
COPY scripts/ /app/scripts/
|
||||
COPY web/ /var/www/lecoffre/
|
||||
COPY docker-compose.yml /app/
|
||||
COPY .env /app/.env
|
||||
|
||||
# Configuration Nginx autonome et génération des certificats SSL
|
||||
RUN mkdir -p /var/www/lecoffre/status /var/www/lecoffre/assets && \
|
||||
ln -sf /etc/nginx/sites-available/* /etc/nginx/sites-enabled/ && \
|
||||
rm -f /etc/nginx/sites-enabled/default && \
|
||||
/app/scripts/generate-ssl-certs.sh && \
|
||||
nginx -t && \
|
||||
chown -R www-data:www-data /var/www/lecoffre
|
||||
|
||||
# Configuration Supervisor
|
||||
RUN mkdir -p /var/log/supervisor && \
|
||||
chown -R appuser:appuser /app
|
||||
|
||||
# Scripts d'initialisation
|
||||
RUN chmod +x /app/scripts/*.sh
|
||||
|
||||
# Ports exposés
|
||||
EXPOSE 80 443 3000
|
||||
|
||||
# Volumes pour persistance
|
||||
VOLUME ["/app/data", "/app/logs", "/var/lib/docker"]
|
||||
|
||||
# Utilisateur non-root
|
||||
USER appuser
|
||||
|
||||
# Healthcheck
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost/status/ || exit 1
|
||||
|
||||
# Point d'entrée
|
||||
ENTRYPOINT ["/app/scripts/entrypoint.sh"]
|
||||
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
|
@ -1,67 +0,0 @@
|
||||
# Contexte
|
||||
|
||||
Le site est sur @https://dev4.4nkweb.com/lecoffre (`lecoffre_front`).
|
||||
Il sera redirigé au login des notaires vers un site qui redirige vers local.4nkdev.com qui sera redirigé vers @https://dev4.4nkweb.com/lecoffre avec l'ouverture de l'iframe @https://dev4.4nkweb.com/ (`ihm_client`).
|
||||
|
||||
Fonctionnellement, le test est sur navigateur de :
|
||||
* tenter un login () notaire dont la redirection IdNot (redirections et API notaires) et valider dans l'iframe et d'arriver connecté apres la vérification du compte Stripe (lecoffre-back-mini).
|
||||
* créer un compte dossier en tant que notaire en ajoutant un client ce qui enverra un lien par mail par mailshimp puis en tant que client me connecté avec le lien recçu par mail, confirmer le code sms (api ovh) et accéder à mon dossier.
|
||||
|
||||
Tehcniquement, le test est sur navigateur de :
|
||||
* Vérifier la page de statut des services : @https://dev4.4nkweb.com/status/
|
||||
* Vérifier les dashboard grafana @https://dev4.4nkweb.com/grafana/
|
||||
|
||||
---
|
||||
|
||||
## Dépendances
|
||||
|
||||
A déployer par **`lecoffre_node/`** :
|
||||
|
||||
- image: btcpayserver/tor:0.4.8.10 (pour synchro Bitcoin)
|
||||
- image: git.4nkweb.com/4nk/bitcoin:latest (pour mainchain et signet custom)
|
||||
- image: git.4nkweb.com/4nk/blindbit-oracle:dev (pour scan des blocs et détection des secrets dans les transaction silent payment)
|
||||
- image: containrrr/watchtower (pour la surveillance et mise à jour automatique des images)
|
||||
- image: grafana/grafana:latest (pour le monitoring des évènements)
|
||||
- image: grafana/loki:latest
|
||||
- grafana/promtail:latest
|
||||
|
||||
---
|
||||
|
||||
## Projets locaux avec Dockerfile
|
||||
|
||||
A déployer par **`lecoffre_node/`** (d'autres projets externes sont ne dépendance dans le `lecoffre_node/docker-compose.yml`):
|
||||
|
||||
### Services optimisés (2024-12-19)
|
||||
- **`sdk_relay/`** (relai des transations et messages et oracle) - Debian + Rust
|
||||
- **`sdk_signer/`** (signature des processus métier et des identités/profils) - Debian + Node.js 20
|
||||
- **`sdk_storage/`** (stockage temporaire) - Debian + Rust
|
||||
- **`ihm_client/`** (iframe dans les frontend des projets pour interactions avec les clés privés Bitcoin Silent Payment) - Debian + Node.js 20
|
||||
- **`lecoffre-back-mini/`** (backend pour les API tierces du projet lecoffre) - Debian + Node.js 19
|
||||
- **`lecoffre-front/`** (frontend du projet lecoffre) - Debian + Node.js 19
|
||||
|
||||
### Architecture Docker
|
||||
- **Base standardisée** : `debian:bookworm-slim` pour tous les services
|
||||
- **Packages minimaux** : ca-certificates, curl, jq, git
|
||||
- **Utilisateurs non-root** : appuser (UID 1000)
|
||||
- **Images optimisées** : 120-300MB selon le service
|
||||
- **Tag Docker** : `ext` pour tous les déploiements
|
||||
|
||||
---
|
||||
|
||||
## Projets locaux sans Dockerfile
|
||||
|
||||
A vérifier **`lecoffre_node/`**:
|
||||
|
||||
- **`sdk_common/`** (coeur de la gestion des clés)
|
||||
- **`sdk_client/`** (coeur de l'intégration du système de process)
|
||||
- **`sdk-signer-client/`** (coeur de l'intégration du système de process pour l'intégration)
|
||||
- **`lecoffre_node/miner/`** (miner de la blockchain de preuves -layer2 de bitcoin depuis un signet-) - **Maintenant avec Dockerfile optimisé**
|
||||
- **`status-api`** (interface d'affichage des statuts des interfaces et des services)
|
||||
|
||||
### Note importante
|
||||
Le **miner** a maintenant un Dockerfile optimisé avec Debian + Python 3.11 et fait partie des services avec Dockerfile.
|
||||
|
||||
---
|
||||
|
||||
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.
|
@ -1,207 +0,0 @@
|
||||
# agent_deploy.md
|
||||
|
||||
Respecte totalement et impérativemment les informations de ce document.
|
||||
|
||||
---
|
||||
|
||||
## Contexte
|
||||
|
||||
Consulte attentivement `lecoffre_node/IA_agents/context.md`.
|
||||
Consulte attentivement `lecoffre_node/IA_agents/flux.md`.
|
||||
Reste toujours sur la branche git "ext"
|
||||
Fait toujours les build via CI avec des images docker pour le docker registry tagées "ext"
|
||||
Déclanche toujours avec un tag "ext" remplace le précédent.
|
||||
|
||||
---
|
||||
|
||||
## Objectifs
|
||||
|
||||
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.
|
||||
Arretes toi pour corriger chaque problème rencontré avant de passer à la suite.
|
||||
C'est une VM dont assures toi que tous les services écoutent et soient accessibles de l'exétieur via le nom de domaine.
|
||||
|
||||
Dans **tous les projets** à vérifier un par un dont lecoffre_node:
|
||||
|
||||
- Analyse le dossier pour bien le comprendre
|
||||
- Analyse le code pour bien le comprendre
|
||||
- Une branche Git dédiée `ext` existe.
|
||||
- Aucun tag Git nommé `ext` n’existe.
|
||||
- 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.
|
||||
|
||||
Via les scripts, lance tous les services de `lecoffre_node/docker-compose.yml`.
|
||||
|
||||
## Procédure générale
|
||||
|
||||
### Vérifications initiales par projet
|
||||
|
||||
1. Vérifier que le dépôt distant est **public** (si possible).
|
||||
2. Vérifier l’utilisation des **clés SSH** pour le déploiement Git (idéalement ~/.ssh/id_ed25519)
|
||||
3. Vérifier que la branche courante est bien **`ext`**.
|
||||
4. Mettre à jour les dépendances et les langages
|
||||
5. Vérifier les **variables d’environnement**.
|
||||
|
||||
### Mise à jour et construction par projet
|
||||
|
||||
6. Supprime les caches, Optimise le build du projet et build le projet.
|
||||
7. Mettre à jour la **documentation**.
|
||||
8. Mettre à jour les **tests**.
|
||||
9. Mettre à jour les **scripts**.
|
||||
10. Vérifier que la présence et le contenu exhaustif et spécifique de :
|
||||
- `.gitignore`
|
||||
- `.dockerignore`
|
||||
- `.cursorignore`
|
||||
|
||||
### Synchronisations par projet
|
||||
|
||||
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)
|
||||
|
||||
### Sécurité et conformité par projet
|
||||
|
||||
13. Vérifier que le code ne fournit pas :
|
||||
- de **données personnelles**,
|
||||
- de **données sensibles exploitables**,
|
||||
- de **failles de sécurité**.
|
||||
|
||||
### Gestion Git par projet
|
||||
|
||||
14. Pousser toutes les modifications sur la branche Git `ext`.
|
||||
15. Supprimer les fichiers distants non suivis par Git.
|
||||
|
||||
### Analyse et correction par projet
|
||||
|
||||
16. Analyser les logs.
|
||||
17. Corriger toutes les erreurs, petites et grosses, **sans désactivation**, **sans simplification**, **sans contournement**.
|
||||
18. Tester.
|
||||
19. Analyser de nouveau les logs.
|
||||
20. Vérifier que les logs ne contiennent pas de données personnelles ou sensibles.
|
||||
21. Corriger à nouveau si nécessaire (jusqu'à l'absence totale d'erreurs)
|
||||
|
||||
### Boucle d’amélioration par projet
|
||||
|
||||
22. Ne pas créer de nouvelles versions de scripts : **améliorer et tester ceux existants**.
|
||||
23. Mettre à jour la documentation avec le **retour d’expérience** à chaque fois par une mise à jour de `docs/REX.md`.
|
||||
24. Recommencer si nécessaire pour obtenir un déploiement fluide et parfait.
|
||||
25. Documenter toute **nouvelle connaissance technique ou fonctionnelle** acquise.
|
||||
26. Répéter la synchronisation des confs et logs.
|
||||
27. Pousser toutes les modifications sur la branche `ext`.
|
||||
28. Supprimer à nouveau les fichiers distants non suivis.
|
||||
29. Répéter anal
|
||||
|
||||
### Lancement des services
|
||||
|
||||
30. Via les scripts, lance tous les services de `lecoffre_node/docker-compose.yml`.
|
||||
31. Corriger toutes les erreurs, petites et grosses, **sans désactivation**, **sans simplification**, **sans contournement**.
|
||||
32. Tester.
|
||||
33. Analyser de nouveau les logs.
|
||||
34. Vérifier que les logs ne contiennent pas de données personnelles ou sensibles.
|
||||
35. Corriger à nouveau si nécessaire (jusqu'à l'absence totale d'erreurs)
|
||||
36. Mettre à jour la documentation avec le **retour d’expérience** à chaque fois par une mise à jour de `docs/REX.md`.
|
||||
37. Recommencer si nécessaire pour obtenir un déploiement fluide et parfait.
|
||||
38. Assures toi d'être à jour pour le service grafana
|
||||
39. Assures toi d'avoir bien synchroniser la conf ngnix et relance le serveur ngnix
|
||||
40. Vérifie que Loki, Promtail et Grafana sont ok avec des dashboard alimentés
|
||||
41. Vérifie qu'il n'y a aucun conflit de ports
|
||||
|
||||
---
|
||||
|
||||
## Spécificités Dockerfile par projet
|
||||
|
||||
### Architecture Docker optimisée (2024-12-19)
|
||||
|
||||
**Base standardisée** : Tous les Dockerfiles utilisent `debian:bookworm-slim` pour la cohérence et la légèreté.
|
||||
|
||||
### Règles Dockerfile obligatoires
|
||||
|
||||
Pour tous les projets contenant un **Dockerfile**, avant de pousser sur la branche `ext` :
|
||||
|
||||
#### 1. Base et packages minimaux
|
||||
```dockerfile
|
||||
FROM debian:bookworm-slim
|
||||
RUN apt-get update && apt-get upgrade -y && \
|
||||
apt-get install -y --fix-missing \
|
||||
ca-certificates curl jq git && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
|
||||
**Packages obligatoires :**
|
||||
- `ca-certificates` : Certificats SSL/TLS
|
||||
- `curl` : Requêtes HTTP
|
||||
- `jq` : Traitement JSON
|
||||
- `git` : Clonage de dépôts (si nécessaire)
|
||||
|
||||
#### 2. Installation Node.js (pour les services Node.js)
|
||||
```dockerfile
|
||||
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
||||
apt-get install -y nodejs && \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
```
|
||||
|
||||
#### 3. Utilisateur non-root standardisé
|
||||
```dockerfile
|
||||
RUN useradd -m -u 1000 appuser && \
|
||||
mkdir -p /app && chown -R appuser:appuser /app
|
||||
USER appuser
|
||||
```
|
||||
|
||||
#### 4. Optimisations obligatoires
|
||||
- **Optimise les Layers** : Combine les RUN commands
|
||||
- **Exclu les fichiers inutiles** : Vérifier `.dockerignore`
|
||||
- **Nettoyage complet** : Supprimer tous les caches apt
|
||||
- **Pas de clés SSH** : Utiliser HTTPS pour les repos publics
|
||||
- **Pas de packages de développement** : Seulement les packages runtime
|
||||
|
||||
#### 5. Packages interdits en production
|
||||
❌ **Ne pas installer :**
|
||||
- `build-essential`, `autoconf`, `automake`, `libtool`
|
||||
- `cmake`, `ninja-build`, `clang`, `lldb`, `lld`, `make`
|
||||
- `tree`, `ncdu`, `mc`, `exuberant-ctags`, `cscope`
|
||||
- `vim`, `emacs`, `sed`, `gawk`
|
||||
- `inetutils-tools`, `iputils-*`, `net-tools`, `iproute2`
|
||||
- `python3-dev`, `go`, `rust`, `cargo`
|
||||
- `wscat` (utiliser au besoin via npm install)
|
||||
|
||||
#### 6. Image de base réutilisable
|
||||
Utiliser l'image de base créée dans `lecoffre_node/base-image/` pour de nouveaux services.
|
||||
|
||||
### Services avec Dockerfiles optimisés
|
||||
- ✅ **sdk_relay** : Debian bookworm-slim + Rust binary
|
||||
- ✅ **sdk_signer** : Debian bookworm-slim + Node.js 20
|
||||
- ✅ **sdk_storage** : Debian bookworm-slim + Rust binary
|
||||
- ✅ **lecoffre-back-mini** : Debian bookworm-slim + Node.js 19
|
||||
- ✅ **lecoffre-front** : Debian bookworm-slim + Node.js 19
|
||||
- ✅ **ihm_client** : Debian bookworm-slim + Node.js 20
|
||||
- ✅ **miner** : Debian bookworm-slim + Python 3.11
|
||||
|
||||
### Processus de déploiement
|
||||
|
||||
Après le push sur la branche Git `ext` :
|
||||
1. Créer/supprimer le tag Docker `ext`
|
||||
2. Pousser l'image sur le **tag Docker `ext`** via la CI
|
||||
3. Vérifier le succès du build CI
|
||||
|
||||
### Tailles d'images cibles
|
||||
- **Services légers** : 120-200MB
|
||||
- **Services avec Node.js** : 180-250MB
|
||||
- **Services avec Python** : 200-300MB
|
||||
|
||||
---
|
||||
|
||||
## Autres
|
||||
|
||||
N'attend pas infiniment le résultat des curls.
|
||||
Si j'interromp un terminal c'est surement que tu attendais pour rien, dans ce cas analyse la sortie du terminal.
|
||||
Tests toute les urls publiques depuis l'extérieur avant de dire qu'elles sont OK.
|
||||
Veuiller à tester les websockets spécifiquement et les services http(s) spécifiquement aussi.
|
||||
Vérifie que tous les imports sont présents.
|
||||
Déclanche les builds via CI.
|
||||
Vérifie les droits et le résultats de l'écriture sur les fichiers de conf ngninx et sur les fichiers de conf de Bitcoin.
|
||||
|
||||
---
|
||||
|
||||
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
|
@ -1,338 +0,0 @@
|
||||
# Architecture des Flux et Services - LeCoffre Node
|
||||
|
||||
---
|
||||
|
||||
## Tableau des Services - IP/Domaines et Ports
|
||||
|
||||
### 🏠 **Services Locaux (Docker Compose)**
|
||||
|
||||
| Service | Container | Port Local | Port Interne | Protocole | URL d'accès |
|
||||
|---------|-----------|------------|--------------|-----------|-------------|
|
||||
| **tor** | tor-proxy | - | 9050 | TCP | Réseau interne uniquement |
|
||||
| **bitcoin** | bitcoin-signet | - | 38332 (RPC)<br>38333 (P2P)<br>29000 (ZMQ hash)<br>29001 (ZMQ rawtx) | TCP | Réseau interne uniquement |
|
||||
| **blindbit** | blindbit-oracle | 0.0.0.0:8000 | 8000 | HTTP | http://0.0.0.0:8000 |
|
||||
| **sdk_relay** | sdk_relay | 0.0.0.0:8090<br>0.0.0.0:8091 | 8090 (WS)<br>8091 (HTTP) | WebSocket/HTTP | ws://0.0.0.0:8090<br>http://0.0.0.0:8091 |
|
||||
| **lecoffre-back** | lecoffre-back | 0.0.0.0:8080 | 8080 | HTTP | http://0.0.0.0:8080 |
|
||||
| **lecoffre-front** | lecoffre-front | 127.0.0.2:3004 | 3000 | HTTP | http://127.0.0.2:3004 |
|
||||
| **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_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**
|
||||
|
||||
| Service | Domaine | Port | Protocole | URL d'accès | Statut |
|
||||
|---------|---------|------|-----------|-------------|--------|
|
||||
| **Bootstrap Relay** | dev3.4nkweb.com | 443 | WSS | wss://dev3.4nkweb.com/ws/ | ✅ Actif |
|
||||
| **Signer Externe** | dev3.4nkweb.com | 9090 | WS | ws://dev3.4nkweb.com:9090 | ✅ Actif |
|
||||
| **Signer Base** | dev3.4nkweb.com | 443 | HTTPS | https://dev3.4nkweb.com | ✅ Actif |
|
||||
| **Mempool** | mempool2.4nkweb.com | 443 | HTTPS | https://mempool2.4nkweb.com | ✅ Actif |
|
||||
| **Storage** | dev4.4nkweb.com | 443 | HTTPS | https://dev4.4nkweb.com/storage | ✅ Actif |
|
||||
|
||||
### 🔄 **Proxy Nginx (dev4.4nkweb.com)**
|
||||
|
||||
| Route | Destination | Port | Protocole | Description |
|
||||
|-------|-------------|------|-----------|-------------|
|
||||
| **/** | ihm_client | 3003 | HTTP | Interface principale |
|
||||
| **/lecoffre** | lecoffre-front | 3004 | HTTP | Application LeCoffre |
|
||||
| **/api/** | lecoffre-back | 8080 | HTTP | API Backend |
|
||||
| **/back/** | lecoffre-back | 8080 | HTTP | API Backend (alias) |
|
||||
| **/ws/** | sdk_relay | 8090 | WebSocket | Relay WebSocket |
|
||||
| **/signer/** | sdk_signer | 3001 | HTTP/WebSocket | Service Signer |
|
||||
| **/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)**
|
||||
|
||||
| Route | Destination | Port | Protocole | Description |
|
||||
|-------|-------------|------|-----------|-------------|
|
||||
| **/** | Redirection | 3000 | HTTP | Redirige vers port 3000 |
|
||||
| **/lecoffre/** | lecoffre-front | 3004 | HTTP | Application LeCoffre local |
|
||||
|
||||
### 🔧 **Configuration Bitcoin Signet**
|
||||
|
||||
| Service | Port | Protocole | Description |
|
||||
|---------|------|-----------|-------------|
|
||||
| **RPC** | 38332 | TCP | Interface RPC Bitcoin |
|
||||
| **P2P** | 38333 | TCP | Réseau peer-to-peer |
|
||||
| **ZMQ Hash** | 29000 | TCP | Notifications de blocs |
|
||||
| **ZMQ RawTx** | 29001 | TCP | Notifications de transactions |
|
||||
| **Tor** | 9050 | TCP | Proxy Tor |
|
||||
|
||||
### 🌐 **Réseau Docker**
|
||||
|
||||
| Réseau | Subnet | Driver | Services |
|
||||
|--------|--------|--------|----------|
|
||||
| **btcnet** | 172.20.0.0/16 | bridge | Tous les services |
|
||||
|
||||
### 🔗 **Variables d'Environnement Clés**
|
||||
|
||||
| Variable | Valeur | Service |
|
||||
|----------|--------|---------|
|
||||
| **VITE_BOOTSTRAPURL** | wss://dev4.4nkweb.com/ws/ | ihm_client |
|
||||
| **SIGNER_WS_URL** | ws://dev3.4nkweb.com:9090 | sdk_signer |
|
||||
| **SIGNER_BASE_URL** | https://dev3.4nkweb.com | 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 |
|
||||
| **storage** | https://dev4.4nkweb.com/storage | sdk_relay |
|
||||
| **GRAFANA_ADMIN_PASSWORD** | admin123 | grafana |
|
||||
| **GF_SERVER_ROOT_URL** | https://dev4.4nkweb.com/grafana/ | grafana |
|
||||
|
||||
---
|
||||
|
||||
## Flux d'Architecture
|
||||
|
||||
### 🔄 **Flux Principal**
|
||||
|
||||
```
|
||||
Internet → dev4.4nkweb.com (Nginx) → Services Locaux
|
||||
```
|
||||
|
||||
1. **Frontend** : `https://dev4.4nkweb.com/lecoffre` → lecoffre-front (127.0.0.2:3004)
|
||||
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)
|
||||
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**
|
||||
|
||||
```
|
||||
local.4nkdev.com → local.4nkweb.com → https://dev4.4nkweb.com/lecoffre
|
||||
```
|
||||
|
||||
### 🌐 **Flux Externes**
|
||||
|
||||
- **Bootstrap** : `wss://dev3.4nkweb.com/ws/` (Relay externe)
|
||||
- **Signer** : `ws://dev3.4nkweb.com:9090` (Actuellement inactif)
|
||||
- **Mempool** : `https://mempool2.4nkweb.com` (Réseau Bitcoin Signet)
|
||||
|
||||
---
|
||||
|
||||
## 📊 **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**
|
||||
|
||||
1. **dev3.4nkweb.com:9090** - Service signer externe actuellement inactif
|
||||
2. **dev3.4nkweb.com** - Retourne 502 Bad Gateway (services backend indisponibles)
|
||||
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
|
||||
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**
|
||||
|
||||
Selon les règles du projet, l'ordre de démarrage est :
|
||||
|
||||
### 🚀 **Services Principaux**
|
||||
1. **tor** - Proxy anonyme
|
||||
2. **bitcoin** - Nœud Bitcoin Signet
|
||||
3. **blindbit** - Oracle Bitcoin
|
||||
4. **sdk_storage** - Stockage temporaire
|
||||
5. **sdk_relay** - Relais des transactions
|
||||
6. **sdk_signer** - Signature des processus
|
||||
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**
|
||||
|
||||
### 🌐 **Services Externes**
|
||||
- **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 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`
|
||||
|
||||
---
|
||||
|
||||
## 💾 **Volumes et Persistance des Données**
|
||||
|
||||
### 📦 **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
|
||||
|
||||
---
|
||||
|
||||
## 🌐 **Configuration Nginx - Règles et Routes**
|
||||
|
||||
### 📋 **Tableau Récapitulatif des Routes**
|
||||
|
||||
| Domaine | Port | Route | Destination | Protocole | Statut |
|
||||
|---------|------|-------|-------------|-----------|--------|
|
||||
| **dev4.4nkweb.com** | 80 | `/` | Redirection HTTPS | HTTP | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 80 | `/.well-known/acme-challenge/` | Let's Encrypt | HTTP | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/grafana/` | Grafana (3005) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/loki/` | Loki (3100) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/status/` | Page statut | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/status/api` | API statut (3006) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/api/` | Backend (8080) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/ws/` | SDK Relay (8090) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/signer/` | SDK Signer (3001) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/blindbit/` | BlindBit (8000) | HTTPS | ✅ Actif |
|
||||
| **dev4.4nkweb.com** | 443 | `/` | IHM Client (3003) | HTTPS | ✅ Actif |
|
||||
| **local.4nkweb.com** | 80 | `/` | Redirection port 3000 | HTTP | ✅ Actif |
|
||||
| **local.4nkweb.com** | 3000 | `/lecoffre/` | Frontend (3004) | HTTP | ✅ Actif |
|
||||
| **local.4nkweb.com** | 3000 | `/authorized-client` | Frontend (3004) | HTTP | ✅ Actif |
|
||||
|
||||
### 🔧 **Configuration des Certificats SSL**
|
||||
|
||||
| Domaine | Certificat | Expiration | Statut |
|
||||
|---------|------------|------------|--------|
|
||||
| **dev4.4nkweb.com** | `/etc/letsencrypt/live/dev4.4nkweb.com/` | 15 Déc 2025 | ✅ Valide |
|
||||
|
||||
### 📁 **Fichiers de Configuration**
|
||||
|
||||
| Fichier | Description | Statut |
|
||||
|---------|-------------|--------|
|
||||
| `/etc/nginx/sites-enabled/dev4.4nkweb.com.conf` | HTTP + Redirection | ✅ Actif |
|
||||
| `/etc/nginx/sites-enabled/dev4.4nkweb.com-https.conf` | HTTPS complet | ✅ Actif |
|
||||
| `/etc/nginx/sites-enabled/local.4nkweb.com.conf` | Local HTTP | ✅ Actif |
|
||||
| `/etc/nginx/sites-enabled/local.4nkweb.com-3000.conf` | Local port 3000 | ✅ Actif |
|
||||
|
||||
### 🧹 **Configuration Centralisée**
|
||||
|
||||
**Toutes les configurations Nginx sont centralisées dans `lecoffre_node/conf/nginx/` :**
|
||||
- ✅ **Configurations projet** : Supprimées des autres projets
|
||||
- ✅ **Configuration native** : Conservée dans `/etc/nginx/`
|
||||
- ✅ **Liens symboliques** : Pointent vers `lecoffre_node/conf/nginx/`
|
||||
- ✅ **Fichiers supprimés** : `ihm_client/nginx.dev.conf` (obsolète)
|
||||
|
||||
### ✅ **Statut Final**
|
||||
|
||||
1. **Configuration HTTPS active** : Le port 443 est en écoute ✅
|
||||
2. **Fichiers nettoyés** : Tous les fichiers de sauvegarde supprimés ✅
|
||||
3. **Configuration complète** : Tous les services accessibles en HTTPS ✅
|
||||
4. **Redirection HTTP → HTTPS** : Fonctionnelle ✅
|
||||
|
||||
### 🎉 **Services HTTPS Opérationnels**
|
||||
|
||||
- ✅ **Grafana** : `https://dev4.4nkweb.com/grafana/`
|
||||
- ✅ **Page de Statut** : `https://dev4.4nkweb.com/status/`
|
||||
- ✅ **API de Statut** : `https://dev4.4nkweb.com/status/api`
|
||||
- ✅ **Loki** : `https://dev4.4nkweb.com/loki/`
|
||||
- ✅ **IHM Client** : `https://dev4.4nkweb.com/`
|
||||
- ✅ **API Backend** : `https://dev4.4nkweb.com/api/`
|
||||
- ✅ **WebSocket Relay** : `https://dev4.4nkweb.com/ws/`
|
||||
- ✅ **SDK Signer** : `https://dev4.4nkweb.com/signer/`
|
||||
- ✅ **BlindBit** : `https://dev4.4nkweb.com/blindbit/`
|
||||
|
||||
---
|
||||
|
||||
**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**
|
@ -1,124 +0,0 @@
|
||||
# TODO - Améliorations et optimisations LeCoffre
|
||||
|
||||
## 📅 Date de mise à jour
|
||||
**2024-12-19**
|
||||
|
||||
## ✅ Tâches terminées
|
||||
|
||||
### Optimisation Docker (2024-12-19)
|
||||
- [x] Migration de tous les Dockerfiles vers Debian bookworm-slim
|
||||
- [x] Standardisation des packages minimaux (ca-certificates, curl, jq, git)
|
||||
- [x] Optimisation des utilisateurs non-root (appuser:1000)
|
||||
- [x] Création d'une image de base réutilisable
|
||||
- [x] Suppression des packages de développement inutiles
|
||||
- [x] Réduction drastique de la taille des images (70-80%)
|
||||
- [x] Résolution des erreurs 413 Request Entity Too Large
|
||||
- [x] Déclenchement des builds CI avec les nouveaux tags `ext`
|
||||
|
||||
### Services optimisés
|
||||
- [x] sdk_relay : Debian + Rust binary optimisé
|
||||
- [x] sdk_signer : Debian + Node.js 20 optimisé
|
||||
- [x] sdk_storage : Debian + Rust binary optimisé
|
||||
- [x] lecoffre-back-mini : Debian + Node.js 19 optimisé
|
||||
- [x] lecoffre-front : Debian + Node.js 19 optimisé
|
||||
- [x] ihm_client : Debian + Node.js 20 optimisé
|
||||
- [x] miner : Debian + Python 3.11 optimisé
|
||||
|
||||
## 🔄 Tâches en cours
|
||||
|
||||
### Validation des builds CI
|
||||
- [ ] Vérifier le succès des builds CI pour tous les services
|
||||
- [ ] Tester le déploiement des nouvelles images optimisées
|
||||
- [ ] Valider le fonctionnement des services avec les nouvelles images
|
||||
- [ ] Vérifier que les dashboards Grafana fonctionnent correctement
|
||||
|
||||
## 📋 Tâches à faire
|
||||
|
||||
### Monitoring et observabilité
|
||||
- [ ] Mettre en place des alertes sur la taille des images Docker
|
||||
- [ ] Créer des métriques de performance des builds CI
|
||||
- [ ] Optimiser les dashboards Grafana pour les nouvelles images
|
||||
- [ ] Implémenter des tests de régression pour les images
|
||||
|
||||
### Documentation et formation
|
||||
- [ ] Mettre à jour les README avec les nouvelles bases Docker
|
||||
- [ ] Documenter le processus de création de nouveaux services
|
||||
- [ ] Créer un guide de contribution avec les nouvelles règles
|
||||
- [ ] Former l'équipe sur l'architecture Docker optimisée
|
||||
|
||||
### Optimisations futures
|
||||
- [ ] Implémenter le multi-stage builds pour réduire davantage les images
|
||||
- [ ] Optimiser les layers Docker avec des outils comme dive
|
||||
- [ ] Mettre en place des scans de sécurité des images
|
||||
- [ ] Automatiser les mises à jour des bases Debian
|
||||
|
||||
### Infrastructure
|
||||
- [ ] Optimiser les volumes Docker pour les logs
|
||||
- [ ] Implémenter la rotation automatique des logs
|
||||
- [ ] Améliorer la configuration Nginx pour les nouveaux services
|
||||
- [ ] Optimiser les variables d'environnement
|
||||
|
||||
### Tests et qualité
|
||||
- [ ] Créer des tests d'intégration pour tous les services
|
||||
- [ ] Implémenter des tests de performance des images
|
||||
- [ ] Valider la compatibilité avec les différents environnements
|
||||
- [ ] Tester les rollbacks en cas de problème
|
||||
|
||||
## 🚀 Améliorations suggérées
|
||||
|
||||
### Architecture
|
||||
- [ ] Considérer l'utilisation de Docker Compose profiles pour différents environnements
|
||||
- [ ] Implémenter un système de health checks plus robuste
|
||||
- [ ] Optimiser les réseaux Docker pour la communication inter-services
|
||||
- [ ] Considérer l'utilisation de secrets Docker pour les données sensibles
|
||||
|
||||
### Performance
|
||||
- [ ] Optimiser les temps de démarrage des services
|
||||
- [ ] Implémenter des caches pour les builds Docker
|
||||
- [ ] Optimiser l'utilisation des ressources (CPU, mémoire)
|
||||
- [ ] Implémenter des stratégies de scaling automatique
|
||||
|
||||
### Sécurité
|
||||
- [ ] Mettre en place des scans de vulnérabilités automatiques
|
||||
- [ ] Implémenter des politiques de sécurité strictes
|
||||
- [ ] Optimiser les permissions des utilisateurs Docker
|
||||
- [ ] Mettre en place des audits de sécurité réguliers
|
||||
|
||||
## 📊 Métriques à suivre
|
||||
|
||||
### Images Docker
|
||||
- Taille des images (objectif : < 300MB)
|
||||
- Temps de build (objectif : < 10 minutes)
|
||||
- Taux de succès des builds CI (objectif : > 95%)
|
||||
|
||||
### Services
|
||||
- Temps de démarrage (objectif : < 30 secondes)
|
||||
- Disponibilité (objectif : > 99.9%)
|
||||
- Performance des APIs (objectif : < 200ms)
|
||||
|
||||
### Infrastructure
|
||||
- Utilisation des ressources (CPU, mémoire, disque)
|
||||
- Latence réseau entre services
|
||||
- Volume des logs générés
|
||||
|
||||
## 🎯 Objectifs à court terme (1-2 semaines)
|
||||
1. Valider le fonctionnement de tous les services avec les nouvelles images
|
||||
2. Mettre à jour la documentation utilisateur
|
||||
3. Former l'équipe sur les nouvelles pratiques
|
||||
4. Implémenter les alertes de monitoring
|
||||
|
||||
## 🎯 Objectifs à moyen terme (1-2 mois)
|
||||
1. Optimiser davantage les performances
|
||||
2. Implémenter des tests automatisés complets
|
||||
3. Mettre en place des stratégies de déploiement avancées
|
||||
4. Améliorer la sécurité globale
|
||||
|
||||
## 🎯 Objectifs à long terme (3-6 mois)
|
||||
1. Migration vers une architecture microservices plus avancée
|
||||
2. Implémentation de la haute disponibilité
|
||||
3. Optimisation pour la scalabilité horizontale
|
||||
4. Intégration avec des outils de CI/CD plus avancés
|
||||
|
||||
---
|
||||
|
||||
**Note** : Ce document doit être mis à jour régulièrement pour refléter l'évolution du projet et les nouvelles priorités.
|
258
README-AUTONOMOUS.md
Normal file
258
README-AUTONOMOUS.md
Normal file
@ -0,0 +1,258 @@
|
||||
# 🚀 Architecture Autonome LeCoffre Node
|
||||
|
||||
## Vue d'ensemble
|
||||
|
||||
Cette architecture autonome permet de déployer l'ensemble de l'écosystème LeCoffre dans un seul conteneur Docker, avec Nginx intégré pour une autonomie complète.
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Container Master │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Nginx (Port 80) │ │
|
||||
│ │ - Reverse Proxy │ │
|
||||
│ │ - Load Balancing │ │
|
||||
│ │ - SSL Termination │ │
|
||||
│ │ - Rate Limiting │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Supervisor │ │
|
||||
│ │ - Process Management │ │
|
||||
│ │ - Auto-restart │ │
|
||||
│ │ - Log Management │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
│ ┌─────────────────────────────────────────────────┐ │
|
||||
│ │ Docker Compose Services │ │
|
||||
│ │ - Bitcoin Signet │ │
|
||||
│ │ - SDK Relay/Signer/Storage │ │
|
||||
│ │ - LeCoffre Front/Back │ │
|
||||
│ │ - IHM Client │ │
|
||||
│ │ - Grafana/Loki/Promtail │ │
|
||||
│ └─────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 📁 Structure des fichiers
|
||||
|
||||
```
|
||||
lecoffre_node/
|
||||
├── Dockerfile.master # Image Docker autonome
|
||||
├── .env.master # Configuration avec secrets
|
||||
├── env.master # Variables publiques
|
||||
├── docker-compose.yml # Services internes
|
||||
├── conf/
|
||||
│ ├── nginx/
|
||||
│ │ └── nginx.conf # Configuration Nginx intégrée
|
||||
│ └── supervisor/
|
||||
│ └── supervisord.conf # Gestion des processus
|
||||
├── scripts/
|
||||
│ ├── entrypoint.sh # Point d'entrée principal
|
||||
│ ├── startup.sh # Démarrage des services
|
||||
│ └── deploy-autonomous.sh # Script de déploiement
|
||||
└── README-AUTONOMOUS.md # Cette documentation
|
||||
```
|
||||
|
||||
## 🔐 Sécurité
|
||||
|
||||
### Protection des secrets
|
||||
- Tous les fichiers `.env` sont protégés par `.gitignore`
|
||||
- Les secrets sont centralisés dans `.env.master`
|
||||
- Variables sensibles : clés API, mots de passe, tokens
|
||||
|
||||
### Variables protégées
|
||||
```bash
|
||||
# IdNot
|
||||
IDNOT_API_KEY=ba557f84-0bf6-4dbf-844f-df2767555e3e
|
||||
IDNOT_CLIENT_SECRET=3F733549E879878344B6C949B366BB5CDBB2DB5B7F7AB7EBBEBB0F0DD0776D1C
|
||||
|
||||
# OVH
|
||||
OVH_APP_SECRET=de1fac1779d707d263a611a557cd5766
|
||||
OVH_CONSUMER_KEY=5fe817829b8a9c780cfa2354f8312ece
|
||||
|
||||
# Stripe
|
||||
STRIPE_SECRET_KEY=sk_test_51OwKmMP5xh1u9BqSeFpqw0Yr15hHtFsh0pvRGaE0VERhlYtvw33ND1qiGA6Dy1DPmmV61B6BqIimlhuv7bwElhjF00PLQwD60n
|
||||
|
||||
# Grafana
|
||||
GF_SECURITY_ADMIN_PASSWORD=Fuy8ZfxQI2xdSdoB8wsGxNjyU
|
||||
```
|
||||
|
||||
## 🚀 Déploiement
|
||||
|
||||
### Prérequis
|
||||
- Docker et Docker Compose installés
|
||||
- Ports 80, 443, 3000 disponibles (le conteneur utilise son propre Nginx)
|
||||
- Accès au socket Docker (`/var/run/docker.sock`)
|
||||
- **Nginx du host supprimé** pour éviter les conflits
|
||||
|
||||
### Déploiement automatique
|
||||
```bash
|
||||
cd /home/debian/4NK_env/lecoffre_node
|
||||
./scripts/deploy-autonomous.sh
|
||||
```
|
||||
|
||||
### Déploiement manuel
|
||||
```bash
|
||||
# 1. Construction de l'image
|
||||
docker build -f Dockerfile.master -t lecoffre-node-master:ext .
|
||||
|
||||
# 2. Démarrage du conteneur (utilise le port 80 du host)
|
||||
docker run -d \
|
||||
--name lecoffre-node-master \
|
||||
--privileged \
|
||||
--restart unless-stopped \
|
||||
-p 80:80 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v $(pwd)/data:/app/data \
|
||||
-v $(pwd)/logs:/app/logs \
|
||||
-v $(pwd)/.env.master:/app/.env \
|
||||
lecoffre-node-master:ext
|
||||
```
|
||||
|
||||
### Désinstallation du Nginx du host (optionnel)
|
||||
```bash
|
||||
# Pour une indépendance complète, désinstaller Nginx du host
|
||||
./scripts/uninstall-host-nginx.sh
|
||||
```
|
||||
|
||||
## 🌐 Services exposés
|
||||
|
||||
| Service | URL | Description |
|
||||
|---------|-----|-------------|
|
||||
| Status Page | http://localhost/status/ | Tableau de bord des services |
|
||||
| Grafana | http://localhost/grafana/ | Monitoring et logs |
|
||||
| LeCoffre Front | http://localhost/lecoffre/ | Application principale |
|
||||
| IHM Client | http://localhost/ | Interface client |
|
||||
| API Backend | http://localhost/api/ | API REST |
|
||||
| WebSocket | ws://localhost/ws/ | Communication temps réel |
|
||||
| **Redirections IdNot** | http://local.4nkweb.com:3000/ | Redirections externes IdNot |
|
||||
| **HTTPS** | https://localhost/ | Accès sécurisé (certificats auto-signés) |
|
||||
|
||||
## 🔧 Gestion
|
||||
|
||||
### Commandes utiles
|
||||
```bash
|
||||
# Voir les logs
|
||||
docker logs lecoffre-node-master
|
||||
|
||||
# Accéder au shell
|
||||
docker exec -it lecoffre-node-master bash
|
||||
|
||||
# Redémarrer le conteneur
|
||||
docker restart lecoffre-node-master
|
||||
|
||||
# Arrêter le conteneur
|
||||
docker stop lecoffre-node-master
|
||||
|
||||
# Voir les services internes
|
||||
docker exec lecoffre-node-master docker-compose ps
|
||||
```
|
||||
|
||||
### Surveillance
|
||||
```bash
|
||||
# Healthcheck automatique
|
||||
docker inspect lecoffre-node-master | grep Health -A 10
|
||||
|
||||
# Vérification des services
|
||||
curl -f http://localhost:8080/status/api/health
|
||||
```
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Grafana Dashboards
|
||||
- **Bitcoin Miner** : Surveillance du minage Signet
|
||||
- **Backend Services** : Métriques des APIs
|
||||
- **SDK Services** : État des services SDK
|
||||
- **Frontend Services** : Performance des interfaces
|
||||
- **Bitcoin Services** : État du réseau Bitcoin
|
||||
|
||||
### Logs centralisés
|
||||
- Tous les logs sont collectés par Promtail
|
||||
- Stockage dans Loki
|
||||
- Visualisation dans Grafana
|
||||
- Rotation automatique des logs
|
||||
|
||||
## 🔄 Maintenance
|
||||
|
||||
### Sauvegarde
|
||||
```bash
|
||||
# Sauvegarde des données
|
||||
docker exec lecoffre-node-master tar -czf /app/backup/backup-$(date +%Y%m%d).tar.gz /app/data
|
||||
|
||||
# Restauration
|
||||
docker exec lecoffre-node-master tar -xzf /app/backup/backup-YYYYMMDD.tar.gz -C /
|
||||
```
|
||||
|
||||
### Mise à jour
|
||||
```bash
|
||||
# 1. Arrêter le conteneur
|
||||
docker stop lecoffre-node-master
|
||||
|
||||
# 2. Reconstruire l'image
|
||||
docker build -f Dockerfile.master -t lecoffre-node-master:ext .
|
||||
|
||||
# 3. Redémarrer
|
||||
docker start lecoffre-node-master
|
||||
```
|
||||
|
||||
## 🚨 Dépannage
|
||||
|
||||
### Problèmes courants
|
||||
|
||||
1. **Services non accessibles**
|
||||
```bash
|
||||
docker logs lecoffre-node-master
|
||||
docker exec lecoffre-node-master docker-compose ps
|
||||
```
|
||||
|
||||
2. **Problème de permissions Docker**
|
||||
```bash
|
||||
sudo chmod 666 /var/run/docker.sock
|
||||
```
|
||||
|
||||
3. **Ports déjà utilisés**
|
||||
```bash
|
||||
sudo netstat -tulpn | grep :8080
|
||||
sudo fuser -k 8080/tcp
|
||||
```
|
||||
|
||||
### Logs détaillés
|
||||
```bash
|
||||
# Logs du conteneur master
|
||||
docker logs lecoffre-node-master -f
|
||||
|
||||
# Logs des services internes
|
||||
docker exec lecoffre-node-master tail -f /app/logs/docker-compose.log
|
||||
|
||||
# Logs Nginx
|
||||
docker exec lecoffre-node-master tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
## 📝 Configuration
|
||||
|
||||
### Variables d'environnement principales
|
||||
- `EXTERNAL_DOMAIN` : Domaine externe (dev4.4nkweb.com)
|
||||
- `INTERNAL_DOMAIN` : Domaine interne (localhost)
|
||||
- `DOCKER_NETWORK_SUBNET` : Sous-réseau Docker
|
||||
- `GF_SECURITY_ADMIN_PASSWORD` : Mot de passe Grafana
|
||||
|
||||
### Personnalisation
|
||||
1. Modifier `.env.master` pour les secrets
|
||||
2. Ajuster `conf/nginx/nginx.conf` pour le routage
|
||||
3. Configurer `conf/supervisor/supervisord.conf` pour les processus
|
||||
|
||||
## 🎯 Avantages
|
||||
|
||||
✅ **Autonomie complète** : Un seul conteneur pour tout l'écosystème
|
||||
✅ **Sécurité renforcée** : Secrets centralisés et protégés
|
||||
✅ **Monitoring intégré** : Grafana, Loki, Promtail inclus
|
||||
✅ **Facilité de déploiement** : Script automatisé
|
||||
✅ **Scalabilité** : Architecture modulaire
|
||||
✅ **Maintenance simplifiée** : Gestion centralisée
|
||||
|
||||
## 📞 Support
|
||||
|
||||
Pour toute question ou problème :
|
||||
1. Vérifier les logs : `docker logs lecoffre-node-master`
|
||||
2. Consulter la documentation des services individuels
|
||||
3. Tester la connectivité : `curl http://localhost:8080/status/`
|
@ -24,3 +24,4 @@ RUN chmod +x /usr/local/bin/install-packages.sh
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
||||
|
@ -13,3 +13,4 @@ sudo apt-get install -y --fix-missing "$@" && \
|
||||
sudo rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
echo "Packages installed successfully!"
|
||||
|
||||
|
@ -396,3 +396,4 @@
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
||||
|
@ -529,3 +529,4 @@
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
||||
|
@ -529,3 +529,4 @@
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
||||
|
@ -588,3 +588,4 @@
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
||||
|
@ -616,3 +616,4 @@
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
||||
|
||||
|
509
conf/nginx/nginx.conf
Normal file
509
conf/nginx/nginx.conf
Normal file
@ -0,0 +1,509 @@
|
||||
user www-data;
|
||||
worker_processes auto;
|
||||
pid /run/nginx.pid;
|
||||
include /etc/nginx/modules-enabled/*.conf;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
# Configuration de base
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
server_tokens off;
|
||||
|
||||
# MIME types
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
|
||||
# Rate limiting
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
|
||||
|
||||
# Upstream servers
|
||||
upstream lecoffre_backend {
|
||||
server localhost:8080;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream lecoffre_frontend {
|
||||
server localhost:3004;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream ihm_client {
|
||||
server localhost:3003;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream grafana {
|
||||
server localhost:3005;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream loki {
|
||||
server localhost:3100;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream status_api {
|
||||
server localhost:3006;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream sdk_relay {
|
||||
server localhost:8090;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream sdk_signer {
|
||||
server localhost:3001;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream blindbit {
|
||||
server localhost:8000;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
# Serveur principal HTTP (port 80)
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
server_name _;
|
||||
|
||||
# Redirection automatique vers HTTPS si disponible
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
# Serveur HTTPS (port 443)
|
||||
server {
|
||||
listen 443 ssl http2 default_server;
|
||||
listen [::]:443 ssl http2 default_server;
|
||||
server_name _;
|
||||
|
||||
# Certificats SSL (auto-signés pour le développement)
|
||||
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
|
||||
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
|
||||
|
||||
# Configuration SSL
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
# 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;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Page de statut des services
|
||||
location /status/ {
|
||||
alias /var/www/lecoffre/status/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /status/index.html;
|
||||
|
||||
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1h;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# API de statut des services
|
||||
location /status/api {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
proxy_pass http://status_api/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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
# Grafana - Interface de monitoring
|
||||
location /grafana/ {
|
||||
proxy_pass http://grafana/;
|
||||
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_set_header X-Grafana-Org-Id 1;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
}
|
||||
|
||||
# Loki API - API de logs
|
||||
location /loki/ {
|
||||
limit_req zone=api burst=10 nodelay;
|
||||
proxy_pass http://loki/;
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
|
||||
# API backend - routes /back/ vers /api/
|
||||
location ~* ^/back/(.*)$ {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
proxy_pass http://lecoffre_backend/api/$1;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
# API direct - routes /api/
|
||||
location /api/ {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
|
||||
# CORS dynamique
|
||||
set $cors_origin "";
|
||||
if ($http_origin ~* ^(http://localhost:3000|http://local\.4nkweb\.com:3000|https://dev4\.4nkweb\.com)$) {
|
||||
set $cors_origin $http_origin;
|
||||
}
|
||||
|
||||
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://lecoffre_backend/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;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
|
||||
# WebSocket relay (sdk_relay)
|
||||
location /ws/ {
|
||||
proxy_pass http://sdk_relay/;
|
||||
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_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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
}
|
||||
|
||||
# API de transfert de fonds
|
||||
location /api/v1/funds/ {
|
||||
limit_req zone=api burst=5 nodelay;
|
||||
proxy_pass http://lecoffre_backend/api/v1/funds/;
|
||||
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;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
|
||||
# favicon
|
||||
location = /favicon.ico {
|
||||
root /var/www/lecoffre/assets;
|
||||
try_files /favicon.ico =404;
|
||||
}
|
||||
|
||||
# blindbit
|
||||
location /blindbit/ {
|
||||
proxy_pass http://blindbit/;
|
||||
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;
|
||||
}
|
||||
|
||||
# signer (sdk_signer) avec support WebSocket
|
||||
location /signer/ {
|
||||
proxy_pass http://sdk_signer/;
|
||||
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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 300;
|
||||
}
|
||||
|
||||
# LeCoffre Front - Application principale
|
||||
location /lecoffre/ {
|
||||
proxy_pass http://lecoffre_frontend/;
|
||||
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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 300;
|
||||
|
||||
# Configuration spécifique pour Next.js
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Server $host;
|
||||
}
|
||||
|
||||
# ihm_client (root) - DOIT être en dernier
|
||||
location / {
|
||||
proxy_pass http://ihm_client;
|
||||
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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 300;
|
||||
}
|
||||
}
|
||||
|
||||
# Serveur pour redirections externes IdNot (port 3000)
|
||||
server {
|
||||
listen 3000 default_server;
|
||||
listen [::]:3000 default_server;
|
||||
server_name local.4nkweb.com;
|
||||
|
||||
# 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;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Page de statut des services
|
||||
location /status/ {
|
||||
alias /var/www/lecoffre/status/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /status/index.html;
|
||||
|
||||
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1h;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# API de statut des services
|
||||
location /status/api {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
proxy_pass http://status_api/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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
# Grafana - Interface de monitoring
|
||||
location /grafana/ {
|
||||
proxy_pass http://grafana/;
|
||||
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_set_header X-Grafana-Org-Id 1;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
}
|
||||
|
||||
# API backend - routes /back/ vers /api/
|
||||
location ~* ^/back/(.*)$ {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
proxy_pass http://lecoffre_backend/api/$1;
|
||||
proxy_http_version 1.1;
|
||||
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_set_header Connection "";
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
# API direct - routes /api/
|
||||
location /api/ {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
|
||||
# CORS dynamique pour développement local
|
||||
set $cors_origin "";
|
||||
if ($http_origin ~* ^(http://local\.4nkweb\.com:3000|http://localhost:3000|https://dev4\.4nkweb\.com)$) {
|
||||
set $cors_origin $http_origin;
|
||||
}
|
||||
|
||||
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://lecoffre_backend/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;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
|
||||
# WebSocket relay (sdk_relay)
|
||||
location /ws/ {
|
||||
proxy_pass http://sdk_relay/;
|
||||
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_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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 86400;
|
||||
}
|
||||
|
||||
# LeCoffre Front - Application principale
|
||||
location /lecoffre/ {
|
||||
proxy_pass http://lecoffre_frontend/;
|
||||
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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 300;
|
||||
|
||||
# Configuration spécifique pour Next.js
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Server $host;
|
||||
}
|
||||
|
||||
# ihm_client (root) - DOIT être en dernier
|
||||
location / {
|
||||
proxy_pass http://ihm_client;
|
||||
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_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 300;
|
||||
}
|
||||
}
|
||||
}
|
50
conf/supervisor/supervisord.conf
Normal file
50
conf/supervisor/supervisord.conf
Normal file
@ -0,0 +1,50 @@
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
user=root
|
||||
logfile=/var/log/supervisor/supervisord.log
|
||||
pidfile=/var/run/supervisord.pid
|
||||
childlogdir=/var/log/supervisor
|
||||
|
||||
[unix_http_server]
|
||||
file=/var/run/supervisor.sock
|
||||
chmod=0700
|
||||
|
||||
[supervisorctl]
|
||||
serverurl=unix:///var/run/supervisor.sock
|
||||
|
||||
[rpcinterface:supervisor]
|
||||
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx -g "daemon off;"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/var/log/supervisor/nginx.err.log
|
||||
stdout_logfile=/var/log/supervisor/nginx.out.log
|
||||
user=root
|
||||
|
||||
[program:docker-compose]
|
||||
command=/app/scripts/startup.sh
|
||||
directory=/app
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/var/log/supervisor/docker-compose.err.log
|
||||
stdout_logfile=/var/log/supervisor/docker-compose.out.log
|
||||
user=appuser
|
||||
environment=HOME="/app"
|
||||
|
||||
[program:cron]
|
||||
command=/usr/sbin/cron -f
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stderr_logfile=/var/log/supervisor/cron.err.log
|
||||
stdout_logfile=/var/log/supervisor/cron.out.log
|
||||
user=root
|
||||
|
||||
[program:logrotate]
|
||||
command=/usr/sbin/logrotate /etc/logrotate.d/lecoffre
|
||||
autostart=true
|
||||
autorestart=false
|
||||
startsecs=0
|
||||
exitcodes=0
|
||||
user=root
|
@ -89,3 +89,4 @@ curl -s -u admin:Fuy8ZfxQI2xdSdoB8wsGxNjyU \
|
||||
**Date de mise à jour**: 21 Septembre 2025
|
||||
**Version**: 1.0
|
||||
**Responsable**: Déploiement LeCoffre Node
|
||||
|
||||
|
@ -141,3 +141,4 @@ Implémentation réussie de dashboards Grafana spécialisés pour le monitoring
|
||||
✅ **Scripts améliorés**: Tests et validation automatisés
|
||||
|
||||
Le système de monitoring Grafana est maintenant opérationnel et prêt pour la production.
|
||||
|
||||
|
@ -181,3 +181,4 @@ git push origin refs/tags/ext:refs/tags/ext
|
||||
**Auteur** : Assistant IA
|
||||
**Validation** : En attente des tests de déploiement
|
||||
**Statut** : ✅ Optimisation terminée, builds CI en cours
|
||||
|
||||
|
@ -159,3 +159,4 @@ curl -s http://localhost:3100/loki/api/v1/labels
|
||||
✅ **Sécurité renforcée**: Mot de passe fort déployé et testé
|
||||
|
||||
Le système de monitoring LeCoffre Node est maintenant **pleinement opérationnel** avec des dashboards **alimentés en données temps réel** ! 🎉
|
||||
|
||||
|
@ -160,3 +160,4 @@ status-api Up 0.0.0.0:3006->3006/tcp
|
||||
**Services opérationnels :** 8/10
|
||||
**Accessibilité externe :** ✅ Fonctionnelle
|
||||
**Configuration :** ✅ Complète et centralisée
|
||||
|
||||
|
@ -191,3 +191,4 @@ Le flux fonctionnel principal est **OPÉRATIONNEL** :
|
||||
- ✅ WebSockets temps réel opérationnels
|
||||
|
||||
Le seul problème identifié concerne les routes Stripe qui nécessitent une correction de configuration, mais n'empêche pas le test du flux principal de login notaire → IdNot → iframe.
|
||||
|
||||
|
1
lecoffre_node
Submodule
1
lecoffre_node
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 66479e38ceb34ed21f40272172cb060899ba1cc9
|
75
miner/tools/priv_key.json
Normal file
75
miner/tools/priv_key.json
Normal file
@ -0,0 +1,75 @@
|
||||
[
|
||||
{
|
||||
"Mnemonic": "tower keen enrich problem essence east plastic lounge merge sand increase company",
|
||||
"xprv": "tprv8inwidD6qpNwMNY5ZadhYMn62d1WHvSVMRH2pPAj7RsAZGCY4YTiT1McMQSg5DAyijPBZ4HroX83vZQAevQkJSZUVH8kro9JnVbhTPBSAxL",
|
||||
"wallet descriptor": "wsh(multi(1,[86936c07/48'/1'/0'/2']tpubDFUys3FLzC4cEqZsTEJHwmSCbeXSTFdPvisp6uD2XhfZPkTJgwHJdVyUXYcfLRrikRxA2MpBaZWE5kZCtHFc15aVtktsHMrTijDjq2dKRGK/0/*))#pslna7dm",
|
||||
},
|
||||
{
|
||||
"Mnemonic": "deer trust ceiling youth brass rapid scout cradle better clap spike morning",
|
||||
"xprv": "tprv8iNgodqVZKJgEFGhmoouPYPAj7EzaqjqToGcdZGUTVcDpu8YSvvhmoppYp7vWG2LR2SrF93AVYZGgG9bCzuQs1xqwJ2QW8hRwtEVdyUofuH",
|
||||
"wallet descriptor": "wsh(multi(1,[5df7e4b0/48'/1'/0'/2']tpubDF4ix3sjhgzM7iJVfTUVnx3HJ8kvkAvk36sPv5JmsmQcfPPK5KkHxJSgixZAdcYEsGcvHacm1hW4iLksGoTZocJozuaA2BTNp3GEvW432qu/0/*))#4ma3uvl0"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "control load guard error caution hundred main adjust happy infant safe brother",
|
||||
"xprv": "tprv8hTsDtqzaXPoZtQSrfR4HKfAXo1qmh8Xb6oJt5PY5WtET5ecfZ8bUEBoofVrH6s8STU586QHhYSppmQ3n1nvsZ6p5VaKu4MHxsvzUf1gg2D",
|
||||
"wallet descriptor": "wsh(multi(1,[a3a9eb52/48'/1'/0'/2']tpubDE9uNJtEiu5UTMSEkK5egjKH6pXmw2KSAQQ6AbRqVngdHZuPHwxBeiofypHrGmG1WkvAtgjjn7gmPddzaz3ymQj9m3CDFLGEB6Ao4xqripj/0/*))#ju6z6s7v"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "venture ice crash venture tourist tail naive curtain pilot engage code celery",
|
||||
"xprv": "tprv8iTk1ZRgwq4NAysrRgY1Wbycbfvmb7cYgjAGTeR573gKFJ4BFuGtEoaotCS6wdGiUfC2BTHg79tiX7i6NuFiTfjiaM8LXfNzL77YuBGY3K7",
|
||||
"wallet descriptor": "wsh(multi(1,[46d93da5/48'/1'/0'/2']tpubDF9n9yTw6Ck34SueKLCbv1djAhShkSoTG2m3kATNXKUi5nJwtJ6URJCg4M1je81fyabsX4t6F2itrQinMuu3cYLbpLbVQwWBUwYA8pPyKdZ/0/*))#8q8j9sft"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "sheriff zone betray cactus error enable code flat coyote worry guitar equal",
|
||||
"xprv": "tprv8iajQdFf4a7eUEKhE1gukrNEcxY4MZk1FJyKWgwZj48mhqTminKn6mkxyfyn1QwJ2XUke2aiXfXNQ2XqpGBbwXSSRK8hvqHQJuHWHs68YTh",
|
||||
"wallet descriptor": "wsh(multi(1,[d3c3bc8f/48'/1'/0'/2']tpubDFGmZ3HuCwoKMhMV7fMWAG2MBz3zWtvupca6oCys9KwAYKiYMB9NHGNq9qvVgPgDgpDLSiCqnp71f7WsV9N1cLkzsjqW9gxJF9VQ9oSZcj9/0/*))#7r3f3xys"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "bottom sight mistake next reveal modify rather bulk mountain arrow useful buzz",
|
||||
"xprv": "tprv8hqVmTiP493atpsuqdt87Hx5hjU9NwHG9hrWBa97rS8TwTYZBK5Jd8BfH4Jv154oP9YRWy7kU9p7xnqTwXCAnKZuEpACt2uzTx83HrTjqen",
|
||||
"wallet descriptor": "wsh(multi(1,[7f7d263a/48'/1'/0'/2']tpubDEXXuskdCWjFnHuhjHYiWhcCGkz5YGUAj1THU6BRGhvrmwoKohttocoXTCCE9udffumcou7ZYUR5RNqwHW4kw7Jv2UXUUSKeKqJd9xGmSCs/0/*))#zc5ruh7c"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "payment ill whisper noble casual shallow clown pipe keen pencil fluid term""xprv": "tprv8hMLjbE25N5UhZJadZDHb42RNFhgfSLdcsGnhu7BYt5Wt8UzXhcF5ANLuezsgJUNyCC4TJtekes9gssUCm6UKASnqMTPwm6KcePSw4npybF""wallet descriptor": "wsh(multi(1,[154159b3/48'/1'/0'/2']tpubDE3Nt1GGDjm9b2LNXCsszTgXwHDcpmXYCAsZzR9Uy9suicjmA6RqFezD5o8EWHk1vrztkPreHbYXKqGAdupKJNcKWYViKsQNMfr4uW8vcWq/0/*))#5k6w6h6g"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "lesson trumpet royal bright three oval vague organ atom joke favorite april",
|
||||
"xprv": "tprv8ixSxhVBoDTfv846JKDo5Qu8L89wZnmXUZCwdN1sm8CRfS1RpecrWmtthiTqepjnBroRit3Zygn53z3v8QWp3bqQYjev2Mn92g9jGkzaGya",
|
||||
"wallet descriptor": "wsh(multi(1,[fca68db6/48'/1'/0'/2']tpubDFeV77XRwb9Lob5tBxtPUpZEu9fsj7xS3roiut4BBPzpVvGCT3SShGWksqUYLqKBrt7xeKmmmgSrgbRiffcoS5KPiqyDWk5Kgvxek52XnNV/0/*))#j6sm3ntm"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "lyrics undo baby chicken possible vicious capital fun order salon maple source",
|
||||
"xprv": "tprv8ixaRLep3QQB2Rn9UpXXJVt9qcrDL6QTuHJusiKjPPgzkPmDveAQNBViJBrJakLKaoc3w7JzNUXAkSaeQHJAzGsMnrJQggWNkMn1e9rihgP",
|
||||
"wallet descriptor": "wsh(multi(1,[ef9d9ce6/48'/1'/0'/2']tpubDFecZkh4Bn5qutowNUC7huYGQeN9VRbNUauhAEN2ofVPat1zZ2yzYg7aULxsdzh79AFz7rBTVQeu2BsBay88XrFLc5diENj4ibizrwPNMbM/0/*))#zyhj4kj3"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "canoe coral egg public boss stable mercy side tennis behind dance shy",
|
||||
"xprv": "tprv8j58z2XeVe29DeDqb8UABtF14mo4MCPWm5CmkL5BegHBa3prhkLz2HF4JFwU5Z6ypnA7qCVcwdyPGj5yqXPoXiaE2Rcosmx9Ntiav39vRfp",
|
||||
"wallet descriptor": "wsh(multi(1,[8e236875/48'/1'/0'/2']tpubDFmB8SZte1hp77FdUn8kbHu7doJzWXaRLNoZ2r7V4x5aQY5dL9AaCmrvUNZSPYHJKeqto8roTvUpwWFazfxHEg5DvMq8br266uuD1JKieWj/0/*))#8xxkeruq"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "expire document depend hamster spy become blossom midnight ecology salon all earth",
|
||||
"xprv": "tprv8ii6Q43XVJhTrqb9oYUgz1kXXUc763g8c3tgZK38ei9Bwkaw12wEdXzgemB6fmF4jgDBAdavNg4YXyRe1XSx3jxjZ8i2fHruuyn6bP4r7uq",
|
||||
"wallet descriptor": "wsh(multi(1,[d03aacca/48'/1'/0'/2']tpubDFQ8YU5mdgP8kJcwhC9HPRQe6W83FNs3BMVTqq5S4ywanEqhdRkpp2cYpro3XRXKJPi8d1d3m4L2JXWdNQFfs31x37S3zfPpd7pwKEwLAm7/0/*))#phcw966k"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "movie west unit carbon adapt liberty crack easily raise toward brother quality",
|
||||
"xprv": "tprv8iszPBk3CEovNt6aHBMHPqeejpNJVKCqws1jfmHobNiC2s497W2jL9nde2FmTBWKMpkuKXDuFKPrBqKcEpsjgYeLsoQVT3MgsHoTjTL64qB",
|
||||
"wallet descriptor": "wsh(multi(1,[ce3600ea/48'/1'/0'/2']tpubDFa2XbnHLcVbGM8NAq1soFJmJqtEeePkXAcWxHL71eWasMJujtrKWeQVp7NHQY5euJL2bFuBkVQHk4uoDrVRfCEELLxJhHuNouPquffbmUy/0/*))#lwv5ura2"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "tip mixture supreme govern faculty panel judge motion aim write soon arrive",
|
||||
"xprv": "tprv8hJQahhR4cqcu6hkUkpVx3ex9tUxNWrY5EFd4zLdxT5Ycn3V14Kp6V7XLEtJ2N5p5dpVeP9mhMqNwTBBeJaavMDquLh8SRFfdDejAy8yygX",
|
||||
"wallet descriptor": "wsh(multi(1,[fe898c92/48'/1'/0'/2']tpubDDzSj7jfCzXHnZjYNQV6MTK4iuztXr3SeXrQMWNwNiswTGJFdT9QGyjPWMoYcoPY9HCYbLdcMGiDokrWDWWZEhg8HpbgebenhJujvTzMeeN/0/*))#675457w4"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "identify devote dice young air turkey angle code observe innocent fragile bench",
|
||||
"xprv": "tprv8iUcGCBaM1XJqsswVqLkJjgQjvKHmGaKrvX9sqBrmRrUTroa5EKEes4x3L7AFE7tLDW4mUCWLmpAhFrjQvZ1uUzuAaziFvLwrtq253g9yzp",
|
||||
"wallet descriptor": "wsh(multi(1,[d33c583b/48'/1'/0'/2']tpubDFAeQcDpVPCyjLujPV1Li9LXJwqDvbmESE7wAMEABhesJM4Lhd8pqMgpDVSmf4cpdsfZbDWkhfyxeyG3SaWcB4MqEqhbseQ8mk41PPHb57T/0/*))#u9xx2lkz"
|
||||
},
|
||||
{
|
||||
"Mnemonic": "slide hollow decade federal pair brief furnace fit pelican heart better place",
|
||||
"xprv": "tprv8iVREMet5hjVGBfng2VLnsrTMPqPDFkVoUAqoy78zKEye1u6XaG8jKju3nsf6GN1UTMbkFWoD6TiTTvnP2ez4NvXyX9c1UMfQ932CmZjuLg",
|
||||
"wallet descriptor": "wsh(multi(1,[facf6b1f/48'/1'/0'/2']tpubDFBTNmh8E5RA9ehaZg9wCHWZvRMKNawQNmmd6V9SQb3NUW9s9y5iupMmDxAbBFFrytzotW9hu8REgqSFg26Q8mcvBjSAaVz9QcNzmCxRJdv/0/*))#3407up02"
|
||||
}
|
||||
]
|
25
miner/tools/pubkeys.json
Normal file
25
miner/tools/pubkeys.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"type": "wsh",
|
||||
"multi": "sortedmulti",
|
||||
"min": "1",
|
||||
"pubkeys": [
|
||||
"[fca68db6/48'/1'/0'/2']tpubDFeV77XRwb9Lob5tBxtPUpZEu9fsj7xS3roiut4BBPzpVvGCT3SShGWksqUYLqKBrt7xeKmmmgSrgbRiffcoS5KPiqyDWk5Kgvxek52XnNV/0/*",
|
||||
"[5df7e4b0/48'/1'/0'/2']tpubDF4ix3sjhgzM7iJVfTUVnx3HJ8kvkAvk36sPv5JmsmQcfPPK5KkHxJSgixZAdcYEsGcvHacm1hW4iLksGoTZocJozuaA2BTNp3GEvW432qu/0/*",
|
||||
"[ef9d9ce6/48'/1'/0'/2']tpubDFecZkh4Bn5qutowNUC7huYGQeN9VRbNUauhAEN2ofVPat1zZ2yzYg7aULxsdzh79AFz7rBTVQeu2BsBay88XrFLc5diENj4ibizrwPNMbM/0/*",
|
||||
"[86936c07/48'/1'/0'/2']tpubDFUys3FLzC4cEqZsTEJHwmSCbeXSTFdPvisp6uD2XhfZPkTJgwHJdVyUXYcfLRrikRxA2MpBaZWE5kZCtHFc15aVtktsHMrTijDjq2dKRGK/0/*",
|
||||
"[7f7d263a/48'/1'/0'/2']tpubDEXXuskdCWjFnHuhjHYiWhcCGkz5YGUAj1THU6BRGhvrmwoKohttocoXTCCE9udffumcou7ZYUR5RNqwHW4kw7Jv2UXUUSKeKqJd9xGmSCs/0/*",
|
||||
"[154159b3/48'/1'/0'/2']tpubDE3Nt1GGDjm9b2LNXCsszTgXwHDcpmXYCAsZzR9Uy9suicjmA6RqFezD5o8EWHk1vrztkPreHbYXKqGAdupKJNcKWYViKsQNMfr4uW8vcWq/0/*",
|
||||
"[46d93da5/48'/1'/0'/2']tpubDF9n9yTw6Ck34SueKLCbv1djAhShkSoTG2m3kATNXKUi5nJwtJ6URJCg4M1je81fyabsX4t6F2itrQinMuu3cYLbpLbVQwWBUwYA8pPyKdZ/0/*",
|
||||
"[d3c3bc8f/48'/1'/0'/2']tpubDFGmZ3HuCwoKMhMV7fMWAG2MBz3zWtvupca6oCys9KwAYKiYMB9NHGNq9qvVgPgDgpDLSiCqnp71f7WsV9N1cLkzsjqW9gxJF9VQ9oSZcj9/0/*",
|
||||
"[8e236875/48'/1'/0'/2']tpubDFmB8SZte1hp77FdUn8kbHu7doJzWXaRLNoZ2r7V4x5aQY5dL9AaCmrvUNZSPYHJKeqto8roTvUpwWFazfxHEg5DvMq8br266uuD1JKieWj/0/*",
|
||||
"[a3a9eb52/48'/1'/0'/2']tpubDE9uNJtEiu5UTMSEkK5egjKH6pXmw2KSAQQ6AbRqVngdHZuPHwxBeiofypHrGmG1WkvAtgjjn7gmPddzaz3ymQj9m3CDFLGEB6Ao4xqripj/0/*",
|
||||
"[d03aacca/48'/1'/0'/2']tpubDFQ8YU5mdgP8kJcwhC9HPRQe6W83FNs3BMVTqq5S4ywanEqhdRkpp2cYpro3XRXKJPi8d1d3m4L2JXWdNQFfs31x37S3zfPpd7pwKEwLAm7/0/*",
|
||||
"[ce3600ea/48'/1'/0'/2']tpubDFa2XbnHLcVbGM8NAq1soFJmJqtEeePkXAcWxHL71eWasMJujtrKWeQVp7NHQY5euJL2bFuBkVQHk4uoDrVRfCEELLxJhHuNouPquffbmUy/0/*",
|
||||
"[fe898c92/48'/1'/0'/2']tpubDDzSj7jfCzXHnZjYNQV6MTK4iuztXr3SeXrQMWNwNiswTGJFdT9QGyjPWMoYcoPY9HCYbLdcMGiDokrWDWWZEhg8HpbgebenhJujvTzMeeN/0/*",
|
||||
"[d33c583b/48'/1'/0'/2']tpubDFAeQcDpVPCyjLujPV1Li9LXJwqDvbmESE7wAMEABhesJM4Lhd8pqMgpDVSmf4cpdsfZbDWkhfyxeyG3SaWcB4MqEqhbseQ8mk41PPHb57T/0/*",
|
||||
"[facf6b1f/48'/1'/0'/2']tpubDFBTNmh8E5RA9ehaZg9wCHWZvRMKNawQNmmd6V9SQb3NUW9s9y5iupMmDxAbBFFrytzotW9hu8REgqSFg26Q8mcvBjSAaVz9QcNzmCxRJdv/0/*"
|
||||
],
|
||||
"checksum": "#jmqku76u",
|
||||
"signet_challenge": "0020341c43803863c252df326e73574a27d7e19322992061017b0dc893e2eab90821",
|
||||
"magic": "b066463d"
|
||||
}
|
115
scripts/deploy-autonomous.sh
Executable file
115
scripts/deploy-autonomous.sh
Executable file
@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🚀 DÉPLOIEMENT DE L'ARCHITECTURE AUTONOME COMPLÈTE"
|
||||
echo "================================================="
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Variables
|
||||
MASTER_IMAGE_NAME="lecoffre-node-master"
|
||||
MASTER_IMAGE_TAG="ext"
|
||||
CONTAINER_NAME="lecoffre-node-master"
|
||||
HOST_PORT=80
|
||||
|
||||
log "🔧 Préparation de l'environnement..."
|
||||
|
||||
# Vérification des prérequis
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log "❌ Docker non disponible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
log "❌ Docker Compose non disponible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "✅ Prérequis validés"
|
||||
|
||||
# Arrêt des services existants
|
||||
log "🛑 Arrêt des services existants..."
|
||||
cd /home/debian/4NK_env/lecoffre_node
|
||||
docker compose down 2>/dev/null || true
|
||||
|
||||
# Construction de l'image master
|
||||
log "🏗️ Construction de l'image master..."
|
||||
docker build -f Dockerfile.master -t ${MASTER_IMAGE_NAME}:${MASTER_IMAGE_TAG} .
|
||||
|
||||
log "🧹 Nettoyage des conteneurs existants..."
|
||||
docker stop ${CONTAINER_NAME} 2>/dev/null || true
|
||||
docker rm ${CONTAINER_NAME} 2>/dev/null || true
|
||||
|
||||
# Création des répertoires de données
|
||||
log "📁 Création des répertoires de données..."
|
||||
mkdir -p /home/debian/4NK_env/lecoffre_node/{data,logs,backup}
|
||||
|
||||
log "🚀 Démarrage du conteneur master autonome..."
|
||||
log "ℹ️ Le conteneur utilise son propre Nginx (ports 80, 443, 3000) - indépendant du host"
|
||||
log "ℹ️ Port 3000 pour redirections externes IdNot (local.4nkweb.com:3000)"
|
||||
docker run -d \
|
||||
--name ${CONTAINER_NAME} \
|
||||
--privileged \
|
||||
--restart unless-stopped \
|
||||
-p 80:80 \
|
||||
-p 443:443 \
|
||||
-p 3000:3000 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /home/debian/4NK_env/lecoffre_node/data:/app/data \
|
||||
-v /home/debian/4NK_env/lecoffre_node/logs:/app/logs \
|
||||
-v /home/debian/4NK_env/lecoffre_node/conf:/app/conf \
|
||||
-v /home/debian/4NK_env/lecoffre_node/backup:/app/backup \
|
||||
-v /home/debian/4NK_env/lecoffre_node/.env.master:/app/.env \
|
||||
${MASTER_IMAGE_NAME}:${MASTER_IMAGE_TAG}
|
||||
|
||||
log "⏳ Attente du démarrage du conteneur master..."
|
||||
sleep 30
|
||||
|
||||
log "🔍 Vérification du statut du conteneur..."
|
||||
docker ps | grep ${CONTAINER_NAME}
|
||||
|
||||
log "🧪 Test de connectivité des services..."
|
||||
sleep 20
|
||||
|
||||
# Tests de connectivité
|
||||
services=(
|
||||
"http://localhost:${HOST_PORT}/status/|Status Page"
|
||||
"http://localhost:${HOST_PORT}/grafana/|Grafana"
|
||||
"http://localhost:${HOST_PORT}/lecoffre/|LeCoffre Front"
|
||||
"http://localhost:${HOST_PORT}/|IHM Client"
|
||||
"http://localhost:${HOST_PORT}/api/v1/health|API Backend"
|
||||
)
|
||||
|
||||
for service in "${services[@]}"; do
|
||||
IFS='|' read -r url name <<< "$service"
|
||||
if curl -f -s "$url" > /dev/null 2>&1; then
|
||||
log "✅ $name: Accessible"
|
||||
else
|
||||
log "⚠️ $name: Inaccessible (peut être normal pendant le démarrage)"
|
||||
fi
|
||||
done
|
||||
|
||||
log "📊 Logs du conteneur master:"
|
||||
docker logs ${CONTAINER_NAME} --tail 10
|
||||
|
||||
log "🎉 Architecture autonome déployée!"
|
||||
log "📋 Services disponibles:"
|
||||
log " - Status Page: http://localhost:${HOST_PORT}/status/"
|
||||
log " - Grafana: http://localhost:${HOST_PORT}/grafana/"
|
||||
log " - LeCoffre Front: http://localhost:${HOST_PORT}/lecoffre/"
|
||||
log " - IHM Client: http://localhost:${HOST_PORT}/"
|
||||
log " - API Backend: http://localhost:${HOST_PORT}/api/"
|
||||
log ""
|
||||
log "🔧 Architecture autonome:"
|
||||
log " - Nginx intégré dans le conteneur (port 80)"
|
||||
log " - Indépendant du Nginx du host"
|
||||
log " - Toutes les configurations dans lecoffre_node/"
|
||||
log ""
|
||||
log "🔧 Commandes utiles:"
|
||||
log " - Logs: docker logs ${CONTAINER_NAME}"
|
||||
log " - Shell: docker exec -it ${CONTAINER_NAME} bash"
|
||||
log " - Redémarrage: docker restart ${CONTAINER_NAME}"
|
||||
log " - Arrêt: docker stop ${CONTAINER_NAME}"
|
71
scripts/deploy-master.sh
Executable file
71
scripts/deploy-master.sh
Executable file
@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🚀 DÉPLOIEMENT DE L'ARCHITECTURE AUTONOME LECOFFRE NODE"
|
||||
echo "======================================================"
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Variables
|
||||
MASTER_IMAGE_NAME="lecoffre-node-master"
|
||||
MASTER_IMAGE_TAG="ext"
|
||||
CONTAINER_NAME="lecoffre-node-master"
|
||||
HOST_PORT=8080
|
||||
|
||||
log "Construction de l'image master..."
|
||||
cd /home/debian/4NK_env/lecoffre_node
|
||||
|
||||
# Construction de l'image master
|
||||
docker build -f Dockerfile.master -t ${MASTER_IMAGE_NAME}:${MASTER_IMAGE_TAG} .
|
||||
|
||||
log "Arrêt du conteneur existant (si présent)..."
|
||||
docker stop ${CONTAINER_NAME} 2>/dev/null || true
|
||||
docker rm ${CONTAINER_NAME} 2>/dev/null || true
|
||||
|
||||
log "Démarrage du conteneur master..."
|
||||
docker run -d \
|
||||
--name ${CONTAINER_NAME} \
|
||||
--privileged \
|
||||
-p ${HOST_PORT}:80 \
|
||||
-p 3005:3005 \
|
||||
-p 3006:3006 \
|
||||
-p 8080:8080 \
|
||||
-p 3003:3003 \
|
||||
-p 3004:3004 \
|
||||
-p 8090:8090 \
|
||||
-p 8091:8091 \
|
||||
-p 8000:8000 \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /home/debian/4NK_env/lecoffre_node/data:/app/data \
|
||||
-v /home/debian/4NK_env/lecoffre_node/logs:/app/logs \
|
||||
-v /home/debian/4NK_env/lecoffre_node/conf:/app/conf \
|
||||
-v /home/debian/4NK_env/lecoffre_node/backup:/app/backup \
|
||||
${MASTER_IMAGE_NAME}:${MASTER_IMAGE_TAG}
|
||||
|
||||
log "Attente du démarrage du conteneur master..."
|
||||
sleep 30
|
||||
|
||||
log "Vérification du statut du conteneur..."
|
||||
docker ps | grep ${CONTAINER_NAME}
|
||||
|
||||
log "Test de connectivité..."
|
||||
sleep 10
|
||||
if curl -f -s http://localhost:${HOST_PORT}/status/ > /dev/null; then
|
||||
log "✅ Architecture autonome déployée avec succès!"
|
||||
log "📊 Services disponibles:"
|
||||
log " - Status Page: http://localhost:${HOST_PORT}/status/"
|
||||
log " - Grafana: http://localhost:${HOST_PORT}/grafana/"
|
||||
log " - LeCoffre Front: http://localhost:${HOST_PORT}/lecoffre/"
|
||||
log " - IHM Client: http://localhost:${HOST_PORT}/"
|
||||
log " - API Backend: http://localhost:${HOST_PORT}/api/"
|
||||
else
|
||||
log "❌ Problème de déploiement détecté"
|
||||
log "Logs du conteneur:"
|
||||
docker logs ${CONTAINER_NAME} --tail 20
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "🎉 Déploiement terminé avec succès!"
|
87
scripts/entrypoint.sh
Executable file
87
scripts/entrypoint.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🚀 DÉMARRAGE DU CONTAINER MASTER LECOFFRE_NODE"
|
||||
echo "=============================================="
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Vérification des prérequis
|
||||
log "Vérification des prérequis..."
|
||||
|
||||
# Vérifier que Docker est disponible
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log "❌ Docker non disponible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que docker-compose est disponible
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
log "❌ Docker Compose non disponible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que Nginx est configuré
|
||||
if [ ! -f /etc/nginx/nginx.conf ]; then
|
||||
log "❌ Configuration Nginx manquante"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "✅ Prérequis validés"
|
||||
|
||||
# Initialisation des répertoires
|
||||
log "Initialisation des répertoires..."
|
||||
mkdir -p /app/data /app/logs /var/log/supervisor
|
||||
chown -R appuser:appuser /app/data /app/logs
|
||||
|
||||
# Configuration des permissions Docker
|
||||
if [ -S /var/run/docker.sock ]; then
|
||||
chown appuser:appuser /var/run/docker.sock
|
||||
fi
|
||||
|
||||
# Test de la configuration Nginx
|
||||
log "Test de la configuration Nginx..."
|
||||
if ! nginx -t; then
|
||||
log "❌ Configuration Nginx invalide"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "✅ Configuration Nginx valide"
|
||||
|
||||
# Initialisation de la base de données Docker Compose
|
||||
log "Initialisation Docker Compose..."
|
||||
cd /app
|
||||
|
||||
# Création du réseau Docker si nécessaire
|
||||
docker network create lecoffre_network 2>/dev/null || true
|
||||
|
||||
# Préparation des variables d'environnement
|
||||
log "Configuration des variables d'environnement..."
|
||||
export COMPOSE_PROJECT_NAME=lecoffre
|
||||
export COMPOSE_FILE=/app/docker-compose.yml
|
||||
|
||||
# Démarrage des services en arrière-plan
|
||||
log "Démarrage des services Docker Compose..."
|
||||
nohup docker-compose up -d > /app/logs/docker-compose.log 2>&1 &
|
||||
DOCKER_COMPOSE_PID=$!
|
||||
|
||||
# Attente du démarrage des services
|
||||
log "Attente du démarrage des services..."
|
||||
sleep 30
|
||||
|
||||
# Vérification de l'état des services
|
||||
log "Vérification de l'état des services..."
|
||||
docker-compose ps
|
||||
|
||||
log "✅ Container Master LeCoffre Node démarré avec succès"
|
||||
log "📊 Services disponibles:"
|
||||
log " - Nginx: http://localhost"
|
||||
log " - Status: http://localhost/status/"
|
||||
log " - Grafana: http://localhost/grafana/"
|
||||
|
||||
# Démarrage de Supervisor
|
||||
log "Démarrage de Supervisor..."
|
||||
exec "$@"
|
35
scripts/generate-ssl-certs.sh
Executable file
35
scripts/generate-ssl-certs.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🔐 GÉNÉRATION DES CERTIFICATS SSL AUTO-SIGNÉS"
|
||||
echo "============================================="
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Création des répertoires SSL
|
||||
log "Création des répertoires SSL..."
|
||||
mkdir -p /etc/ssl/certs /etc/ssl/private
|
||||
|
||||
# Génération de la clé privée
|
||||
log "Génération de la clé privée..."
|
||||
openssl genrsa -out /etc/ssl/private/nginx-selfsigned.key 2048
|
||||
|
||||
# Génération du certificat auto-signé
|
||||
log "Génération du certificat auto-signé..."
|
||||
openssl req -new -x509 -key /etc/ssl/private/nginx-selfsigned.key \
|
||||
-out /etc/ssl/certs/nginx-selfsigned.crt \
|
||||
-days 365 \
|
||||
-subj "/C=FR/ST=France/L=Paris/O=LeCoffre/OU=Development/CN=local.4nkweb.com/emailAddress=admin@lecoffre.io"
|
||||
|
||||
# Configuration des permissions
|
||||
log "Configuration des permissions..."
|
||||
chmod 600 /etc/ssl/private/nginx-selfsigned.key
|
||||
chmod 644 /etc/ssl/certs/nginx-selfsigned.crt
|
||||
|
||||
log "✅ Certificats SSL générés avec succès"
|
||||
log " Certificat: /etc/ssl/certs/nginx-selfsigned.crt"
|
||||
log " Clé privée: /etc/ssl/private/nginx-selfsigned.key"
|
||||
log " Valide pour: local.4nkweb.com"
|
@ -187,3 +187,4 @@ main() {
|
||||
main "$@"
|
||||
|
||||
|
||||
|
||||
|
@ -159,3 +159,4 @@ main() {
|
||||
main "$@"
|
||||
|
||||
|
||||
|
||||
|
121
scripts/startup.sh
Executable file
121
scripts/startup.sh
Executable file
@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🚀 DÉMARRAGE AUTONOME LECOFFRE NODE"
|
||||
echo "=================================="
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Chargement des variables d'environnement
|
||||
if [ -f /app/env.master ]; then
|
||||
log "Chargement des variables d'environnement..."
|
||||
export $(cat /app/env.master | grep -v '^#' | xargs)
|
||||
fi
|
||||
|
||||
# Vérification des prérequis
|
||||
log "Vérification des prérequis..."
|
||||
|
||||
# Vérifier que Docker est disponible
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log "❌ Docker non disponible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Vérifier que docker-compose est disponible
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
log "❌ Docker Compose non disponible"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "✅ Prérequis validés"
|
||||
|
||||
# Initialisation des répertoires
|
||||
log "Initialisation des répertoires..."
|
||||
mkdir -p /app/data /app/logs /app/backup /var/www/lecoffre/status /var/www/lecoffre/assets
|
||||
chown -R appuser:appuser /app/data /app/logs /app/backup
|
||||
|
||||
# Création du réseau Docker
|
||||
log "Création du réseau Docker..."
|
||||
docker network create ${DOCKER_NETWORK_NAME:-lecoffre_network} 2>/dev/null || true
|
||||
|
||||
# Configuration des volumes Docker
|
||||
log "Configuration des volumes Docker..."
|
||||
docker volume create lecoffre_bitcoin_data 2>/dev/null || true
|
||||
docker volume create lecoffre_blindbit_data 2>/dev/null || true
|
||||
docker volume create lecoffre_sdk_data 2>/dev/null || true
|
||||
docker volume create lecoffre_grafana_data 2>/dev/null || true
|
||||
docker volume create lecoffre_loki_data 2>/dev/null || true
|
||||
|
||||
# Démarrage des services
|
||||
log "Démarrage des services Docker Compose..."
|
||||
cd /app
|
||||
|
||||
# Export des variables pour docker-compose
|
||||
export COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-lecoffre}
|
||||
export COMPOSE_FILE=${COMPOSE_FILE:-docker-compose.yml}
|
||||
|
||||
# Démarrage en mode détaché
|
||||
docker-compose up -d
|
||||
|
||||
# Attente du démarrage des services
|
||||
log "Attente du démarrage des services..."
|
||||
sleep 30
|
||||
|
||||
# Vérification de l'état des services
|
||||
log "Vérification de l'état des services..."
|
||||
docker-compose ps
|
||||
|
||||
# Vérification de la santé des services
|
||||
log "Vérification de la santé des services..."
|
||||
for service in bitcoin-signet blindbit-oracle sdk_relay lecoffre-back ihm_client; do
|
||||
if docker-compose ps $service | grep -q "healthy\|Up"; then
|
||||
log "✅ $service: OK"
|
||||
else
|
||||
log "⚠️ $service: Problème détecté"
|
||||
fi
|
||||
done
|
||||
|
||||
# Test de connectivité
|
||||
log "Test de connectivité..."
|
||||
if curl -f -s http://localhost:8091/ > /dev/null; then
|
||||
log "✅ SDK Relay: Accessible"
|
||||
else
|
||||
log "❌ SDK Relay: Inaccessible"
|
||||
fi
|
||||
|
||||
if curl -f -s http://localhost:8080/api/v1/health > /dev/null; then
|
||||
log "✅ LeCoffre Back: Accessible"
|
||||
else
|
||||
log "❌ LeCoffre Back: Inaccessible"
|
||||
fi
|
||||
|
||||
if curl -f -s http://localhost:3003/ > /dev/null; then
|
||||
log "✅ IHM Client: Accessible"
|
||||
else
|
||||
log "❌ IHM Client: Inaccessible"
|
||||
fi
|
||||
|
||||
log "✅ Démarrage autonome LeCoffre Node terminé"
|
||||
log "📊 Services disponibles:"
|
||||
log " - Nginx: http://localhost"
|
||||
log " - Status: http://localhost/status/"
|
||||
log " - Grafana: http://localhost/grafana/"
|
||||
log " - LeCoffre Front: http://localhost/lecoffre/"
|
||||
log " - IHM Client: http://localhost/"
|
||||
|
||||
# Boucle de surveillance
|
||||
log "Démarrage de la surveillance des services..."
|
||||
while true; do
|
||||
sleep 60
|
||||
|
||||
# Vérification périodique des services
|
||||
for service in bitcoin-signet sdk_relay lecoffre-back; do
|
||||
if ! docker-compose ps $service | grep -q "healthy\|Up"; then
|
||||
log "⚠️ Service $service en problème, redémarrage..."
|
||||
docker-compose restart $service
|
||||
fi
|
||||
done
|
||||
done
|
78
scripts/uninstall-host-nginx.sh
Executable file
78
scripts/uninstall-host-nginx.sh
Executable file
@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🗑️ DÉSINSTALLATION DU NGINX DU HOST"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
echo "⚠️ ATTENTION: Ce script va désinstaller Nginx du système host"
|
||||
echo " L'architecture autonome LeCoffre Node utilise son propre Nginx"
|
||||
echo ""
|
||||
|
||||
# Fonction de logging
|
||||
log() {
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||||
}
|
||||
|
||||
# Vérification que le conteneur LeCoffre est en cours d'exécution
|
||||
if ! docker ps | grep -q "lecoffre-node-master"; then
|
||||
log "❌ Le conteneur LeCoffre Node n'est pas en cours d'exécution"
|
||||
log " Démarrez d'abord l'architecture autonome avec:"
|
||||
log " ./scripts/deploy-autonomous.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "✅ Conteneur LeCoffre Node détecté et en cours d'exécution"
|
||||
|
||||
# Test de connectivité du Nginx du conteneur
|
||||
if curl -f -s http://localhost/status/ > /dev/null; then
|
||||
log "✅ Nginx du conteneur fonctionne correctement"
|
||||
else
|
||||
log "❌ Nginx du conteneur ne répond pas correctement"
|
||||
log " Vérifiez les logs: docker logs lecoffre-node-master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔍 État actuel du Nginx du host:"
|
||||
systemctl status nginx 2>/dev/null || echo "Nginx non installé ou arrêté"
|
||||
|
||||
echo ""
|
||||
read -p "Êtes-vous sûr de vouloir désinstaller Nginx du host ? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log "❌ Désinstallation annulée"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "🛑 Arrêt des services Nginx du host..."
|
||||
sudo systemctl stop nginx 2>/dev/null || true
|
||||
sudo systemctl disable nginx 2>/dev/null || true
|
||||
|
||||
log "🗑️ Désinstallation des paquets Nginx..."
|
||||
sudo apt-get remove --purge nginx nginx-common nginx-core -y || true
|
||||
sudo apt-get autoremove -y || true
|
||||
|
||||
log "🧹 Nettoyage des fichiers de configuration..."
|
||||
sudo rm -rf /etc/nginx/
|
||||
sudo rm -rf /var/www/html/
|
||||
sudo rm -rf /var/log/nginx/
|
||||
|
||||
log "🔧 Configuration du firewall pour le port 80..."
|
||||
# Autoriser le port 80 pour le conteneur
|
||||
sudo ufw allow 80/tcp 2>/dev/null || true
|
||||
|
||||
log "✅ Désinstallation terminée"
|
||||
log ""
|
||||
log "🎉 L'architecture autonome LeCoffre Node est maintenant complètement indépendante!"
|
||||
log ""
|
||||
log "📊 Services accessibles via le conteneur:"
|
||||
log " - Status Page: http://localhost/status/"
|
||||
log " - Grafana: http://localhost/grafana/"
|
||||
log " - LeCoffre Front: http://localhost/lecoffre/"
|
||||
log " - IHM Client: http://localhost/"
|
||||
log " - API Backend: http://localhost/api/"
|
||||
log ""
|
||||
log "🔧 Gestion du conteneur:"
|
||||
log " - Arrêt: docker stop lecoffre-node-master"
|
||||
log " - Redémarrage: docker restart lecoffre-node-master"
|
||||
log " - Logs: docker logs lecoffre-node-master"
|
@ -35,3 +35,4 @@ echo "[SUCCES] Tests sdk_relay passés"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,241 +3,103 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LeCoffre Node - Status des Services</title>
|
||||
<title>LeCoffre Node - Status</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
* { 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%);
|
||||
color: #333;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
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;
|
||||
color: white;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 10px;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 1.1em;
|
||||
font-size: 1.2em;
|
||||
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));
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
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;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
.status-indicator {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.status-up { background-color: #4CAF50; }
|
||||
.status-down { background-color: #f44336; }
|
||||
.status-warning { background-color: #ff9800; }
|
||||
.service-title {
|
||||
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;
|
||||
.service-description {
|
||||
color: #7f8c8d;
|
||||
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);
|
||||
.service-url {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #666;
|
||||
.service-url:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.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;
|
||||
color: white;
|
||||
margin-top: 30px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.services-grid {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
.refresh-btn {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin: 20px 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
.refresh-btn:hover {
|
||||
background: #2980b9;
|
||||
}
|
||||
.timestamp {
|
||||
color: #95a5a6;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -245,212 +107,112 @@
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🚀 LeCoffre Node</h1>
|
||||
<p>Status des Services et Connexions</p>
|
||||
<p>Architecture Autonome - Tableau de Bord des Services</p>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center;">
|
||||
<button class="refresh-btn" onclick="refreshStatus()">🔄 Actualiser</button>
|
||||
<div class="timestamp" id="timestamp"></div>
|
||||
</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 class="services-grid" id="services-grid">
|
||||
<!-- Les services seront chargés dynamiquement -->
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>LeCoffre Node - Monitoring en temps réel | <span id="footerTime"></span></p>
|
||||
<p>LeCoffre Node - Architecture Autonome Complète</p>
|
||||
<p>Monitoring et logs disponibles via Grafana</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' }
|
||||
{
|
||||
name: "Status API",
|
||||
description: "API de surveillance des services",
|
||||
url: "/status/api/health",
|
||||
endpoint: "/api/health"
|
||||
},
|
||||
{
|
||||
name: "Grafana",
|
||||
description: "Interface de monitoring et logs",
|
||||
url: "/grafana/",
|
||||
endpoint: "/grafana/"
|
||||
},
|
||||
{
|
||||
name: "LeCoffre Frontend",
|
||||
description: "Application principale LeCoffre",
|
||||
url: "/lecoffre/",
|
||||
endpoint: "/lecoffre/"
|
||||
},
|
||||
{
|
||||
name: "IHM Client",
|
||||
description: "Interface client 4NK",
|
||||
url: "/",
|
||||
endpoint: "/"
|
||||
},
|
||||
{
|
||||
name: "API Backend",
|
||||
description: "API REST LeCoffre",
|
||||
url: "/api/v1/health",
|
||||
endpoint: "/api/v1/health"
|
||||
},
|
||||
{
|
||||
name: "WebSocket Relay",
|
||||
description: "Communication temps réel",
|
||||
url: "/ws/",
|
||||
endpoint: "/ws/"
|
||||
}
|
||||
];
|
||||
|
||||
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 checkServiceStatus(service) {
|
||||
try {
|
||||
const response = await fetch(service.endpoint, {
|
||||
method: 'HEAD',
|
||||
timeout: 5000
|
||||
});
|
||||
return response.ok ? 'up' : 'down';
|
||||
} catch (error) {
|
||||
return 'down';
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshStatus() {
|
||||
document.getElementById('loading').style.display = 'block';
|
||||
document.getElementById('errorMessage').style.display = 'none';
|
||||
document.getElementById('servicesContainer').style.display = 'none';
|
||||
const grid = document.getElementById('services-grid');
|
||||
grid.innerHTML = '<div style="text-align: center; color: white;">Chargement...</div>';
|
||||
|
||||
try {
|
||||
const response = await fetch('/status/api');
|
||||
const data = await response.json();
|
||||
const serviceCards = await Promise.all(services.map(async (service) => {
|
||||
const status = await checkServiceStatus(service);
|
||||
const statusClass = `status-${status}`;
|
||||
const statusText = status === 'up' ? 'En ligne' : 'Hors ligne';
|
||||
|
||||
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>
|
||||
return `
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="status-indicator ${statusClass}"></div>
|
||||
<div class="service-title">${service.name}</div>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Image Docker:</span>
|
||||
<span class="detail-value">${serviceData.image}</span>
|
||||
<div class="service-description">${service.description}</div>
|
||||
<div>
|
||||
<a href="${service.url}" class="service-url" target="_blank">
|
||||
Accéder au service →
|
||||
</a>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">${service.protocol}</span>
|
||||
<div style="margin-top: 10px; font-size: 0.9em; color: #7f8c8d;">
|
||||
Statut: ${statusText}
|
||||
</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);
|
||||
});
|
||||
}));
|
||||
|
||||
grid.innerHTML = serviceCards.join('');
|
||||
document.getElementById('timestamp').textContent =
|
||||
`Dernière mise à jour: ${new Date().toLocaleString('fr-FR')}`;
|
||||
}
|
||||
|
||||
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
|
||||
// Actualisation automatique toutes les 30 secondes
|
||||
refreshStatus();
|
||||
setInterval(refreshStatus, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user