docs: rewrite deployment guide with Stripe and API keys management
Complete rewrite of DEPLOYMENT_HOMELAB.md covering: - IONOS DNS setup (with @ record workaround) - NPM proxy host config with exact nginx custom config - Docker server setup with setup-env.sh wizard - All 7 translation providers (Google, DeepL, OpenAI, DeepSeek, Minimax, OpenRouter, Ollama) - Full Stripe integration guide (account, products, webhooks, test cards, live mode) - NAS backup setup - Prometheus + Grafana monitoring - Gitea Actions CI/CD runner setup - Complete checklist Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Guide de Deploiement - Wordly.art (Homelab)
|
# Guide de Deploiement - Wordly.art (Homelab)
|
||||||
> Nginx Proxy Manager + IONOS DNS + Docker + NAS Backup + Monitoring
|
> NPM + IONOS + Docker + Stripe + API Keys + NAS Backup + Monitoring
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -8,398 +8,353 @@
|
|||||||
```
|
```
|
||||||
Internet
|
Internet
|
||||||
|
|
|
|
||||||
| DNS IONOS: wordly.art -> ton IP fixe
|
| DNS IONOS: wordly.art -> IP fixe
|
||||||
|
|
|
|
||||||
[Routeur/Box] (port forwarding 80+443 -> machine NPM)
|
[Routeur/Box] (port forwarding 80+443 -> machine NPM)
|
||||||
|
|
|
|
||||||
+-- Machine 1: Nginx Proxy Manager (NPM)
|
+-- Machine 1: Nginx Proxy Manager (NPM)
|
||||||
| - SSL Let's Encrypt automatique
|
| - SSL Let's Encrypt auto
|
||||||
| - Reverse proxy vers les services
|
| - Reverse proxy
|
||||||
|
|
|
|
||||||
+-- Machine 2 ou 3: Docker (Wordly app)
|
+-- Machine 2/3: Docker (192.168.1.151)
|
||||||
|
|
|
|
||||||
+-- wordly-backend (FastAPI :8000)
|
+-- wordly-backend (FastAPI :8000)
|
||||||
+-- wordly-frontend (Next.js :3000)
|
+-- wordly-frontend (Next.js :3000)
|
||||||
+-- wordly-postgres (PostgreSQL :5432)
|
+-- wordly-postgres (PostgreSQL :5432)
|
||||||
+-- wordly-redis (Redis :6379)
|
+-- wordly-redis (Redis :6379)
|
||||||
+-- wordly-prometheus (interne :9090)
|
+-- wordly-prometheus (:9090 interne)
|
||||||
+-- wordly-grafana (:3001)
|
+-- wordly-grafana (:3001)
|
||||||
+-- wordly-node-exporter
|
+-- wordly-node-exporter + cadvisor
|
||||||
+-- wordly-cadvisor
|
|
||||||
|
|
|
|
||||||
+-- Backup quotidien -> NAS (SMB/NFS)
|
+-- Backup quotidien -> NAS
|
||||||
```
|
```
|
||||||
|
|
||||||
### Routing NPM
|
|
||||||
|
|
||||||
| Sous-domaine | Cible Docker | Port |
|
|
||||||
|--------------|-------------|------|
|
|
||||||
| `wordly.art` | `wordly-frontend` | 3000 |
|
|
||||||
| `wordly.art/api/*` | `wordly-backend` | 8000 |
|
|
||||||
| `wordly.art/translate` | `wordly-backend` | 8000 |
|
|
||||||
| `monitoring.wordly.art` | `wordly-grafana` | 3000 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 1 : Configuration DNS chez IONOS
|
## Etape 1 : DNS IONOS
|
||||||
|
|
||||||
### 1.1 Connexion a IONOS
|
1. Se connecter sur **ionos.fr** > **Domaines & SSL** > **wordly.art** > **DNS**
|
||||||
1. Se connecter sur **ionos.fr** / **ionos.com**
|
2. Modifier les enregistrements **A** existants :
|
||||||
2. Aller dans **Domaines & SSL**
|
|
||||||
3. Cliquer sur **wordly.art**
|
|
||||||
|
|
||||||
### 1.2 Creer les enregistrements DNS
|
| Type | Nom (hote) | Valeur | Attention |
|
||||||
|
|------|-----------|--------|-----------|
|
||||||
|
| **A** | *(vide ou @)* | Ton IP fixe | Pas dans "Sous-domaines", dans DNS principal |
|
||||||
|
| **A** | `www` | Ton IP fixe | Dans Sous-domaines, taper juste `www` |
|
||||||
|
| **A** | `monitoring` | Ton IP fixe | Dans Sous-domaines, taper juste `monitoring` |
|
||||||
|
|
||||||
Cliquer sur **DNS** > **Gerer les enregistrements** et ajouter :
|
> Ton IP fixe : ouvre https://api.ipify.org depuis ton reseau
|
||||||
|
|
||||||
| Type | Nom | Valeur | TTL |
|
Ne **pas** toucher aux lignes Mail (MX, SPF, DKIM, autodiscover).
|
||||||
|------|-----|--------|-----|
|
|
||||||
| **A** | `@` | `TON_IP_FIXE` | 3600 |
|
|
||||||
| **A** | `www` | `TON_IP_FIXE` | 3600 |
|
|
||||||
| **A** | `monitoring` | `TON_IP_FIXE` | 3600 |
|
|
||||||
|
|
||||||
> Remplace `TON_IP_FIXE` par ton IP fixe publique.
|
Verifier apres 10 min :
|
||||||
> Pour la trouver : https://whatismyip.com
|
|
||||||
|
|
||||||
### 1.3 Verifier la propagation DNS
|
|
||||||
```bash
|
```bash
|
||||||
# Attendre 5-30 minutes puis verifier
|
|
||||||
nslookup wordly.art
|
nslookup wordly.art
|
||||||
nslookup monitoring.wordly.art
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 2 : Nginx Proxy Manager (NPM)
|
## Etape 2 : Port forwarding + NPM
|
||||||
|
|
||||||
### 2.1 Verifier que NPM tourne
|
### 2.1 Routeur : ouvrir les ports
|
||||||
NPM est deja installe sur une de tes machines. Verifier :
|
|
||||||
|
|
||||||
```bash
|
Sur ton routeur/box (souvent `192.168.1.1`) :
|
||||||
# Sur la machine qui heberge NPM
|
|
||||||
docker ps | grep npm
|
|
||||||
# ou
|
|
||||||
docker ps | grep nginx-proxy-manager
|
|
||||||
```
|
|
||||||
|
|
||||||
L'interface admin NPM est accessible sur **http://IP_NPM:81**
|
| Port externe | Port interne | IP destination |
|
||||||
|
|-------------|-------------|---------------|
|
||||||
|
| **80** | 80 | IP de la machine NPM |
|
||||||
|
| **443** | 443 | IP de la machine NPM |
|
||||||
|
|
||||||
### 2.2 Connecter NPM au reseau Docker de Wordly
|
### 2.2 NPM : creer les Proxy Hosts
|
||||||
|
|
||||||
Pour que NPM puisse atteindre les containers Wordly par leur nom, il doit etre sur le meme reseau Docker.
|
Interface NPM : **http://IP_NPM:81**
|
||||||
|
|
||||||
```bash
|
#### Proxy Host 1 : wordly.art
|
||||||
# Sur la machine qui heberge NPM, trouver le nom du container NPM
|
|
||||||
docker ps | grep -i npm
|
|
||||||
|
|
||||||
# Trouver le reseau du container NPM
|
**Details :**
|
||||||
docker inspect <NPM_CONTAINER> | grep -A5 Networks
|
- Domain Names : `wordly.art`
|
||||||
|
- Scheme : `http`
|
||||||
|
- Forward Hostname/IP : `192.168.1.151` (IP du serveur Wordly)
|
||||||
|
- Forward Port : `3000`
|
||||||
|
- Cocher Block Common Exploits + Websockets
|
||||||
|
|
||||||
# Sur la machine Wordly, on va connecter NPM au reseau wordly-network
|
**SSL :**
|
||||||
# (uniquement si NPM et Wordly sont sur la MEME machine Docker)
|
- Request a new SSL Certificate
|
||||||
docker network connect wordly-network <NPM_CONTAINER>
|
- Cocher Force SSL + HTTP/2 + HSTS
|
||||||
```
|
- Email : `admin@wordly.art`
|
||||||
|
|
||||||
**Si NPM et Wordly sont sur des machines differentes** (recommande avec 3 machines) :
|
**Advanced** - coller cette config nginx :
|
||||||
- Pas besoin de reseau Docker partage
|
|
||||||
- NPM utilisera l'IP de la machine Wordly au lieu du nom de container
|
|
||||||
- Voir section 2.4 pour la configuration
|
|
||||||
|
|
||||||
### 2.3 Creer les Proxy Hosts dans NPM
|
|
||||||
|
|
||||||
Se connecter a **http://IP_NPM:81** puis :
|
|
||||||
|
|
||||||
#### Proxy Host 1 : wordly.art (Frontend + Backend)
|
|
||||||
|
|
||||||
Aller dans **Proxy Hosts** > **Add Proxy Host** :
|
|
||||||
|
|
||||||
**Onglet Details :**
|
|
||||||
- **Domain Names** : `wordly.art`
|
|
||||||
- **Scheme** : `http`
|
|
||||||
- **Forward Hostname/IP** : `wordly-frontend` *(si meme machine)* OU `IP_MACHINE_WORDLY` *(si machines differentes)*
|
|
||||||
- **Forward Port** : `3000`
|
|
||||||
- Cocher **Block Common Exploits**
|
|
||||||
- Cocher **Websockets Support**
|
|
||||||
|
|
||||||
**Onglet SSL :**
|
|
||||||
- **SSL Certificate** : `Request a new SSL Certificate`
|
|
||||||
- Cocher **Force SSL**
|
|
||||||
- Cocher **HTTP/2 Support**
|
|
||||||
- Cocher **HSTS Enabled**
|
|
||||||
- **Email** : `admin@wordly.art`
|
|
||||||
- Cocher **I Agree to the...**
|
|
||||||
|
|
||||||
Cliquer **Save**. NPM va automatiquement obtenir le certificat Let's Encrypt.
|
|
||||||
|
|
||||||
#### Proxy Host 2 : www.wordly.art -> redirect
|
|
||||||
|
|
||||||
**Onglet Details :**
|
|
||||||
- **Domain Names** : `www.wordly.art`
|
|
||||||
- **Scheme** : `http`
|
|
||||||
- **Forward Hostname/IP** : `wordly-frontend`
|
|
||||||
- **Forward Port** : `3000`
|
|
||||||
|
|
||||||
**Onglet SSL :**
|
|
||||||
- Meme certificat que wordly.art (selectionner le certificat deja cree)
|
|
||||||
|
|
||||||
**Onglet Advanced :**
|
|
||||||
Ajouter dans le champ Custom Nginx Configuration :
|
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
# Rediriger toutes les requetes API et translate vers le backend
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://wordly-backend:8000;
|
proxy_pass http://192.168.1.151:8000;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header Connection "";
|
proxy_set_header Connection "";
|
||||||
|
|
||||||
proxy_connect_timeout 60s;
|
proxy_connect_timeout 60s;
|
||||||
proxy_send_timeout 300s;
|
proxy_send_timeout 300s;
|
||||||
proxy_read_timeout 300s;
|
proxy_read_timeout 300s;
|
||||||
proxy_buffer_size 128k;
|
proxy_buffer_size 128k;
|
||||||
proxy_buffers 4 256k;
|
proxy_buffers 4 256k;
|
||||||
proxy_busy_buffers_size 256k;
|
proxy_busy_buffers_size 256k;
|
||||||
|
|
||||||
add_header Access-Control-Allow-Origin https://wordly.art always;
|
add_header Access-Control-Allow-Origin https://wordly.art always;
|
||||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||||
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With, X-API-Key" always;
|
add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With, X-API-Key" always;
|
||||||
add_header Access-Control-Allow-Credentials "true" always;
|
add_header Access-Control-Allow-Credentials "true" always;
|
||||||
|
if ($request_method = 'OPTIONS') { return 204; }
|
||||||
if ($request_method = 'OPTIONS') {
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
location /translate {
|
location /translate {
|
||||||
proxy_pass http://wordly-backend:8000;
|
proxy_pass http://192.168.1.151:8000;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
proxy_connect_timeout 60s;
|
proxy_connect_timeout 60s;
|
||||||
proxy_send_timeout 600s;
|
proxy_send_timeout 600s;
|
||||||
proxy_read_timeout 600s;
|
proxy_read_timeout 600s;
|
||||||
|
|
||||||
client_max_body_size 100M;
|
client_max_body_size 100M;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /health {
|
location /health {
|
||||||
proxy_pass http://wordly-backend:8000;
|
proxy_pass http://192.168.1.151:8000;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Connection "";
|
proxy_set_header Connection "";
|
||||||
}
|
}
|
||||||
|
|
||||||
location /docs {
|
location /docs { proxy_pass http://192.168.1.151:8000; proxy_set_header Host $host; }
|
||||||
proxy_pass http://wordly-backend:8000;
|
location /redoc { proxy_pass http://192.168.1.151:8000; proxy_set_header Host $host; }
|
||||||
proxy_set_header Host $host;
|
location /openapi.json { proxy_pass http://192.168.1.151:8000; proxy_set_header Host $host; }
|
||||||
}
|
location /admin { proxy_pass http://192.168.1.151:3000; 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; }
|
||||||
|
location /_next/static/ { proxy_pass http://192.168.1.151:3000; add_header Cache-Control "public, max-age=31536000, immutable"; }
|
||||||
location /redoc {
|
|
||||||
proxy_pass http://wordly-backend:8000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /openapi.json {
|
|
||||||
proxy_pass http://wordly-backend:8000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /admin {
|
|
||||||
proxy_pass http://wordly-frontend:3000;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /_next/static/ {
|
|
||||||
proxy_pass http://wordly-frontend:3000;
|
|
||||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
> **IMPORTANT** : Si NPM et Wordly sont sur des machines differentes, remplacer
|
> Si NPM et Wordly sont sur la meme machine Docker, remplace `192.168.1.151:8000` par `wordly-backend:8000` etc.
|
||||||
> `wordly-backend:8000` par `IP_MACHINE_WORDLY:8000` et
|
|
||||||
> `wordly-frontend:3000` par `IP_MACHINE_WORDLY:3000`
|
|
||||||
|
|
||||||
#### Proxy Host 3 : monitoring.wordly.art (Grafana)
|
#### Proxy Host 2 : www.wordly.art
|
||||||
|
|
||||||
**Onglet Details :**
|
Meme config, meme certificat SSL. Dans Advanced, ajoute :
|
||||||
- **Domain Names** : `monitoring.wordly.art`
|
```nginx
|
||||||
- **Scheme** : `http`
|
return 301 https://wordly.art$request_uri;
|
||||||
- **Forward Hostname/IP** : `wordly-grafana` *(si meme machine)* OU `IP_MACHINE_WORDLY` *(si machines differentes)*
|
```
|
||||||
- **Forward Port** : `3000`
|
|
||||||
- Cocher **Block Common Exploits**
|
|
||||||
|
|
||||||
**Onglet SSL :**
|
#### Proxy Host 3 : monitoring.wordly.art
|
||||||
- **SSL Certificate** : `Request a new SSL Certificate`
|
|
||||||
- Cocher **Force SSL**
|
|
||||||
- Cocher **HSTS Enabled**
|
|
||||||
- **Email** : `admin@wordly.art`
|
|
||||||
|
|
||||||
### 2.4 Cas : NPM et Wordly sur machines differentes
|
- Forward : `192.168.1.151:3001`
|
||||||
|
- SSL Let's Encrypt
|
||||||
Si NPM tourne sur Machine A et Wordly sur Machine B :
|
|
||||||
|
|
||||||
1. **Ouvrir les ports** sur la Machine B pour que NPM puisse atteindre les services :
|
|
||||||
```bash
|
|
||||||
# Sur Machine B, ouvrir dans le pare-feu local
|
|
||||||
sudo ufw allow from IP_MACHINE_A to any port 3000 # Frontend
|
|
||||||
sudo ufw allow from IP_MACHINE_A to any port 8000 # Backend
|
|
||||||
sudo ufw allow from IP_MACHINE_A to any port 3001 # Grafana
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Exposer les ports** dans docker-compose.yml en ajoutant la section `ports` :
|
|
||||||
```yaml
|
|
||||||
backend:
|
|
||||||
# ... config existante ...
|
|
||||||
ports:
|
|
||||||
- "IP_MACHINE_B:8000:8000" # Bind sur IP locale seulement
|
|
||||||
|
|
||||||
frontend:
|
|
||||||
# ... config existante ...
|
|
||||||
ports:
|
|
||||||
- "IP_MACHINE_B:3000:3000"
|
|
||||||
|
|
||||||
grafana:
|
|
||||||
# ... config existante ...
|
|
||||||
ports:
|
|
||||||
- "IP_MACHINE_B:3000:3000"
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Dans NPM, utiliser `IP_MACHINE_B` comme Forward Hostname
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 3 : Deploiement de l'application
|
## Etape 3 : Serveur Docker (192.168.1.151)
|
||||||
|
|
||||||
### 3.1 Preparer le serveur
|
### 3.1 Installer Docker
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Installer Docker (si pas deja fait)
|
|
||||||
curl -fsSL https://get.docker.com | sh
|
curl -fsSL https://get.docker.com | sh
|
||||||
sudo usermod -aG docker $USER
|
sudo usermod -aG docker $USER
|
||||||
newgrp docker
|
newgrp docker
|
||||||
|
|
||||||
# Verifier
|
|
||||||
docker --version
|
|
||||||
docker compose version
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.2 Transferer le code
|
### 3.2 Cloner le projet
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Cloner le repo
|
git clone -b production-deployment https://gitea.parsanet.org/sepehr/office_translator.git /opt/wordly
|
||||||
git clone <ton-repo-git> /opt/wordly
|
|
||||||
cd /opt/wordly
|
cd /opt/wordly
|
||||||
git checkout production-deployment
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.3 Configurer les secrets
|
### 3.3 Configurer le .env avec le wizard
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/wordly
|
bash scripts/setup-env.sh
|
||||||
|
```
|
||||||
|
|
||||||
# Copier le fichier env
|
Le wizard demande le domaine, le mot de passe admin, le service de traduction, et genere tous les secrets automatiquement.
|
||||||
|
|
||||||
|
Ou configurer manuellement :
|
||||||
|
```bash
|
||||||
cp .env.production .env
|
cp .env.production .env
|
||||||
|
|
||||||
# Generer le hash bcrypt du mot de passe admin
|
|
||||||
docker run --rm python:3.12-slim bash -c "
|
|
||||||
pip install 'passlib[bcrypt]' bcrypt > /dev/null 2>&1 &&
|
|
||||||
python -c \"from passlib.context import CryptContext; print(CryptContext(schemes=['bcrypt']).hash('TON_MOT_DE_PASSE_ADMIN'))\"
|
|
||||||
"
|
|
||||||
```
|
|
||||||
|
|
||||||
Copier le hash affiche et le coller dans `.env` pour `ADMIN_PASSWORD_HASH`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Editer le fichier .env et verifier tous les champs
|
|
||||||
nano .env
|
nano .env
|
||||||
```
|
```
|
||||||
|
|
||||||
Verifications cles dans `.env` :
|
|
||||||
- `DOMAIN=wordly.art`
|
|
||||||
- `NEXT_PUBLIC_API_URL=https://wordly.art`
|
|
||||||
- `JWT_SECRET_KEY=` (deja rempli)
|
|
||||||
- `ADMIN_TOKEN_SECRET=` (deja rempli)
|
|
||||||
- `ADMIN_PASSWORD_HASH=` (coller le hash genere)
|
|
||||||
- `CORS_ORIGINS=https://wordly.art`
|
|
||||||
- `POSTGRES_PASSWORD=` (deja rempli)
|
|
||||||
|
|
||||||
### 3.4 Lancer l'application
|
### 3.4 Lancer l'application
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build et demarrage
|
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
|
docker compose ps # Verifier que tout est "Up (healthy)"
|
||||||
# Suivre les logs pendant le premier demarrage
|
|
||||||
docker compose logs -f
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.5 Verifier
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Sur le serveur, tester directement
|
|
||||||
curl http://localhost:8000/health
|
curl http://localhost:8000/health
|
||||||
|
|
||||||
# Verifier tous les containers
|
|
||||||
docker compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
Resultat attendu :
|
|
||||||
```
|
|
||||||
NAME STATUS PORTS
|
|
||||||
wordly-postgres Up (healthy)
|
|
||||||
wordly-redis Up (healthy)
|
|
||||||
wordly-backend Up (healthy)
|
|
||||||
wordly-frontend Up (healthy)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 4 : Verification complete
|
## Etape 4 : Cles API - Services de traduction
|
||||||
|
|
||||||
### 4.1 Tester depuis l'exterieur
|
L'application supporte **7 providers de traduction**. Tu n'es pas oblige de tous les configurer - commence avec 1 ou 2.
|
||||||
|
|
||||||
|
### Gerer les cles
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Depuis un autre ordinateur ou telephone
|
cd /opt/wordly
|
||||||
curl -I https://wordly.art
|
bash scripts/manage-keys.sh
|
||||||
|
|
||||||
# Doit retourner:
|
|
||||||
# HTTP/2 200
|
|
||||||
# server: nginx
|
|
||||||
# strict-transport-security: ...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 Tester dans le navigateur
|
Menu interactif pour ajouter/modifier/supprimer des cles API.
|
||||||
|
|
||||||
1. Ouvrir **https://wordly.art** -> doit afficher le frontend
|
### Ou trouver les cles
|
||||||
2. Ouvrir **https://wordly.art/health** -> doit retourner `{"status": "ok"}`
|
|
||||||
3. Ouvrir **https://wordly.art/admin** -> doit afficher le login admin
|
|
||||||
4. Ouvrir **https://monitoring.wordly.art** -> doit afficher Grafana
|
|
||||||
|
|
||||||
### 4.3 Tester le SSL
|
| Provider | URL d'inscription | Cle a recuperer | Cout |
|
||||||
|
|----------|-------------------|-----------------|------|
|
||||||
|
| **Google** | Aucune inscription | Aucune cle (gratuit via deep_translator) | Gratuit |
|
||||||
|
| **DeepL** | https://www.deepl.com/pro-api | Clé API DeepL (format: `xxx-xxx-...`) | Gratuit 500k car/mois, puis 5.49EUR/mois |
|
||||||
|
| **OpenAI** | https://platform.openai.com/api-keys | `sk-...` | ~0.15$/1000 traductions |
|
||||||
|
| **DeepSeek** | https://platform.deepseek.com/api_keys | `sk-...` | ~0.14$/M tokens (tres bon rapport Q/P) |
|
||||||
|
| **Minimax** | https://platform.minimaxi.com/ | Cle API | Variable |
|
||||||
|
| **OpenRouter** | https://openrouter.ai/keys | `sk-or-...` | Multi-modeles, pay-per-use |
|
||||||
|
|
||||||
Le cadenas vert doit etre present sur wordly.art. NPM a automatiquement obtenu le certificat Let's Encrypt.
|
### Activer un provider dans le .env
|
||||||
|
|
||||||
|
Exemple pour DeepSeek :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Dans le .env
|
||||||
|
DEEPSEEK_ENABLED=true
|
||||||
|
DEEPSEEK_API_KEY=sk-votre-cle-ici
|
||||||
|
DEEPSEEK_MODEL=deepseek-chat
|
||||||
|
DEEPSEEK_BASE_URL=https://api.deepseek.com/v1
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis `docker compose restart backend`.
|
||||||
|
|
||||||
|
### Recommandation pour demarrer
|
||||||
|
|
||||||
|
1. **Google** (active par defaut, gratuit, aucune cle)
|
||||||
|
2. **DeepSeek** (ajouter quand tu veux meilleure qualite, tres peu cher)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 5 : Backup automatique vers NAS
|
## Etape 5 : Stripe - Systeme de paiement
|
||||||
|
|
||||||
### 5.1 Monter le NAS
|
Stripe gere les abonnements (Starter, Pro, Business). Si tu ne configures pas Stripe, l'app fonctionne en mode gratuit sans limitation d'abonnement.
|
||||||
|
|
||||||
|
### 5.1 Creer un compte Stripe
|
||||||
|
|
||||||
|
1. Aller sur **https://dashboard.stripe.com/register**
|
||||||
|
2. Creer un compte avec ton email
|
||||||
|
3. Activer le compte (verifie identite + banque pour recevoir les paiements)
|
||||||
|
|
||||||
|
### 5.2 Recuperer les cles Stripe
|
||||||
|
|
||||||
|
Dans le dashboard Stripe : **Developers** > **API keys**
|
||||||
|
|
||||||
|
| Cle | Nom dans .env | Description |
|
||||||
|
|-----|---------------|-------------|
|
||||||
|
| `sk_test_...` ou `sk_live_...` | `STRIPE_SECRET_KEY` | Cle secrete (attention: NE PAS utiliser la cle publique `pk_...`) |
|
||||||
|
| `whsec_...` | `STRIPE_WEBHOOK_SECRET` | Cle du webhook (voir section 5.4) |
|
||||||
|
|
||||||
|
> **Test vs Live** : commence en mode test (`sk_test_...`), passe en live quand tout fonctionne.
|
||||||
|
|
||||||
|
### 5.3 Creer les produits et forfaits
|
||||||
|
|
||||||
|
Dans Stripe : **Products** > **Add product**
|
||||||
|
|
||||||
|
Cree 3 produits :
|
||||||
|
|
||||||
|
**Produit 1 : Starter**
|
||||||
|
- Name : `Starter`
|
||||||
|
- Price : `9.00 EUR` / Monthly (recurring)
|
||||||
|
- Une fois cree, clique sur le prix et copie le **Price ID** (`price_...`)
|
||||||
|
|
||||||
|
**Produit 2 : Pro**
|
||||||
|
- Name : `Pro`
|
||||||
|
- Price : `19.00 EUR` / Monthly
|
||||||
|
|
||||||
|
**Produit 3 : Business**
|
||||||
|
- Name : `Business`
|
||||||
|
- Price : `49.00 EUR` / Monthly
|
||||||
|
|
||||||
|
Copie les 3 Price IDs.
|
||||||
|
|
||||||
|
### 5.4 Configurer le Webhook Stripe
|
||||||
|
|
||||||
|
Le webhook permet a Stripe de notifier ton app quand un paiement reussit, un abonnement est annule, etc.
|
||||||
|
|
||||||
|
Dans Stripe : **Developers** > **Webhooks** > **Add endpoint**
|
||||||
|
|
||||||
|
- **Endpoint URL** : `https://wordly.art/api/v1/stripe/webhook`
|
||||||
|
- **Events a ecouter** (cliquer "Select events") :
|
||||||
|
- `checkout.session.completed`
|
||||||
|
- `customer.subscription.updated`
|
||||||
|
- `customer.subscription.deleted`
|
||||||
|
- `invoice.payment_succeeded`
|
||||||
|
- `invoice.payment_failed`
|
||||||
|
|
||||||
|
Une fois le webhook cree, clique dessus et copie le **Signing secret** (`whsec_...`).
|
||||||
|
|
||||||
|
### 5.5 Ajouter les cles Stripe dans le .env
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/wordly
|
||||||
|
bash scripts/manage-keys.sh
|
||||||
|
# Choisir option 4 (Stripe)
|
||||||
|
```
|
||||||
|
|
||||||
|
Ou manuellement dans `.env` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
STRIPE_SECRET_KEY=sk_live_votre_cle_secrete
|
||||||
|
STRIPE_WEBHOOK_SECRET=whsec_votre_signing_secret
|
||||||
|
STRIPE_STARTER_PRICE_ID=price_votre_price_id_starter
|
||||||
|
STRIPE_PRO_PRICE_ID=price_votre_price_id_pro
|
||||||
|
STRIPE_BUSINESS_PRICE_ID=price_votre_price_id_business
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis `docker compose restart backend`.
|
||||||
|
|
||||||
|
### 5.6 Tester Stripe en mode test
|
||||||
|
|
||||||
|
1. Utilise `sk_test_...` comme STRIPE_SECRET_KEY
|
||||||
|
2. Cree des produits en mode test (meme process)
|
||||||
|
3. Pour tester un paiement, Stripe fournit des cartes test :
|
||||||
|
- **Succes** : `4242 4242 4242 4242`
|
||||||
|
- **Echec** : `4000 0000 0000 0002`
|
||||||
|
- Exp : n'importe quelle date future
|
||||||
|
- CVC : n'importe quel nombre
|
||||||
|
4. Verifie dans Stripe Dashboard > Payments que les paiements apparaissent
|
||||||
|
|
||||||
|
### 5.7 Passer en production
|
||||||
|
|
||||||
|
Quand tout fonctionne en test :
|
||||||
|
|
||||||
|
1. Dans Stripe Dashboard, clique **"Activate your account"** en haut a gauche
|
||||||
|
2. Remplie les infos business (identite, banque)
|
||||||
|
3. Change dans le .env : `sk_test_...` -> `sk_live_...`
|
||||||
|
4. Refais les webhooks et produits en mode live
|
||||||
|
5. `docker compose restart backend`
|
||||||
|
|
||||||
|
### 5.8 Checklist Stripe
|
||||||
|
|
||||||
|
- [ ] Compte Stripe cree et verifie
|
||||||
|
- [ ] 3 produits crees (Starter 9EUR, Pro 19EUR, Business 49EUR)
|
||||||
|
- [ ] 3 Price IDs copies
|
||||||
|
- [ ] STRIPE_SECRET_KEY configure
|
||||||
|
- [ ] Webhook configure avec les 5 events
|
||||||
|
- [ ] STRIPE_WEBHOOK_SECRET configure
|
||||||
|
- [ ] 3 STRIPE_*_PRICE_ID configures
|
||||||
|
- [ ] Backend redemarre
|
||||||
|
- [ ] Test avec carte 4242 reussi
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Etape 6 : Backup automatique vers NAS
|
||||||
|
|
||||||
|
### 6.1 Monter le NAS
|
||||||
|
|
||||||
#### Option A : SMB/CIFS (Synology / QNAP)
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt install cifs-utils
|
sudo apt install cifs-utils
|
||||||
sudo mkdir -p /mnt/nas-backups/wordly
|
sudo mkdir -p /mnt/nas-backups/wordly
|
||||||
|
|
||||||
# Fichier credentials
|
|
||||||
sudo tee /etc/nas-credentials <<EOF
|
sudo tee /etc/nas-credentials <<EOF
|
||||||
username=wordly-backup
|
username=wordly-backup
|
||||||
password=MOT_DE_PASSE_NAS
|
password=MOT_DE_PASSE_NAS
|
||||||
@@ -407,159 +362,169 @@ domain=WORKGROUP
|
|||||||
EOF
|
EOF
|
||||||
sudo chmod 600 /etc/nas-credentials
|
sudo chmod 600 /etc/nas-credentials
|
||||||
|
|
||||||
# Montage auto au demarrage
|
|
||||||
echo "//IP_DU_NAS/wordly-backups /mnt/nas-backups/wordly cifs credentials=/etc/nas-credentials,uid=$(id -u),gid=$(id -g),iocharset=utf8,vers=3.0,noperm 0 0" | sudo tee -a /etc/fstab
|
echo "//IP_DU_NAS/wordly-backups /mnt/nas-backups/wordly cifs credentials=/etc/nas-credentials,uid=$(id -u),gid=$(id -g),iocharset=utf8,vers=3.0,noperm 0 0" | sudo tee -a /etc/fstab
|
||||||
|
|
||||||
sudo mount /mnt/nas-backups/wordly
|
sudo mount /mnt/nas-backups/wordly
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Option B : NFS
|
### 6.2 Tester et programmer
|
||||||
```bash
|
|
||||||
sudo apt install nfs-common
|
|
||||||
sudo mkdir -p /mnt/nas-backups/wordly
|
|
||||||
echo "IP_DU_NAS:/volume1/wordly-backups /mnt/nas-backups/wordly nfs rw,hard,intr 0 0" | sudo tee -a /etc/fstab
|
|
||||||
sudo mount /mnt/nas-backups/wordly
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5.2 Tester le backup
|
|
||||||
```bash
|
```bash
|
||||||
chmod +x /opt/wordly/scripts/backup-to-nas.sh
|
cd /opt/wordly
|
||||||
/opt/wordly/scripts/backup-to-nas.sh --full
|
bash scripts/backup-to-nas.sh --full
|
||||||
|
|
||||||
# Verifier
|
|
||||||
ls -lh /mnt/nas-backups/wordly/daily/
|
ls -lh /mnt/nas-backups/wordly/daily/
|
||||||
```
|
|
||||||
|
|
||||||
### 5.3 Programmer le cron
|
# Programmer le cron quotidien a 3h
|
||||||
```bash
|
|
||||||
crontab -e
|
crontab -e
|
||||||
|
# Ajouter :
|
||||||
# Backup quotidien a 3h du matin
|
|
||||||
0 3 * * * /opt/wordly/scripts/backup-to-nas.sh >> /var/log/wordly-backup.log 2>&1
|
0 3 * * * /opt/wordly/scripts/backup-to-nas.sh >> /var/log/wordly-backup.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 6 : Monitoring (Prometheus + Grafana)
|
## Etape 7 : Monitoring (Prometheus + Grafana)
|
||||||
|
|
||||||
|
### 7.1 Lancer
|
||||||
|
|
||||||
### 6.1 Lancer le stack monitoring
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/wordly
|
cd /opt/wordly
|
||||||
|
|
||||||
# Creer le reseau externe si necessaire
|
|
||||||
docker network create wordly-network 2>/dev/null || true
|
|
||||||
|
|
||||||
# Lancer application + monitoring
|
|
||||||
docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d
|
docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 Acceder a Grafana
|
### 7.2 Acceder
|
||||||
|
|
||||||
- **URL** : `https://monitoring.wordly.art` (via NPM)
|
- **URL** : `https://monitoring.wordly.art`
|
||||||
- **Login** : `admin`
|
- **Login** : `admin` / mot de passe defini dans le .env
|
||||||
- **Mot de passe** : `WordlyGrafana2026!`
|
|
||||||
- Changer le mot de passe a la premiere connexion
|
|
||||||
|
|
||||||
### 6.3 Dashboards pre-configures
|
### 7.3 Dashboards
|
||||||
|
|
||||||
| Dashboard | Contenu |
|
| Dashboard | Contenu |
|
||||||
|-----------|---------|
|
|-----------|---------|
|
||||||
| **Wordly - Application** | Traductions, latence, providers, taux d'erreur |
|
| Wordly - Application | Traductions, latence, providers, taux d'erreur |
|
||||||
| **Wordly - Infrastructure** | CPU, RAM, disque, reseau, status containers |
|
| Wordly - Infrastructure | CPU, RAM, disque, reseau, status containers |
|
||||||
|
|
||||||
Ils apparaissent automatiquement dans le dossier **Wordly** de Grafana.
|
Alertes pre-configures : backend down, erreur > 10%, RAM > 90%, disque < 15%.
|
||||||
|
|
||||||
### 6.4 Configurer les alertes (optionnel)
|
|
||||||
|
|
||||||
Dans Grafana : **Alerting** > **Contact points** > **Add contact point** :
|
|
||||||
- Type : **Email** ou **Discord webhook**
|
|
||||||
- Ajouter ton email ou l'URL du webhook
|
|
||||||
|
|
||||||
Les regles d'alerte suivantes sont pre-configures :
|
|
||||||
- Backend down
|
|
||||||
- Taux d'erreur > 10%
|
|
||||||
- RAM > 90%
|
|
||||||
- Disque < 15%
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Etape 7 : Operations courantes
|
## Etape 8 : Gitea Actions - Deploiement automatique
|
||||||
|
|
||||||
|
### 8.1 Installer le runner sur 192.168.1.151
|
||||||
|
|
||||||
### Logs
|
|
||||||
```bash
|
```bash
|
||||||
docker compose logs -f --tail=100 # Tous les services
|
mkdir -p /opt/gitea-runner && cd /opt/gitea-runner
|
||||||
docker compose logs -f backend # Backend seul
|
wget https://gitea.com/gitea/act_runner/releases/latest/download/act_runner-linux-amd64
|
||||||
docker compose logs -f frontend # Frontend seul
|
chmod +x act_runner-linux-amd64 && mv act_runner-linux-amd64 act_runner
|
||||||
docker compose logs -f postgres # Base de donnees
|
./act_runner generate-config > config.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
### Redemarrer
|
### 8.2 Enregistrer le runner
|
||||||
|
|
||||||
|
1. Gitea > office_translator > Settings > Actions > Runners > Create new Runner
|
||||||
|
2. Copier le token
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose restart backend
|
cd /opt/gitea-runner
|
||||||
docker compose restart frontend
|
./act_runner register \
|
||||||
|
--instance https://gitea.parsanet.org \
|
||||||
|
--token LE_TOKEN \
|
||||||
|
--name homelab-runner \
|
||||||
|
--labels self-hosted
|
||||||
```
|
```
|
||||||
|
|
||||||
### Mettre a jour
|
### 8.3 Service systemd
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt/wordly
|
sudo tee /etc/systemd/system/gitea-runner.service <<EOF
|
||||||
git pull origin production-deployment
|
[Unit]
|
||||||
docker compose up -d --build
|
Description=Gitea Act Runner
|
||||||
|
After=docker.service
|
||||||
|
Requires=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
WorkingDirectory=/opt/gitea-runner
|
||||||
|
ExecStart=/opt/gitea-runner/act_runner daemon --config config.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now gitea-runner
|
||||||
|
sudo systemctl status gitea-runner
|
||||||
```
|
```
|
||||||
|
|
||||||
### Restaurer un backup
|
Desormais, chaque `git push` sur `production-deployment` deploye automatiquement.
|
||||||
```bash
|
|
||||||
/opt/wordly/scripts/backup-to-nas.sh --restore
|
|
||||||
# Liste les backups disponibles
|
|
||||||
|
|
||||||
/opt/wordly/scripts/backup-to-nas.sh --restore wordly_db_20260510_030000.sql.gz
|
|
||||||
```
|
|
||||||
|
|
||||||
### Verifier l'espace
|
|
||||||
```bash
|
|
||||||
df -h # Disque systeme
|
|
||||||
docker system df # Espace Docker
|
|
||||||
```
|
|
||||||
|
|
||||||
### Renouveler le SSL
|
|
||||||
NPM renouvelle les certificats Let's Encrypt automatiquement. Pas d'action requise.
|
|
||||||
Verifier dans NPM > SSL Certificates que le statut est OK.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Checklist de deploiement
|
## Etape 9 : Operations courantes
|
||||||
|
|
||||||
|
| Action | Commande |
|
||||||
|
|--------|----------|
|
||||||
|
| Voir les logs | `docker compose logs -f --tail=100` |
|
||||||
|
| Redemarrer backend | `docker compose restart backend` |
|
||||||
|
| Mettre a jour | `cd /opt/wordly && git pull && docker compose up -d --build` |
|
||||||
|
| Restaurer backup | `bash scripts/backup-to-nas.sh --restore` |
|
||||||
|
| Gerer les cles API | `bash scripts/manage-keys.sh` |
|
||||||
|
| Changer mot de passe admin | `bash scripts/manage-keys.sh` > option 5 |
|
||||||
|
| Espace disque | `df -h && docker system df` |
|
||||||
|
| SSL | NPM gere le renouvellement auto |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist complete
|
||||||
|
|
||||||
### DNS IONOS
|
### DNS IONOS
|
||||||
- [ ] Enregistrement A : `@` -> IP fixe
|
- [ ] A record `@` -> IP fixe
|
||||||
- [ ] Enregistrement A : `www` -> IP fixe
|
- [ ] A record `www` -> IP fixe
|
||||||
- [ ] Enregistrement A : `monitoring` -> IP fixe
|
- [ ] A record `monitoring` -> IP fixe
|
||||||
- [ ] Propagation DNS verifiee (nslookup)
|
- [ ] Propagation verifiee
|
||||||
|
|
||||||
### Nginx Proxy Manager
|
### Routeur + NPM
|
||||||
- [ ] Proxy Host cree pour `wordly.art` -> frontend:3000
|
- [ ] Ports 80+443 ouverts vers machine NPM
|
||||||
- [ ] SSL Let's Encrypt obtenu pour `wordly.art`
|
- [ ] Proxy Host wordly.art avec custom config
|
||||||
- [ ] Custom config nginx ajoutee (routing API/backend)
|
- [ ] SSL Let's Encrypt obtenu
|
||||||
- [ ] Proxy Host cree pour `monitoring.wordly.art` -> grafana:3000
|
- [ ] Proxy Host monitoring.wordly.art
|
||||||
- [ ] SSL Let's Encrypt obtenu pour `monitoring.wordly.art`
|
|
||||||
|
|
||||||
### Serveur Docker
|
### Serveur Docker
|
||||||
- [ ] Docker installe
|
- [ ] Docker installe
|
||||||
- [ ] Code clone dans /opt/wordly
|
- [ ] Code clone dans /opt/wordly
|
||||||
- [ ] Fichier .env rempli avec tous les secrets
|
- [ ] `bash scripts/setup-env.sh` executed
|
||||||
- [ ] Hash bcrypt genere et colle
|
|
||||||
- [ ] `docker compose up -d --build` reussi
|
- [ ] `docker compose up -d --build` reussi
|
||||||
- [ ] Tous les containers healthy
|
- [ ] Tous les containers healthy
|
||||||
|
|
||||||
### NAS
|
### Cles API (minimum 1 provider)
|
||||||
- [ ] Partage de backup cree sur le NAS
|
- [ ] Provider de traduction configure et teste
|
||||||
|
- [ ] `bash scripts/manage-keys.sh` pour verifier
|
||||||
|
|
||||||
|
### Stripe (optionnel)
|
||||||
|
- [ ] Compte Stripe cree et active
|
||||||
|
- [ ] 3 produits + Price IDs crees
|
||||||
|
- [ ] Webhook configure (5 events)
|
||||||
|
- [ ] Cles Stripe dans le .env
|
||||||
|
- [ ] Test avec carte 4242 reussi
|
||||||
|
|
||||||
|
### Backup NAS
|
||||||
- [ ] NAS monte sur /mnt/nas-backups/wordly
|
- [ ] NAS monte sur /mnt/nas-backups/wordly
|
||||||
- [ ] Backup manuel test OK
|
- [ ] Backup manuel OK
|
||||||
- [ ] Cron programme a 3h
|
- [ ] Cron programme a 3h
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
- [ ] `docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d`
|
||||||
|
- [ ] Grafana accessible sur monitoring.wordly.art
|
||||||
|
|
||||||
|
### CI/CD
|
||||||
|
- [ ] Gitea runner installe et enregistre
|
||||||
|
- [ ] Service systemd active
|
||||||
|
|
||||||
### Verification finale
|
### Verification finale
|
||||||
- [ ] https://wordly.art accessible depuis Internet
|
- [ ] https://wordly.art accessible depuis Internet
|
||||||
- [ ] HTTPS OK (cadenas vert)
|
- [ ] HTTPS OK (cadenas vert)
|
||||||
- [ ] Upload fichier OK
|
- [ ] Inscription utilisateur OK
|
||||||
- [ ] Traduction test OK
|
- [ ] Upload + traduction OK
|
||||||
- [ ] https://monitoring.wordly.art accessible
|
- [ ] Page admin /admin OK
|
||||||
- [ ] Dashboards Grafana affichent des donnees
|
- [ ] Monitoring OK
|
||||||
- [ ] Page admin accessible (/admin)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user