feat(seo): index de sitemaps acheteurs/titulaires, canonical, robots

- robots.txt déclare désormais le sitemap
- /sitemap.xml devient un index de sous-sitemaps paginés (limite 50k URLs/fichier)
  générés depuis DuckDB et mis en cache 24h : pages statiques, acheteurs, titulaires
- balise canonical auto-référente (JS, car index_string Dash partagé)
- config nginx de référence : 301 decp.info → colibre.fr (chemin préservé)
- tests SEO via test client Flask

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Colin Maudry
2026-06-30 23:06:46 +02:00
parent 9e8ad6c74b
commit 7184b7768a
4 changed files with 281 additions and 18 deletions
+85
View File
@@ -0,0 +1,85 @@
# Configuration nginx de référence pour colibre.fr + migration decp.info.
#
# Installation (sur le serveur, en root) :
# cp deploy/nginx-colibre.conf /etc/nginx/sites-available/colibre
# ln -s /etc/nginx/sites-available/colibre /etc/nginx/sites-enabled/colibre
# nginx -t && systemctl reload nginx
#
# Les certificats TLS sont gérés par certbot (Let's Encrypt) :
# certbot --nginx -d colibre.fr -d www.colibre.fr -d decp.info -d www.decp.info
# Obtenir/installer les certificats AVANT d'activer les redirections 301 :
# une 301 vers un https cassé est mise en cache par les navigateurs/Google.
# ---------------------------------------------------------------------------
# 1. Migration decp.info → colibre.fr (301 permanentes, chemin préservé)
# La structure d'URL est identique entre les deux domaines (rebranding),
# donc $request_uri suffit : /acheteurs/123 → https://colibre.fr/acheteurs/123.
# On NE redirige PAS vers la home : chaque ancienne URL garde son équivalent,
# ce qui transfère l'autorité SEO page par page.
# ---------------------------------------------------------------------------
server {
listen 80;
listen [::]:80;
server_name decp.info www.decp.info;
# Laisser certbot répondre aux challenges ACME avant la redirection.
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location / { return 301 https://colibre.fr$request_uri; }
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name decp.info www.decp.info;
ssl_certificate /etc/letsencrypt/live/colibre.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/colibre.fr/privkey.pem;
return 301 https://colibre.fr$request_uri;
}
# ---------------------------------------------------------------------------
# 2. www.colibre.fr → colibre.fr (canonicalisation : un seul hôte indexé)
# ---------------------------------------------------------------------------
server {
listen 80;
listen [::]:80;
server_name colibre.fr www.colibre.fr;
location /.well-known/acme-challenge/ { root /var/www/certbot; }
location / { return 301 https://colibre.fr$request_uri; }
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.colibre.fr;
ssl_certificate /etc/letsencrypt/live/colibre.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/colibre.fr/privkey.pem;
return 301 https://colibre.fr$request_uri;
}
# ---------------------------------------------------------------------------
# 3. Hôte canonique : https://colibre.fr → application Dash (gunicorn)
# ---------------------------------------------------------------------------
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name colibre.fr;
ssl_certificate /etc/letsencrypt/live/colibre.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/colibre.fr/privkey.pem;
# Le sitemap acheteurs/titulaires peut être volumineux : autoriser de
# gros corps de réponse en proxy et des timeouts généreux.
proxy_read_timeout 120s;
location / {
# gunicorn app:server — adapter le bind à l'unit systemd colibre.
proxy_pass http://127.0.0.1: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;
}
}