Major changes across backend, frontend, infrastructure: - Provider system with model selection (Google, DeepL, OpenAI, Ollama, Google Cloud) - Admin panel: user management, pricing, settings - Glossary system with CSV import/export - Subscription and tier quota management - Security hardening (rate limiting, API key auth, path traversal fixes) - Docker compose for dev, prod, and IONOS deployment - Alembic migrations for new tables - Frontend: dashboard, pricing page, landing page, i18n (en/fr) - Test suite and verification scripts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.1 KiB
8.1 KiB
Guide de déploiement — Ionos VPS
Résumé de l'architecture en production
Internet
↓ HTTPS :443
[Nginx] ──→ /api/* → [Backend FastAPI :8000]
──→ /* → [Frontend Next.js :3000]
↓
[PostgreSQL :5432]
[Redis :6379]
Étape 1 — Choisir et commander le VPS Ionos
Sur ionos.fr → Cloud → VPS :
| Critère | Recommandation |
|---|---|
| Offre | VPS RAM 4 Go (ou Cloud M1) |
| RAM | 4 Go minimum (8 Go recommandé) |
| CPU | 2 vCores |
| Stockage | 80 Go SSD |
| OS | Ubuntu 22.04 LTS |
| Prix | ~8–12 €/mois |
Pourquoi Ubuntu 22.04 ? LTS jusqu'en 2027, Docker officiel disponible, apt bien documenté.
Étape 2 — Premier accès SSH et sécurisation
# Depuis votre Mac — connexion initiale (Ionos vous donne root + IP)
ssh root@VOTRE_IP_IONOS
# Créer un utilisateur non-root
adduser deploy
usermod -aG sudo docker deploy
# Copier votre clé SSH publique (depuis votre Mac dans un autre terminal)
ssh-copy-id deploy@VOTRE_IP_IONOS
# Désactiver l'auth par mot de passe SSH
nano /etc/ssh/sshd_config
# → PasswordAuthentication no
# → PermitRootLogin no
systemctl restart sshd
# Pare-feu UFW
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
Étape 3 — Installer Docker
# Se connecter en tant que deploy
ssh deploy@VOTRE_IP_IONOS
# Installer Docker (méthode officielle)
curl -fsSL https://get.docker.com | sudo bash
# Ajouter deploy au groupe docker (sans sudo)
sudo usermod -aG docker $USER
newgrp docker
# Vérifier
docker --version
docker compose version
Étape 4 — Configurer le domaine Ionos
Dans votre espace client Ionos → Domaines & SSL :
- Allez dans DNS de votre domaine
- Ajoutez un enregistrement A :
- Nom :
translate(ou@pour la racine) - Valeur :
VOTRE_IP_IONOS - TTL : 3600
- Nom :
- Attendez 5–15 minutes la propagation DNS
Testez :
# Depuis votre Mac
dig wordly.art
# → doit retourner votre IP
Étape 5 — Déployer l'application
# Sur le serveur Ionos
cd /home/deploy
# Cloner le dépôt
git clone https://github.com/VOTRE_USER/office-translator.git
cd office-translator
# Créer le fichier .env depuis le template Ionos
cp .env.ionos .env
nano .env # Remplissez TOUTES les valeurs (voir ci-dessous)
Valeurs à générer pour le .env
# Clé JWT (obligatoire)
python3 -c "import secrets; print(secrets.token_urlsafe(64))"
# Mot de passe PostgreSQL
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
# Hash mot de passe admin
python3 -c "from passlib.context import CryptContext; print(CryptContext(schemes=['bcrypt']).hash('VotreMotDePasse'))"
Étape 6 — Obtenir le certificat SSL (Let's Encrypt)
# 1. Démarrer Nginx en mode HTTP seulement d'abord
# Créer conf HTTP temporaire pour la vérification ACME
cat > docker/nginx/conf.d/app.conf << 'EOF'
server {
listen 80;
server_name wordly.art;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
proxy_pass http://frontend:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /api/ {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
# 2. Démarrer les services
docker compose -f docker-compose.ionos.yml up -d postgres redis backend frontend nginx
# 3. Obtenir le certificat
docker compose -f docker-compose.ionos.yml run --rm certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
--email votre-email@wordly.art \
--agree-tos \
--no-eff-email \
-d wordly.art
# 4. Activer la conf HTTPS complète (modifier app.conf pour ajouter SSL)
# Voir section "Configuration Nginx HTTPS" ci-dessous
Configuration Nginx HTTPS complète
cat > docker/nginx/conf.d/app.conf << 'EOF'
server {
listen 80;
server_name wordly.art;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name wordly.art;
ssl_certificate /etc/letsencrypt/live/wordly.art/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wordly.art/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
client_max_body_size 60M;
location /api/ {
proxy_pass http://backend:8000;
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 300s;
proxy_send_timeout 300s;
}
location / {
proxy_pass http://frontend:3000;
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;
}
}
EOF
# Redémarrer Nginx
docker compose -f docker-compose.ionos.yml restart nginx
Étape 7 — Migrations base de données
# Exécuter les migrations Alembic
docker compose -f docker-compose.ionos.yml exec backend alembic upgrade head
# Vérifier les tables
docker compose -f docker-compose.ionos.yml exec postgres \
psql -U translate -d translate_db -c "\dt"
Étape 8 — Vérifications finales
# Tous les services actifs ?
docker compose -f docker-compose.ionos.yml ps
# Logs backend
docker compose -f docker-compose.ionos.yml logs backend --tail=50
# Test santé API
curl https://wordly.art/health
# Test frontend
curl -I https://wordly.art
Mises à jour (déploiement continu)
# Sur le serveur Ionos
cd /home/deploy/office-translator
# Récupérer les modifications
git pull origin main
# Reconstruire et redémarrer (zéro downtime possible avec --no-deps)
docker compose -f docker-compose.ionos.yml build backend frontend
docker compose -f docker-compose.ionos.yml up -d --no-deps backend frontend
# Migrations si besoin
docker compose -f docker-compose.ionos.yml exec backend alembic upgrade head
Checklist de sécurité avant mise en ligne
JWT_SECRET_KEYgénéré aléatoirement (64+ chars)POSTGRES_PASSWORDfort et unique (32+ chars)ADMIN_PASSWORD_HASHest un vrai hash bcrypt (pas un mot de passe en clair)CORS_ORIGINSpointe sur votre domaine HTTPS uniquementDEBUG=falseetENV=production- Clés Stripe en mode live (pas test)
- Clé Google Cloud régénérée (ancienne révoquée)
- Clé OpenRouter régénérée (ancienne révoquée)
- UFW activé avec seulement 22/80/443 ouverts
- Connexion SSH par clé uniquement (mot de passe désactivé)
.envabsent du dépôt git (git statusne le montre pas)
Surveillance & Logs
# Voir les logs en temps réel
docker compose -f docker-compose.ionos.yml logs -f
# Espace disque
df -h
# RAM/CPU
docker stats
# Renouvellement SSL (automatique, mais vérification manuelle)
docker compose -f docker-compose.ionos.yml exec certbot certbot certificates
Sauvegarde PostgreSQL
# Créer un backup
docker compose -f docker-compose.ionos.yml exec postgres \
pg_dump -U translate translate_db | gzip > backup_$(date +%Y%m%d).sql.gz
# Restaurer un backup
gunzip -c backup_20260418.sql.gz | \
docker compose -f docker-compose.ionos.yml exec -T postgres \
psql -U translate translate_db
Idéalement, configurez une tâche cron pour sauvegarder automatiquement :
# Sur le serveur, en tant que deploy
crontab -e
# Ajouter :
0 3 * * * cd /home/deploy/office-translator && docker compose -f docker-compose.ionos.yml exec -T postgres pg_dump -U translate translate_db | gzip > /home/deploy/backups/db_$(date +\%Y\%m\%d).sql.gz