# 📘 Documentation complète : Architecture Duniter ĞTest #2
> **Serveur** : OMV avec Docker/Portainer
> **Réseau** : 192.168.1.101
> **Stack** : Archive (mirror) + Mirror (ws) + Smith + Squid (indexeur GraphQL)
> **Chain ID** : `0xd4586d7dd4c1c838dd3f826a99f3aadc0d44477ab3a72cf0f3494099f92cc57a`
---
## 🗺️ Architecture globale
```
Internet (HTTPS via Let's Encrypt)
│
├─── mirror.gtest.bulma.sleoconnect.fr
│ └─→ Nginx → 192.168.1.101:9949 (Archive node, profil "archive")
│
├─── ws.gtest.bulma.sleoconnect.fr
│ └─→ Nginx → 192.168.1.101:9947 (Mirror node, profil "mirror")
│
├─── smith.gtest.bulma.sleoconnect.fr
│ └─→ Nginx → 192.168.1.101:30334 (Smith node, localhost only)
│
└─── squid.gtest.bulma.sleoconnect.fr
├─→ /v1/graphql (API REST)
└─→ /graphiql (Interface de test)
└─→ Nginx → 192.168.1.101:8084
Réseau Docker interne (duniter-gtest)
│
├─── duniter-archive-gtest:9944 (mirror.gtest)
│ └─→ Volume: /srv/.../duniter-mirror/
│
├─── duniter-mirror-gtest:9944 (ws.gtest)
│ └─→ Volume: /srv/.../duniter-mirror-gtest/
│
├─── duniter-smith-gtest:9944 (smith.gtest, localhost)
│ └─→ Volume: /srv/.../duniter-smith/
│
└─── squid-processor-gtest
├─→ Lit ws://duniter-archive-gtest:9944
├─→ Écrit dans squid-db-gtest (PostgreSQL)
└─→ Expose via squid-graphql-gtest:8084
```
---
## 🐳 Stack 1 : Archive node (mirror.gtest.bulma.sleoconnect.fr)
**Nom du stack Portainer** : `duniter-v2s-gtest-1100-archive`
```yaml
version: "3.9"
networks:
duniter-gtest:
external: true
services:
duniter-archive-gtest:
image: duniter/duniter-v2s-gtest-1100:1000-0.12.0
container_name: duniter-archive-gtest
restart: unless-stopped
networks:
duniter-gtest:
ports:
- "0.0.0.0:9619:9615" # Prometheus (monitoring)
- "0.0.0.0:9939:9933" # HTTP RPC
- "0.0.0.0:9949:9944" # WebSocket RPC (public via reverse proxy)
- "0.0.0.0:30339:30333" # P2P
volumes:
- /srv/.../duniter-mirror:/var/lib/duniter
environment:
- DUNITER_CHAIN_NAME=gtest
- DUNITER_NODE_NAME=Bulmananabelle-Docker-OMV-Gtest-Archive
- DUNITER_PRUNING_PROFILE=archive
- DUNITER_LISTEN_ADDR=/ip4/0.0.0.0/tcp/30339
```
### Configuration Nginx (mirror.gtest.bulma.sleoconnect.fr)
**⚠️ Configuration Nginx Proxy Manager**
Pour les WebSocket RPC, utiliser http comme schéma backend, même si le frontend est en HTTPS.
Nginx gère le SSL entre le client et lui, puis redirige en HTTP vers le conteneur.
```nginx
# /etc/nginx/sites-available/mirror.gtest.bulma.sleoconnect.fr
upstream duniter_archive_backend {
server 192.168.1.101:9949;
}
server {
listen 80;
server_name mirror.gtest.bulma.sleoconnect.fr;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name mirror.gtest.bulma.sleoconnect.fr;
ssl_certificate /etc/letsencrypt/live/mirror.gtest.bulma.sleoconnect.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mirror.gtest.bulma.sleoconnect.fr/privkey.pem;
location / {
proxy_pass http://duniter_archive_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
```
---
## 🐳 Stack 2 : Mirror node (ws.gtest.bulma.sleoconnect.fr)
**Nom du stack Portainer** : `duniter-v2s-gtest-1100-mirror-ws`
```yaml
version: "3.9"
networks:
duniter-gtest:
external: true
services:
duniter-mirror-gtest:
image: duniter/duniter-v2s-gtest-1100:1000-0.12.0
container_name: duniter-mirror-gtest
restart: unless-stopped
networks:
duniter-gtest:
ports:
- "0.0.0.0:9617:9615" # Prometheus
- "0.0.0.0:9937:9933" # HTTP RPC
- "0.0.0.0:9947:9944" # WebSocket RPC (public)
- "0.0.0.0:30333:30333" # P2P
volumes:
- /srv/.../duniter-mirror-gtest:/var/lib/duniter
environment:
- DUNITER_CHAIN_NAME=gtest
- DUNITER_NODE_NAME=Bulmananabelle-Docker-OMV-Gtest-Mirror
- DUNITER_PRUNING_PROFILE=mirror
- DUNITER_LISTEN_ADDR=/ip4/0.0.0.0/tcp/30333
- DUNITER_PUBLIC_ADDR=/dns/ws.gtest.bulma.sleoconnect.fr/tcp/443/wss
```
### Configuration Nginx (ws.gtest.bulma.sleoconnect.fr)
**⚠️ Configuration Nginx Proxy Manager**
Pour les WebSocket RPC, utiliser http comme schéma backend, même si le frontend est en HTTPS.
Nginx gère le SSL entre le client et lui, puis redirige en HTTP vers le conteneur.
```nginx
# /etc/nginx/sites-available/ws.gtest.bulma.sleoconnect.fr
upstream duniter_mirror_backend {
server 192.168.1.101:9947;
}
server {
listen 80;
server_name ws.gtest.bulma.sleoconnect.fr;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name ws.gtest.bulma.sleoconnect.fr;
ssl_certificate /etc/letsencrypt/live/ws.gtest.bulma.sleoconnect.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ws.gtest.bulma.sleoconnect.fr/privkey.pem;
location / {
proxy_pass http://duniter_mirror_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}
```
---
## 🐳 Stack 3 : Smith node (localhost uniquement)
**Nom du stack Portainer** : `duniter-v2s-gtest-1100-smith`
```yaml
version: "3.9"
networks:
duniter-gtest:
external: true
services:
duniter-smith-gtest:
image: duniter/duniter-v2s-gtest-1100:1000-0.12.0
container_name: duniter-smith-gtest
restart: unless-stopped
networks:
duniter-gtest:
ports:
- "127.0.0.1:9618:9615" # Prometheus (localhost)
- "127.0.0.1:9948:9944" # WebSocket RPC (localhost)
- "0.0.0.0:30334:30333" # P2P
volumes:
- /srv/.../duniter-smith:/var/lib/duniter
environment:
- DUNITER_CHAIN_NAME=gtest
- DUNITER_NODE_NAME=Bulmananabelle-Docker-OMV-Gtest-Smith
- DUNITER_PRUNING_PROFILE=validator
```
> ⚠️ **Pas de reverse proxy** pour le port RPC (9944) du Smith (accès localhost uniquement via `gcli`)
---
## 🐳 Stack 4 : Squid indexeur GraphQL
**Nom du stack Portainer** : `duniter-squid-gtest`
```yaml
version: "3.9"
networks:
duniter-gtest:
external: true
services:
squid-db-gtest:
image: duniter/squid-postgres-gtest:0.5.5
container_name: squid-db-gtest
restart: unless-stopped
networks:
duniter-gtest:
environment:
POSTGRES_DB: squid
POSTGRES_USER: squid
POSTGRES_PASSWORD: squid
volumes:
- /srv/.../squid-gtest/db:/var/lib/postgresql/data
squid-processor-gtest:
image: duniter/squid-app-gtest:0.5.5 # ⚠️ Version stable (bug sur 0.5.6)
container_name: squid-processor-gtest
restart: unless-stopped
networks:
duniter-gtest:
depends_on:
- squid-db-gtest
environment:
- DB_NAME=squid
- DB_HOST=squid-db-gtest
- DB_PORT=5432
- DB_USER=squid
- DB_PASS=squid
- RPC_ENDPOINT=ws://duniter-archive-gtest:9944
- TYPES_BUNDLE=gtest.json
command: ["sqd", "process:prod"]
squid-graphql-gtest:
image: duniter/squid-graphile-gtest:0.5.5
container_name: squid-graphql-gtest
restart: unless-stopped
networks:
duniter-gtest:
depends_on:
- squid-db-gtest
ports:
- "0.0.0.0:8084:8084"
environment:
- DB_NAME=squid
- DB_HOST=squid-db-gtest
- DB_PORT=5432
- DB_USER=squid
- DB_PASS=squid
command: ["sqd", "serve:prod"]
```
### Configuration Nginx (squid.gtest.bulma.sleoconnect.fr)
```nginx
# /etc/nginx/sites-available/squid.gtest.bulma.sleoconnect.fr
upstream squid_graphql_backend {
server 192.168.1.101:8084;
}
server {
listen 80;
server_name squid.gtest.bulma.sleoconnect.fr;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name squid.gtest.bulma.sleoconnect.fr;
ssl_certificate /etc/letsencrypt/live/squid.gtest.bulma.sleoconnect.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/squid.gtest.bulma.sleoconnect.fr/privkey.pem;
location / {
proxy_pass http://squid_graphql_backend;
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;
}
}
```
---
## 📋 URLs d'accès publiques ĞTest #2
| Service | URL | Usage |
|---------|-----|-------|
| **Archive RPC** | `wss://mirror.gtest.bulma.sleoconnect.fr/` | Historique complet (Squid) |
| **Mirror RPC** | `wss://ws.gtest.bulma.sleoconnect.fr/` | Nœud public léger |
| **GraphQL API** | `https://squid.gtest.bulma.sleoconnect.fr/v1/graphql` | Requêtes indexées |
| **GraphiQL** | `https://squid.gtest.bulma.sleoconnect.fr/graphiql` | Interface de test |
| **Smith node** | `ws://127.0.0.1:9948` | Accès local uniquement |
| **Télémétrie** | [ĞTest #2 Telemetry](https://telemetry.polkadot.io/#list/0xd4586d7dd4c1c838dd3f826a99f3aadc0d44477ab3a72cf0f3494099f92cc57a) | Monitoring réseau |
| **Duniter Portal** | [Portal + RPC Mirror](https://duniter-portal.axiom-team.fr/?rpc=wss%3A%2F%2Fws.gtest.bulma.sleoconnect.fr%2F#/explorer) | Explorateur de blocs |
| **Duniter Panel** | [Network Scan](https://duniter--vue-coinduf-eu.ipns.gyroi.de/#/settings/network-scan) | Surveillance réseau |
---
## 🧪 Commandes de vérification
### Vérifier la synchronisation des nœuds
```bash
# Archive node (mirror.gtest)
docker logs -f duniter-archive-gtest | grep "Imported"
# Mirror node (ws.gtest)
docker logs -f duniter-mirror-gtest | grep "Imported"
# Smith node
docker logs -f duniter-smith-gtest | grep "Imported"
```
---
### Vérifier l'indexation Squid
```bash
# Logs du processeur (doit indexer les blocs)
docker logs -f squid-processor-gtest | grep "rate:"
# Logs du GraphQL (doit démarrer après indexation)
docker logs -f squid-graphql-gtest
```
---
### Tester les endpoints GraphQL
**Requête simple** (liste des comptes) :
```bash
curl -X POST https://squid.gtest.bulma.sleoconnect.fr/v1/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ accounts(limit: 5) { id balance { free } } }"
}'
```
**Interface GraphiQL** :
👉 [https://squid.gtest.bulma.sleoconnect.fr/graphiql](https://squid.gtest.bulma.sleoconnect.fr/graphiql)
---
### Tester la connexion RPC publique
**Via Duniter Portal** :
```
https://duniter-portal.axiom-team.fr/?rpc=wss://ws.gtest.bulma.sleoconnect.fr/#/explorer
```
**Via curl** :
```bash
curl -H "Content-Type: application/json" \
-d '{"id":1, "jsonrpc":"2.0", "method": "system_health"}' \
https://ws.gtest.bulma.sleoconnect.fr/
```
---
## ⚠️ Bug connu
**Squid v0.5.6** → Incompatibilité avec Duniter ĞTest #1100
**Solution** : Utiliser `duniter/squid:0.5.5`
---
## 🔧 Maintenance
### Redémarrer un service
```bash
docker restart duniter-archive-gtest
docker restart squid-processor-gtest
```
### Voir l'utilisation disque
```bash
du -sh /srv/dev-disk-by-uuid-*/duniter-*
du -sh /srv/dev-disk-by-uuid-*/squid-gtest/
```
### Surveiller la télémétrie en temps réel
👉 [Télémétrie ĞTest #2](https://telemetry.polkadot.io/#list/0xd4586d7dd4c1c838dd3f826a99f3aadc0d44477ab3a72cf0f3494099f92cc57a)
**Vérifier** :
- ✅ Les 3 nœuds apparaissent (Archive, Mirror, Smith)
- ✅ Le nombre de pairs connectés
- ✅ La synchronisation (même hauteur de bloc)
---
## 📊 Monitoring (à configurer plus tard)
Les nœuds exposent déjà Prometheus :
| Nœud | Port Prometheus |
|------|-----------------|
| Archive | 9619 |
| Mirror | 9617 |
| Smith | 9618 (localhost) |
Configuration Prometheus à venir...
---
## 📚 Ressources
- [Doc officielle Duniter v2](https://duniter.org/wiki/duniter-v2/)
- [Squid Indexer](https://git.duniter.org/nodes/duniter-squid)
- [Télémétrie ĞTest #2](https://telemetry.polkadot.io/#list/0xd4586d7dd4c1c838dd3f826a99f3aadc0d44477ab3a72cf0f3494099f92cc57a)
- [Duniter Portal](https://duniter-portal.axiom-team.fr/)
- [Duniter Panel](https://duniter--vue-coinduf-eu.ipns.gyroi.de/)
---
**✅ Configuration complète et fonctionnelle ĞTest #2 !** 🎉
**Chain ID** : `0xd4586d7dd4c1c838dd3f826a99f3aadc0d44477ab3a72cf0f3494099f92cc57a`