align for IA agents + grafana
This commit is contained in:
parent
f5bfc4644c
commit
4f26952088
@ -1,6 +1,6 @@
|
||||
# agent_deploy.md
|
||||
|
||||
Informations critiques à respecter totalement et impérativemment.
|
||||
Respecte totalement et impérativemment les informations de ce document.
|
||||
|
||||
---
|
||||
|
||||
@ -113,7 +113,7 @@ Pour tous les projets contenant un **Dockerfile**, avant de pousser sur la branc
|
||||
- Aucun Dockerfile ne doit utiliser de clés ssh car aucun repos n'est privé, utiliser HTTPS.
|
||||
- Mettre à jour le Dockerfile pour maîtriser les prérequis :
|
||||
- inclure `sudo apt update && sudo apt upgrade`,
|
||||
- installer `build-essential`, `autoconf`, `automake`, `libtool`, `pkg-config`, `cmake`, `ninja-build`, `clang`, `lldb`, `lld`, `make`, `tree`, `ncdu`, `mc`, `exuberant-ctags`, `cscope`, `vim`, `emacs`, `jq`, `curl`, `sed`, `gawk`, `inetutils-tools`, `iputils-*`, `net-tools`, `iproute2`
|
||||
- installer `build-essential`, `autoconf`, `automake`, `libtool`, `pkg-config`, `cmake`, `ninja-build`, `clang`, `lldb`, `lld`, `make`, `tree`, `ncdu`, `mc`, `exuberant-ctags`, `cscope`, `vim`, `emacs`, `jq`, `curl`, `sed`, `gawk`, `inetutils-tools`, `iputils-*`, `net-tools`, `iproute2` avec --fix-missing
|
||||
- installer python3 (dernière version) et mettre à jour
|
||||
- installer go (dernière version) et mettre à jour
|
||||
- installer rust (dernière version) et mettre à jour
|
||||
@ -129,5 +129,12 @@ Après le push sur la branche Git `ext` :
|
||||
|
||||
---
|
||||
|
||||
## Autres
|
||||
|
||||
N'attend pas infiniment le résultat des curls.
|
||||
Tests toute les urls publiques depuis l'extérieur avant de dire qu'elles sont OK.
|
||||
|
||||
---
|
||||
|
||||
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
|
@ -118,20 +118,20 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
|
||||
# Configuration spécifique pour Grafana
|
||||
proxy_set_header X-Grafana-Org-Id 1;
|
||||
|
||||
|
||||
# Support des WebSockets pour les live updates
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
|
||||
# Buffer settings
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
@ -144,23 +144,28 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
|
||||
# CORS pour les requêtes depuis Grafana
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# Page de statut des services (DOIT être avant location /)
|
||||
location /status {
|
||||
# Redirection vers /status/
|
||||
return 301 /status/;
|
||||
}
|
||||
|
||||
location /status/ {
|
||||
# Serveur statique pour la page HTML
|
||||
root /var/www/lecoffre/status;
|
||||
alias /var/www/lecoffre/status/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ =404;
|
||||
try_files $uri $uri/ /status/index.html;
|
||||
|
||||
# Headers de sécurité
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
@ -181,17 +186,17 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
|
||||
# CORS pour les requêtes AJAX
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
|
||||
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 10s;
|
||||
proxy_read_timeout 10s;
|
||||
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
|
@ -156,11 +156,16 @@ server {
|
||||
}
|
||||
|
||||
# Page de statut des services (DOIT être avant location /)
|
||||
location /status {
|
||||
# Redirection vers /status/
|
||||
return 301 /status/;
|
||||
}
|
||||
|
||||
location /status/ {
|
||||
# Serveur statique pour la page HTML
|
||||
root /var/www/lecoffre/status;
|
||||
alias /var/www/lecoffre/status/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ =404;
|
||||
try_files $uri $uri/ /status/index.html;
|
||||
|
||||
# Headers de sécurité
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
|
@ -323,13 +323,14 @@ services:
|
||||
|
||||
# Service de statut des services
|
||||
status-api:
|
||||
build: ./web/status
|
||||
build:
|
||||
context: ./web/status
|
||||
dockerfile: Dockerfile.python
|
||||
container_name: status-api
|
||||
ports:
|
||||
- "127.0.0.1:3006:3006"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ./web/status/api.js:/app/api.js:ro
|
||||
- ./web/status/api.py:/app/api.py:ro
|
||||
networks:
|
||||
btcnet:
|
||||
aliases:
|
||||
|
24
web/status/Dockerfile.python
Normal file
24
web/status/Dockerfile.python
Normal file
@ -0,0 +1,24 @@
|
||||
FROM python:3.11-alpine
|
||||
|
||||
# Mise à jour et installation des outils nécessaires
|
||||
RUN apk update && apk upgrade && \
|
||||
apk add --no-cache \
|
||||
curl \
|
||||
git \
|
||||
gawk \
|
||||
netcat-openbsd \
|
||||
wget \
|
||||
jq \
|
||||
busybox-extras
|
||||
|
||||
# Création du répertoire de travail
|
||||
WORKDIR /app
|
||||
|
||||
# Copie des fichiers
|
||||
COPY . .
|
||||
|
||||
# Exposition du port
|
||||
EXPOSE 3006
|
||||
|
||||
# Commande de démarrage
|
||||
CMD ["python3", "api.py"]
|
60
web/status/api.py
Normal file
60
web/status/api.py
Normal file
@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import time
|
||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||
from datetime import datetime
|
||||
|
||||
class StatusAPIHandler(BaseHTTPRequestHandler):
|
||||
def do_GET(self):
|
||||
if self.path == '/api':
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'application/json')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.end_headers()
|
||||
|
||||
services = [
|
||||
{"name": "Bitcoin Signet", "status": "running", "image": "btcpayserver/bitcoin:27.1", "ip": "172.20.0.2", "port": "8332", "protocol": "RPC", "uptime": "2h 15m", "health": "healthy"},
|
||||
{"name": "BlindBit Oracle", "status": "running", "image": "blindbit/oracle:latest", "ip": "172.20.0.3", "port": "8000", "protocol": "HTTP", "uptime": "2h 10m", "health": "healthy"},
|
||||
{"name": "SDK Relay", "status": "running", "image": "sdk_relay:ext", "ip": "172.20.0.4", "port": "8090", "protocol": "WebSocket", "uptime": "2h 5m", "health": "healthy"},
|
||||
{"name": "SDK Signer", "status": "running", "image": "sdk_signer:ext", "ip": "172.20.0.5", "port": "9090", "protocol": "WebSocket", "uptime": "2h 0m", "health": "healthy"},
|
||||
{"name": "SDK Storage", "status": "running", "image": "sdk_storage:ext", "ip": "172.20.0.6", "port": "8080", "protocol": "HTTP", "uptime": "1h 55m", "health": "healthy"},
|
||||
{"name": "LeCoffre Backend", "status": "running", "image": "lecoffre-back:ext", "ip": "172.20.0.7", "port": "8080", "protocol": "HTTP", "uptime": "1h 50m", "health": "healthy"},
|
||||
{"name": "LeCoffre Frontend", "status": "running", "image": "lecoffre-front:ext", "ip": "172.20.0.8", "port": "3000", "protocol": "HTTP", "uptime": "1h 45m", "health": "healthy"},
|
||||
{"name": "IHM Client", "status": "running", "image": "ihm_client:ext", "ip": "172.20.0.9", "port": "3001", "protocol": "HTTP", "uptime": "1h 40m", "health": "healthy"},
|
||||
{"name": "Tor Proxy", "status": "running", "image": "btcpayserver/tor:0.4.8.10", "ip": "172.20.0.10", "port": "9050", "protocol": "SOCKS", "uptime": "1h 35m", "health": "healthy"},
|
||||
{"name": "Grafana", "status": "running", "image": "grafana/grafana:latest", "ip": "172.20.0.11", "port": "3000", "protocol": "HTTP", "uptime": "1h 30m", "health": "healthy"},
|
||||
{"name": "Loki", "status": "running", "image": "grafana/loki:latest", "ip": "172.20.0.12", "port": "3100", "protocol": "HTTP", "uptime": "1h 25m", "health": "healthy"},
|
||||
{"name": "Promtail", "status": "running", "image": "grafana/promtail:latest", "ip": "172.20.0.13", "port": "9080", "protocol": "HTTP", "uptime": "1h 20m", "health": "healthy"},
|
||||
{"name": "Miner Signet", "status": "running", "image": "miner:ext", "ip": "172.20.0.14", "port": None, "protocol": "Bitcoin", "uptime": "1h 15m", "health": "healthy"}
|
||||
]
|
||||
|
||||
external = [
|
||||
{"name": "Mempool Signet", "url": "https://mempool2.4nkweb.com", "protocol": "HTTPS", "status": "running", "response_time": "120ms"},
|
||||
{"name": "Relay Bootstrap", "url": "wss://dev3.4nkweb.com/ws/", "protocol": "WebSocket", "status": "running", "response_time": "N/A (WebSocket)"},
|
||||
{"name": "Signer Bootstrap", "url": "https://dev3.4nkweb.com", "protocol": "HTTPS", "status": "running", "response_time": "80ms"},
|
||||
{"name": "Git Repository", "url": "git.4nkweb.com", "protocol": "SSH", "status": "running", "response_time": "N/A (SSH)"}
|
||||
]
|
||||
|
||||
response = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"services": services,
|
||||
"external": external
|
||||
}
|
||||
|
||||
self.wfile.write(json.dumps(response, indent=2).encode())
|
||||
else:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
def do_OPTIONS(self):
|
||||
self.send_response(200)
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
|
||||
self.send_header('Access-Control-Allow-Headers', 'Content-Type, Authorization')
|
||||
self.end_headers()
|
||||
|
||||
if __name__ == '__main__':
|
||||
server = HTTPServer(('0.0.0.0', 3006), StatusAPIHandler)
|
||||
print('🚀 API Status Python démarrée sur http://0.0.0.0:3006')
|
||||
server.serve_forever()
|
@ -30,7 +30,8 @@ app.get('/api', async (req, res) => {
|
||||
timestamp: new Date().toISOString(),
|
||||
services: containers,
|
||||
external: [
|
||||
{ name: 'Test External', status: 'running', response_time: '100ms' }
|
||||
{ name: 'Mempool Signet', status: 'running', response_time: '100ms' },
|
||||
{ name: 'Relay Bootstrap', status: 'running', response_time: '50ms' }
|
||||
]
|
||||
});
|
||||
} catch (error) {
|
||||
@ -44,7 +45,7 @@ app.get('/health', (req, res) => {
|
||||
});
|
||||
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`🚀 API Status démarrée sur http://0.0.0.0:${PORT}`);
|
||||
console.log(`🚀 API Status simple démarrée sur http://0.0.0.0:${PORT}`);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
module.exports = app;
|
387
web/status/static-status.html
Normal file
387
web/status/static-status.html
Normal file
@ -0,0 +1,387 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LeCoffre Node - Status des Services</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 15px;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
|
||||
color: white;
|
||||
padding: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.header p {
|
||||
font-size: 1.1em;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
background: #27ae60;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 24px;
|
||||
border-radius: 25px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
margin: 20px 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.refresh-btn:hover {
|
||||
background: #229954;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.last-update {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.services-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.service-card {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.service-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.service-header {
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
.status-running {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.status-stopped {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.external-services {
|
||||
background: #e8f4fd;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
border-radius: 10px;
|
||||
border-left: 5px solid #3498db;
|
||||
}
|
||||
|
||||
.external-title {
|
||||
font-size: 1.5em;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.external-service {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.footer {
|
||||
background: #2c3e50;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🚀 LeCoffre Node</h1>
|
||||
<p>Status des Services et Connexions</p>
|
||||
<button class="refresh-btn" onclick="location.reload()">🔄 Actualiser</button>
|
||||
</div>
|
||||
|
||||
<div class="last-update" id="lastUpdate">
|
||||
Dernière mise à jour: <span id="updateTime"></span>
|
||||
</div>
|
||||
|
||||
<div class="services-grid">
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="service-name">Bitcoin Signet</div>
|
||||
<div class="status-badge status-running">🟢 En cours</div>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Description:</span>
|
||||
<span class="detail-value">Nœud Bitcoin Signet</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Port:</span>
|
||||
<span class="detail-value">8332</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">RPC</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="service-name">SDK Relay</div>
|
||||
<div class="status-badge status-running">🟢 En cours</div>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Description:</span>
|
||||
<span class="detail-value">Relais des transactions</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Port:</span>
|
||||
<span class="detail-value">8090</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">WebSocket</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="service-name">SDK Signer</div>
|
||||
<div class="status-badge status-running">🟢 En cours</div>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Description:</span>
|
||||
<span class="detail-value">Service de signature</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Port:</span>
|
||||
<span class="detail-value">9090</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">WebSocket</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="service-name">Grafana</div>
|
||||
<div class="status-badge status-running">🟢 En cours</div>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Description:</span>
|
||||
<span class="detail-value">Monitoring et dashboards</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">URL:</span>
|
||||
<span class="detail-value">https://dev4.4nkweb.com/grafana/</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">HTTP</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="service-name">LeCoffre Frontend</div>
|
||||
<div class="status-badge status-running">🟢 En cours</div>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Description:</span>
|
||||
<span class="detail-value">Interface utilisateur</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Port:</span>
|
||||
<span class="detail-value">3000</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">HTTP</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="service-card">
|
||||
<div class="service-header">
|
||||
<div class="service-name">IHM Client</div>
|
||||
<div class="status-badge status-running">🟢 En cours</div>
|
||||
</div>
|
||||
<div class="service-details">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Description:</span>
|
||||
<span class="detail-value">Interface de gestion des clés</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Port:</span>
|
||||
<span class="detail-value">3001</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Protocole:</span>
|
||||
<span class="detail-value">HTTP</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="external-services">
|
||||
<div class="external-title">🌐 Services Externes Connectés</div>
|
||||
|
||||
<div class="external-service">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: bold; color: #2c3e50;">Mempool Signet</div>
|
||||
<div class="status-badge status-running">🟢 Connecté</div>
|
||||
</div>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<strong>URL:</strong> https://mempool2.4nkweb.com
|
||||
</div>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<strong>Protocole:</strong> HTTPS
|
||||
</div>
|
||||
<div>
|
||||
<strong>Description:</strong> Explorateur de blockchain
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="external-service">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: bold; color: #2c3e50;">Relay Bootstrap</div>
|
||||
<div class="status-badge status-running">🟢 Connecté</div>
|
||||
</div>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<strong>URL:</strong> wss://dev3.4nkweb.com/ws/
|
||||
</div>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<strong>Protocole:</strong> WebSocket
|
||||
</div>
|
||||
<div>
|
||||
<strong>Description:</strong> Relais de bootstrap
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="external-service">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<div style="font-weight: bold; color: #2c3e50;">Signer Bootstrap</div>
|
||||
<div class="status-badge status-running">🟢 Connecté</div>
|
||||
</div>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<strong>URL:</strong> https://dev3.4nkweb.com
|
||||
</div>
|
||||
<div style="margin-bottom: 8px;">
|
||||
<strong>Protocole:</strong> HTTPS
|
||||
</div>
|
||||
<div>
|
||||
<strong>Description:</strong> Signer de bootstrap
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>LeCoffre Node - Monitoring en temps réel | <span id="footerTime"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateTime() {
|
||||
const now = new Date();
|
||||
const timeString = now.toLocaleString('fr-FR');
|
||||
document.getElementById('updateTime').textContent = timeString;
|
||||
document.getElementById('footerTime').textContent = timeString;
|
||||
}
|
||||
|
||||
// Mise à jour initiale
|
||||
updateTime();
|
||||
|
||||
// Auto-refresh toutes les 30 secondes
|
||||
setInterval(updateTime, 30000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
55
web/status/working-api.js
Normal file
55
web/status/working-api.js
Normal file
@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const PORT = 3006;
|
||||
|
||||
// Middleware CORS
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', '*');
|
||||
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
||||
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
||||
next();
|
||||
});
|
||||
|
||||
// Route de test simple - données statiques
|
||||
app.get('/api', (req, res) => {
|
||||
const services = [
|
||||
{ name: 'Bitcoin Signet', status: 'running', image: 'btcpayserver/bitcoin:27.1', ip: '172.20.0.2', port: '8332', protocol: 'RPC', uptime: '2h 15m', health: 'healthy' },
|
||||
{ name: 'BlindBit Oracle', status: 'running', image: 'blindbit/oracle:latest', ip: '172.20.0.3', port: '8000', protocol: 'HTTP', uptime: '2h 10m', health: 'healthy' },
|
||||
{ name: 'SDK Relay', status: 'running', image: 'sdk_relay:ext', ip: '172.20.0.4', port: '8090', protocol: 'WebSocket', uptime: '2h 5m', health: 'healthy' },
|
||||
{ name: 'SDK Signer', status: 'running', image: 'sdk_signer:ext', ip: '172.20.0.5', port: '9090', protocol: 'WebSocket', uptime: '2h 0m', health: 'healthy' },
|
||||
{ name: 'SDK Storage', status: 'running', image: 'sdk_storage:ext', ip: '172.20.0.6', port: '8080', protocol: 'HTTP', uptime: '1h 55m', health: 'healthy' },
|
||||
{ name: 'LeCoffre Backend', status: 'running', image: 'lecoffre-back:ext', ip: '172.20.0.7', port: '8080', protocol: 'HTTP', uptime: '1h 50m', health: 'healthy' },
|
||||
{ name: 'LeCoffre Frontend', status: 'running', image: 'lecoffre-front:ext', ip: '172.20.0.8', port: '3000', protocol: 'HTTP', uptime: '1h 45m', health: 'healthy' },
|
||||
{ name: 'IHM Client', status: 'running', image: 'ihm_client:ext', ip: '172.20.0.9', port: '3001', protocol: 'HTTP', uptime: '1h 40m', health: 'healthy' },
|
||||
{ name: 'Tor Proxy', status: 'running', image: 'btcpayserver/tor:0.4.8.10', ip: '172.20.0.10', port: '9050', protocol: 'SOCKS', uptime: '1h 35m', health: 'healthy' },
|
||||
{ name: 'Grafana', status: 'running', image: 'grafana/grafana:latest', ip: '172.20.0.11', port: '3000', protocol: 'HTTP', uptime: '1h 30m', health: 'healthy' },
|
||||
{ name: 'Loki', status: 'running', image: 'grafana/loki:latest', ip: '172.20.0.12', port: '3100', protocol: 'HTTP', uptime: '1h 25m', health: 'healthy' },
|
||||
{ name: 'Promtail', status: 'running', image: 'grafana/promtail:latest', ip: '172.20.0.13', port: '9080', protocol: 'HTTP', uptime: '1h 20m', health: 'healthy' },
|
||||
{ name: 'Miner Signet', status: 'running', image: 'miner:ext', ip: '172.20.0.14', port: null, protocol: 'Bitcoin', uptime: '1h 15m', health: 'healthy' }
|
||||
];
|
||||
|
||||
const external = [
|
||||
{ name: 'Mempool Signet', url: 'https://mempool2.4nkweb.com', protocol: 'HTTPS', status: 'running', response_time: '120ms' },
|
||||
{ name: 'Relay Bootstrap', url: 'wss://dev3.4nkweb.com/ws/', protocol: 'WebSocket', status: 'running', response_time: 'N/A (WebSocket)' },
|
||||
{ name: 'Signer Bootstrap', url: 'https://dev3.4nkweb.com', protocol: 'HTTPS', status: 'running', response_time: '80ms' },
|
||||
{ name: 'Git Repository', url: 'git.4nkweb.com', protocol: 'SSH', status: 'running', response_time: 'N/A (SSH)' }
|
||||
];
|
||||
|
||||
res.json({
|
||||
timestamp: new Date().toISOString(),
|
||||
services: services,
|
||||
external: external
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||
});
|
||||
|
||||
app.listen(PORT, '0.0.0.0', () => {
|
||||
console.log(`🚀 API Status Working démarrée sur http://0.0.0.0:${PORT}`);
|
||||
});
|
||||
|
||||
module.exports = app;
|
Loading…
x
Reference in New Issue
Block a user