Files
FEDIVERSE-OKI/DEPLOY.adoc
T

12 KiB
Raw Blame History

🚀 DEPLOY — Mise en production et CI/CD

Ce document dĂ©crit la mise en production complĂšte d'ANNU KUTE CED sur un serveur fraĂźchement installĂ©, puis l’activation du dĂ©ploiement continu via Gitea Actions.

Il est complĂ©mentaire au README (installation manuelle, configuration de l’application).

🧭 Vue d’ensemble

L’architecture retenue (identique à celle de pawol.nu) :

┌─────────────┐   push main    ┌──────────────────┐   SSH (git pull)   ┌─────────────┐
│  DĂ©pĂŽt git  │ ─────────────▶│  Gitea Actions   │ ─────────────────▶│  Serveur    │
│  (LaBola)   │                │  check → deploy  │                    │  production │
└─────────────┘                └──────────────────┘                    └─────────────┘
  1. VĂ©rification (check-pr.yml + job check de deploy-prod.yml) : lint PHP/JS, validation AsciiDoc, JSON, XML, shellcheck. Les mĂȘmes vĂ©rifications sont exĂ©cutables en local avec scripts/check.sh.

  2. Déploiement (deploy-prod.yml) : le runner se connecte en SSH au serveur, qui tient un clone du dépÎt, fait git pull --ff-only, puis bumpe la version des caches du Service Worker (sw.js) pour déclencher le modal de mise à jour PWA chez les visiteurs.

Pourquoi un git pull sur le serveur plutĂŽt qu’un rsync : tous les fichiers propres Ă  l’instance (config.local.php, .htaccess, sitemap.xml, robots.txt, site.webmanifest, mentions-legales.php, dons.php, uploads/, cache/) sont ignorĂ©s par Git — un pull ne les Ă©crase jamais. Le dĂ©ploiement est ainsi sans risque pour la configuration de production.

📋 PrĂ©requis

  • Un serveur Debian 12 ou Ubuntu 24.04 fraĂźchement installĂ©, avec accĂšs root (ou sudo)

  • Un nom de domaine dont le DNS pointe vers le serveur (enregistrement A/AAAA)

  • Le dĂ©pĂŽt Gitea : git@labola.o-k-i.net:cedric/annu-kute-ced.git

  • Un runner Gitea Actions opĂ©rationnel sur l’instance LaBola (dĂ©jĂ  le cas pour pawol.nu)

Note
Sur un hĂ©bergement mutualisĂ© (pas d’accĂšs root), adaptez : les fichiers sont dĂ©ployĂ©s dans le docroot fourni par l’hĂ©bergeur, et la clĂ© SSH s’ajoute via le panneau de contrĂŽle (o2switch : ClĂ©s SSH dans cPanel).

1ïžâƒŁ Installation des paquets

# Nginx + PHP-FPM (choix recommandé ; Apache possible, voir §5 option B)
apt update && apt upgrade -y
apt install -y nginx php-fpm \
    php-curl php-intl php-mbstring php-xml \
    git curl unzip

# Vérifier les extensions requises
php -m | grep -E 'curl|intl|mbstring|SimpleXML|json'

2ïžâƒŁ Utilisateur de dĂ©ploiement

Le runner CI se connectera en SSH avec cet utilisateur. Ne pas utiliser root.

adduser --disabled-password --gecos "Deploy annu-kute-ced" deploy
usermod -aG www-data deploy

# Répertoire de l'application
mkdir -p /var/www/annu-kute-ced
chown -R deploy:www-data /var/www/annu-kute-ced

3ïžâƒŁ Clone du dĂ©pĂŽt

Le serveur de production tient un clone du dépÎt. Le runner y exécutera git pull à chaque déploiement.

# Clé SSH du serveur pour lire le dépÎt (deploy key Gitea, lecture seule)
sudo -u deploy ssh-keygen -t ed25519 -f /home/deploy/.ssh/id_ed25519 -N ""
cat /home/deploy/.ssh/id_ed25519.pub
  1. Sur LaBola : Settings du dĂ©pĂŽt → Deploy Keys → Add deploy key (coller la clĂ© publique, lecture seule suffit).

  2. Puis :

    sudo -u deploy git clone git@labola.o-k-i.net:cedric/annu-kute-ced.git /var/www/annu-kute-ced
    cd /var/www/annu-kute-ced
    sudo -u deploy git config pull.ff only   # sécurité : refuser tout pull non fast-forward

4ïžâƒŁ Fichiers d’instance

Ces fichiers sont ignorés par Git : ils vivent uniquement sur le serveur et ne seront jamais écrasés par les déploiements.

cd /var/www/annu-kute-ced
sudo -u deploy cp includes/config.local.php.sample includes/config.local.php
sudo -u deploy cp site.webmanifest.sample site.webmanifest
sudo -u deploy cp robots.txt.sample robots.txt
sudo -u deploy cp sitemap.xml.sample sitemap.xml
sudo -u deploy cp mentions-legales.php.sample mentions-legales.php
# Uniquement si vous utilisez Apache (option B de l'étape 5) :
# sudo -u deploy cp conf/.htaccess.sample .htaccess
# Facultatif (page de dons) :
# sudo -u deploy cp dons.php.sample dons.php

Éditer ensuite les fichiers copiĂ©s :

  • includes/config.local.php : APP_HOST_NAME, sources (PeerTube/Castopod/Mastodon), CACHE_ENABLED=true (recommandĂ© pour Castopod), etc. — voir la rĂ©fĂ©rence de configuration

  • sitemap.xml, robots.txt, site.webmanifest : remplacer example.com par le domaine rĂ©el

  • mentions-legales.php : remplacer le placeholder VOTRE-DATE-MAJ

# Le cache de l'API doit ĂȘtre accessible en Ă©criture par PHP
mkdir -p /var/www/annu-kute-ced/cache
chown -R www-data:www-data /var/www/annu-kute-ced/cache

5ïžâƒŁ VirtualHost

Option A — Nginx + PHP-FPM (recommandĂ©e, configuration fournie)

Le fichier conf/nginx.conf.sample est l’équivalent Nginx complet du .htaccess : mĂȘmes protections (fichiers de configuration, rĂ©pertoires sensibles, dotfiles, pas de listing), masquage de l’extension .php, HTTPS forcĂ©, no-cache pour sw.js et site.webmanifest, plus le cache des assets et gzip.

# Adapter conf/nginx.conf.sample :
#   - server_name  : votre domaine
#   - root         : /var/www/annu-kute-ced
#   - fastcgi_pass : socket de votre version PHP (ex. /var/run/php/php8.3-fpm.sock)
#   - ssl_certificate(_key) : chemins de vos certificats (étape 6)
cp conf/nginx.conf.sample /etc/nginx/sites-available/annu-kute-ced
ln -s /etc/nginx/sites-available/annu-kute-ced /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

Option B — Apache

apt install -y apache2 php libapache2-mod-php
a2enmod rewrite headers
cat > /etc/apache2/sites-available/annu-kute-ced.conf <<'EOF'
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/annu-kute-ced

    <Directory /var/www/annu-kute-ced>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
EOF
a2ensite annu-kute-ced
systemctl reload apache2

Le .htaccess copiĂ© Ă  l’étape 4 applique les rĂšgles de sĂ©curitĂ©, le HTTPS forcĂ© (actif aprĂšs l’étape 6) et le no-cache de sw.js.

6ïžâƒŁ HTTPS (obligatoire pour la PWA)

MĂ©thode recommandĂ©e par l’EFF : Certbot via snap (instructions officielles). PrĂ©requis : le domaine pointe vers le serveur et le site rĂ©pond dĂ©jĂ  en HTTP sur le port 80 (Ă©tape 5 terminĂ©e).

# 1. Installer snapd (Ubuntu : déjà présent. Debian : apt + support classic)
apt install -y snapd
snap install core && snap refresh core

# 2. Retirer tout certbot installé via apt (évite les conflits de commande)
apt-get remove -y certbot || true

# 3. Installer Certbot et préparer la commande
snap install --classic certbot
ln -s /snap/bin/certbot /usr/local/bin/certbot

# 4. Obtenir le certificat ET laisser Certbot configurer Nginx automatiquement
certbot --nginx -d example.com -d www.example.com
# Variante prudente (ne fait qu'émettre le certificat, vhost édité à la main) :
# certbot certonly --nginx -d example.com -d www.example.com

# 5. Vérifier le renouvellement automatique (timer systemd/cron inclus avec le snap)
certbot renew --dry-run
Note
Pour Apache (option B), la mĂ©thode snap est identique, avec certbot --apache Ă  l’étape 4.

Ouvrez ensuite https://example.com dans un navigateur : le cadenas doit apparaütre dans la barre d’URL.

7ïžâƒŁ VĂ©rification du site

curl -I https://example.com
# Attendu : HTTP/2 200, en-tĂȘtes de sĂ©curitĂ© (CSP, X-Frame-Options
)
curl -I https://example.com/sw.js
# Attendu : Cache-Control: no-cache

Ouvrir le site dans un navigateur : vidĂ©os, podcasts, timeline et le bouton d’installation PWA doivent fonctionner.

8ïžâƒŁ ClĂ© SSH du CI

C’est la clĂ© utilisĂ©e par le runner Gitea Actions pour dĂ©ployer. Elle est diffĂ©rente de la deploy key de lecture (Ă©tape 3) : celle-ci doit pouvoir Ă©crire dans le clone.

# Générer la paire SUR VOTRE POSTE (pas sur le serveur)
ssh-keygen -t ed25519 -f annu-kute-ced-deploy -C "ci-gitea-annu-kute-ced"

# Autoriser la clé publique pour l'utilisateur deploy
sudo -u deploy tee -a /home/deploy/.ssh/authorized_keys < annu-kute-ced-deploy.pub

La clĂ© privĂ©e (annu-kute-ced-deploy, sans passphrase) ira dans les secrets Gitea Ă  l’étape suivante. Conservez-la en lieu sĂ»r et ne la commitez jamais.

9ïžâƒŁ Secrets Gitea

Dans LaBola : Settings du dĂ©pĂŽt → Actions → Secrets, crĂ©er :

Secret Valeur

SSH_HOST

Adresse du serveur (IP ou FQDN), port 22 par défaut (sinon host:port)

SSH_USER

deploy

SSH_KEY

Contenu intĂ©gral de la clĂ© privĂ©e gĂ©nĂ©rĂ©e Ă  l’étape 8

PROD_DEPLOY_PATH

/var/www/annu-kute-ced

Warning
SSH_KEY donne un accÚs shell au serveur avec les droits de deploy. Ne jamais la coller ailleurs que dans les secrets Gitea, et révoquer la clé publique (authorized_keys) en cas de doute.

🔟 Test du pipeline

  1. Pousser un commit sur main (par exemple une correction de coquille dans le README).

  2. Dans LaBola, onglet Actions : le workflow Déploiement PROD doit exécuter check puis deploy au vert.

  3. CÎté serveur :

    cd /var/www/annu-kute-ced
    git log -1 --oneline        # doit correspondre au commit poussé
    grep STATIC_CACHE_NAME sw.js # le suffixe de version a été bumpé à l'heure du déploiement
  4. CĂŽtĂ© visiteur : au prochain chargement de page, le modal « Nouvelle version disponible » apparaĂźt (Service Worker dĂ©jĂ  installĂ© lors d’une visite prĂ©cĂ©dente).

🔄 Fonctionnement courant

ÉvĂ©nement RĂ©sultat

Pull request vers main

Workflow VĂ©rification PR : lints et validations bloquants en cas d’erreur

Push sur main

Workflow DĂ©ploiement PROD : mĂȘmes vĂ©rifications, puis SSH → git pull --ff-only → bump de la version des caches sw.js → modal de mise Ă  jour chez les visiteurs

En local, avant de pousser

scripts/check.sh exĂ©cute les mĂȘmes vĂ©rifications que le CI

Le bump de version dans sw.js est fait sur le serveur uniquement : le dĂ©pĂŽt garde sa valeur de rĂ©fĂ©rence, le working tree du serveur est nettoyĂ© (git checkout — sw.js) avant chaque pull pour garantir le fast-forward.

🧰 DĂ©pannage

SymptĂŽme Piste

git pull --ff-only échoue sur le serveur

Une modification locale existe : git status dans le docroot, puis git checkout — <fichier> (le workflow le fait dĂ©jĂ  pour sw.js)

L’action ne se dĂ©clenche pas

VĂ©rifier que le runner act est en ligne (LaBola → Site Administration → Actions → Runners) et que Actions est activĂ© pour le dĂ©pĂŽt (Settings → Units)

Permission denied (publickey) dans le job deploy

Clé publique absente de /home/deploy/.ssh/authorized_keys, ou mauvais SSH_USER/SSH_HOST

Les visiteurs ne reçoivent pas la mise à jour

VĂ©rifier curl -I https://example.com/sw.js → Cache-Control: no-cache requis (rĂšgles fournies dans conf/)

Erreurs 500 sur les vidéos/podcasts

cache/ non accessible en écriture : chown -R www-data:www-data cache/

php-intl manquant

apt install php-intl puis systemctl restart php*-fpm (Nginx) ou systemctl restart apache2 (Apache)

🔒 Notes de sĂ©curitĂ©

  • La clĂ© privĂ©e du CI est dĂ©diĂ©e Ă  ce dĂ©pĂŽt : une clĂ© compromise ne donne accĂšs qu’au compte deploy, sans sudo.

  • La deploy key Gitea (Ă©tape 3) est en lecture seule.

  • Pour restreindre davantage la clĂ© du CI, on peut limiter les commandes dans authorized_keys (command="
​", no-pty) — facultatif, hors scope de ce guide.

  • Les fichiers sensibles (includes/, .htaccess, config.local.php) sont bloquĂ©s en accĂšs web par les configurations fournies dans conf/.

📞 Support

En cas de blocage : kontak@o-k-i.net