Files
FEDIVERSE-OKI/DEPLOY.adoc
T

11 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

# Apache + PHP (choix retenu pour ce guide ; Nginx possible, voir §5)
apt update && apt upgrade -y
apt install -y apache2 php libapache2-mod-php \
    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 conf/.htaccess.sample .htaccess
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
# 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 — Apache (recommandĂ©e, .htaccess fourni)

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.

Option B — Nginx + PHP-FPM

apt install -y nginx php-fpm
# Adapter conf/nginx.conf.sample : server_name, root, socket php-fpm,
# chemins des certificats. ⚠ Le bloc "location ~* \.(php|inc|...)$ { deny all; }"
# de l'exemple correspond Ă  TOUS les .php : le restreindre Ă  ^/includes/.
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

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

apt install -y certbot python3-certbot-apache   # ou python3-certbot-nginx
certbot --apache -d example.com -d www.example.com
# ou : certbot --nginx -d example.com -d www.example.com

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 && systemctl restart apache2

🔒 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