guides/serveur/kirby-ci-cd-deploy.md

1008 lines
23 KiB
Markdown
Raw Permalink Normal View History

# CI/CD pour déployer Kirby
Automatiser le déploiement de Kirby CMS avec GitLab CI ou Forgejo Actions (alternatives libres).
**🆓 Philosophie :** Ce guide privilégie les solutions **libres et open-source** :
- **Forgejo** : Alternative libre à GitHub, auto-hébergeable
- **GitLab** : Solution mature avec version Community (libre)
- Pas de dépendance aux services propriétaires
---
## 📋 Table des matières
1. [Concepts de base](#concepts-de-base)
2. [GitLab CI (SSH/rsync)](#gitlab-ci-sshrsync)
3. [Forgejo Actions (SSH/rsync)](#forgejo-actions-sshrsync)
4. [Forgejo Actions (FTP)](#forgejo-actions-ftp)
5. [Image Docker optimisée](#image-docker-optimisée-pour-kirby)
6. [Configuration des secrets](#configuration-des-secrets)
7. [Troubleshooting](#troubleshooting)
---
## Concepts de base
### Workflow typique
```
1. Push sur main/master
2. CI/CD se déclenche
3. Stage BUILD
- Installer les dépendances (Composer)
- Optimiser (autoloader, assets)
4. Stage DEPLOY
- Se connecter au VPS (SSH ou FTP)
- Synchroniser les fichiers
- Exclure les dossiers sensibles (cache, sessions, accounts)
5. ✅ Site déployé
```
### Prérequis VPS
- VPS configuré → [vps-setup-rapide.md](vps-setup-rapide.md)
- Site Kirby fonctionnel → [kirby-vps-deploy.md](kirby-vps-deploy.md)
- Clé SSH configurée (pour déploiement SSH)
---
## GitLab CI (SSH/rsync)
### Avantages
- ✅ Rapide (rsync ne transfère que les modifications)
- ✅ Sécurisé (SSH)
- ✅ Contrôle total (permissions, exclusions)
- ✅ Logs détaillés
### Configuration complète
**.gitlab-ci.yml** à la racine du projet :
```yaml
stages:
- build
- deploy
variables:
COMPOSER_ALLOW_SUPERUSER: "1"
# ===== STAGE BUILD =====
build_prod:
stage: build
only:
- main # Déclencher uniquement sur la branche main
image: composer:2 # Image officielle Composer
script:
# Installer les dépendances Kirby
- composer install --no-dev --optimize-autoloader --ignore-platform-req=ext-gd
artifacts:
# Fichiers à passer au stage deploy
paths:
- vendor/
- kirby/
- site/
- assets/
- content/
- media/
- index.php
- .htaccess
expire_in: 1 hour # Les artifacts expirent après 1h
# ===== STAGE DEPLOY =====
deploy_prod:
stage: deploy
image: alpine:latest
only:
- main
dependencies:
- build_prod # Récupère les artifacts du build
before_script:
# Installer rsync et SSH
- apk add --no-cache rsync openssh
# Configurer la clé SSH
- mkdir -p ~/.ssh
- echo -e "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
# Configuration SSH (désactiver la vérification de l'host)
- |
cat > ~/.ssh/config <<EOF
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
BatchMode yes
IdentitiesOnly yes
EOF
- chmod 600 ~/.ssh/config
script:
- echo "🚀 Déploiement sur le serveur de production..."
# Fonction rsync réutilisable
- |
rsync_deploy() {
src="$1"
dst="$2"
shift 2
cmd="rsync -az --delete --no-perms --no-owner --no-group"
for excl in "$@"; do
cmd="$cmd --exclude=$excl"
done
cmd="$cmd -e 'ssh -p ${SSH_PORT:-22} -i ~/.ssh/id_ed25519' $src $USERNAME@$HOST:$dst"
echo "$cmd"
eval $cmd
}
# Déployer les dossiers buildés
- rsync_deploy site/ "$PROD_PATH/site/" "accounts/" "cache/" "sessions/"
- rsync_deploy vendor/ "$PROD_PATH/vendor/"
- rsync_deploy kirby/ "$PROD_PATH/kirby/"
- rsync_deploy assets/ "$PROD_PATH/assets/"
- rsync_deploy content/ "$PROD_PATH/content/"
- rsync_deploy media/ "$PROD_PATH/media/"
- rsync_deploy .htaccess "$PROD_PATH/"
- rsync_deploy index.php "$PROD_PATH/"
- echo "✅ Déploiement terminé !"
```
### Variables CI/CD à configurer
**GitLab → Settings → CI/CD → Variables :**
| Variable | Valeur | Protégé | Masqué |
|----------|--------|---------|--------|
| `SSH_PRIVATE_KEY` | Contenu de `~/.ssh/id_ed25519` | ✅ | ✅ |
| `HOST` | `203.0.113.10` (IP du VPS) | ✅ | ❌ |
| `USERNAME` | `debian` | ✅ | ❌ |
| `SSH_PORT` | `22` (ou autre si modifié) | ❌ | ❌ |
| `PROD_PATH` | `/var/www/monsite.com` | ✅ | ❌ |
**Obtenir la clé SSH privée :**
```bash
cat ~/.ssh/id_ed25519
# Copiez TOUT le contenu (-----BEGIN ... -----END)
```
---
## Forgejo Actions (SSH/rsync)
### Avantages
-**Libre** : Alternative open-source à GitHub
- ✅ Auto-hébergé : Vos données restent chez vous
- ✅ Compatible : Syntaxe proche de GitHub Actions
- ✅ Rapide : rsync incrémental
### Configuration
**.forgejo/workflows/deploy.yml** :
```yaml
name: Deploy to VPS
on:
push:
branches:
- main
jobs:
deploy:
name: Build and Deploy
runs-on: docker
container:
image: php:8.2-cli # Image PHP avec Composer
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Composer
run: |
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
- name: Deploy to VPS
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
HOST: ${{ secrets.HOST }}
USERNAME: ${{ secrets.USERNAME }}
PROD_PATH: ${{ secrets.PROD_PATH }}
run: |
# Installer rsync et SSH
apt-get update -qq
apt-get install -y -qq rsync openssh-client
# Configurer SSH
mkdir -p ~/.ssh
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
cat > ~/.ssh/config <<EOF
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
BatchMode yes
IdentitiesOnly yes
EOF
chmod 600 ~/.ssh/config
# Déployer avec rsync
echo "🚀 Déploiement..."
rsync -avz --delete \
--exclude 'site/accounts/' \
--exclude 'site/cache/' \
--exclude 'site/sessions/' \
--exclude '.git' \
--exclude '.github' \
--exclude '.forgejo' \
--exclude 'node_modules' \
-e "ssh -i ~/.ssh/id_ed25519" \
./ $USERNAME@$HOST:$PROD_PATH/
echo "✅ Déploiement terminé !"
```
### Secrets à configurer
**Dans Forgejo :** Settings → Secrets → Actions
| Secret | Valeur |
|--------|--------|
| `SSH_PRIVATE_KEY` | Clé privée SSH complète |
| `HOST` | IP ou domaine du VPS |
| `USERNAME` | Utilisateur SSH |
| `PROD_PATH` | Chemin absolu sur le VPS |
**💡 Note :** Si vous utilisez GitLab, la configuration des secrets est identique (Settings → CI/CD → Variables)
---
## Forgejo Actions (FTP)
### Quand utiliser FTP ?
- ✅ Hébergement mutualisé (pas d'accès SSH)
- ✅ Hébergeur impose FTP uniquement
- ❌ Plus lent que SSH/rsync
- ❌ Moins sécurisé (sauf FTPS/SFTP)
### Configuration
**.forgejo/workflows/deploy-ftp.yml** :
```yaml
name: Deploy via FTP
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy to FTP
runs-on: docker
container:
image: forgejo-ci-php:latest # Image custom (voir ci-dessous)
steps:
- name: Checkout code
run: |
git clone --depth 1 --branch main \
https://forge.example.com/${{ github.repository }}.git .
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
- name: Deploy via FTP
env:
FTP_USERNAME: ${{ secrets.FTP_USERNAME }}
FTP_PASSWORD: ${{ secrets.FTP_PASSWORD }}
FTP_HOST: ${{ secrets.FTP_HOST }}
run: |
# Installer lftp (client FTP puissant)
apt-get update -qq && apt-get install -y -qq lftp
# Script lftp
cat > /tmp/lftp-script.txt <<SCRIPT
set ftp:ssl-allow no
open -u $FTP_USERNAME,$FTP_PASSWORD $FTP_HOST
# Synchroniser les dossiers (mirror --reverse = upload)
mirror --reverse --verbose --ignore-time --parallel=10 \
-x accounts/ -x cache/ -x sessions/ \
site site
mirror --reverse --verbose --ignore-time --parallel=10 \
kirby kirby
mirror --reverse --verbose --ignore-time --parallel=10 \
vendor vendor
mirror --reverse --verbose --ignore-time --parallel=10 \
assets assets
mirror --reverse --verbose --ignore-time --parallel=10 \
content content
# Upload des fichiers individuels
put .htaccess
put index.php
quit
SCRIPT
# Exécuter
lftp -f /tmp/lftp-script.txt
echo "✅ Déploiement FTP terminé !"
```
### Secrets FTP
| Secret | Valeur |
|--------|--------|
| `FTP_HOST` | `ftp.example.com` |
| `FTP_USERNAME` | Utilisateur FTP |
| `FTP_PASSWORD` | Mot de passe FTP |
---
## Image Docker optimisée pour Kirby
### Pourquoi créer une image custom ?
**Sans image custom :**
```
Chaque CI installe : Composer + dépendances + rsync/lftp
→ Temps : 2-5 minutes
→ Bande passante gaspillée
```
**Avec image custom :**
```
Image pré-configurée avec tout installé
→ Temps : 30 secondes - 1 minute
→ CI plus rapide et stable
```
### Créer l'image Docker
**Dockerfile** :
```dockerfile
FROM php:8.2-cli
# Métadonnées
LABEL maintainer="votre-email@example.com"
LABEL description="Image PHP optimisée pour CI Kirby CMS"
# Installation des extensions PHP nécessaires pour Kirby
RUN apt-get update && apt-get install -y \
# Extensions PHP
libzip-dev \
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
# Outils de déploiement
rsync \
openssh-client \
lftp \
git \
unzip \
# Nettoyage
&& rm -rf /var/lib/apt/lists/*
# Configurer GD (images)
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd zip
# Installer Composer
RUN curl -sS https://getcomposer.org/installer | php -- \
--install-dir=/usr/local/bin --filename=composer
# Définir Composer en mode superuser (pour CI)
ENV COMPOSER_ALLOW_SUPERUSER=1
# Optimisations Composer
RUN composer global config --no-plugins allow-plugins.composer/installers true
# Version et vérification
RUN php -v && composer --version && rsync --version
WORKDIR /workspace
CMD ["/bin/bash"]
```
### Builder et publier l'image
**Option 1 : Forgejo Container Registry** (recommandé - auto-hébergé)
```bash
# Builder l'image
docker build -t forge.example.com/votre-user/kirby-ci:latest .
# Tester localement
docker run --rm -it forge.example.com/votre-user/kirby-ci:latest bash
composer --version
rsync --version
# Login sur votre registry Forgejo
docker login forge.example.com
# Publier
docker push forge.example.com/votre-user/kirby-ci:latest
```
**Option 2 : GitLab Container Registry**
```bash
# Builder
docker build -t registry.gitlab.com/votre-user/kirby-ci:latest .
# Login GitLab
docker login registry.gitlab.com
# Publier
docker push registry.gitlab.com/votre-user/kirby-ci:latest
```
**Option 3 : Docker Hub** (public)
```bash
# Builder
docker build -t votre-user/kirby-ci:latest .
# Login Docker Hub
docker login
# Publier
docker push votre-user/kirby-ci:latest
```
### Utiliser l'image dans la CI
**GitLab CI :**
```yaml
build_prod:
stage: build
image: registry.gitlab.com/votre-user/kirby-ci:latest # Votre image custom
script:
- composer install --no-dev --optimize-autoloader
```
**Forgejo Actions :**
```yaml
jobs:
deploy:
runs-on: docker
container:
image: forge.example.com/votre-user/kirby-ci:latest
steps:
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
```
**Gain de temps :**
- Avant : ~3-5 min (install PHP + Composer + tools)
- Après : ~30s - 1 min (juste `composer install`)
---
## Configuration des secrets
### Clé SSH pour la CI
**1. Générer une clé dédiée à la CI (recommandé) :**
```bash
# Sur votre machine locale
ssh-keygen -t ed25519 -C "ci-deploy-kirby" -f ~/.ssh/ci_deploy
# Deux fichiers créés :
# ~/.ssh/ci_deploy (PRIVÉE - pour la CI)
# ~/.ssh/ci_deploy.pub (PUBLIQUE - pour le VPS)
```
**2. Ajouter la clé publique au VPS :**
```bash
# Copier la clé publique
cat ~/.ssh/ci_deploy.pub
# Sur le VPS
ssh debian@VPS
vim ~/.ssh/authorized_keys
# Collez la clé publique sur une nouvelle ligne
```
**3. Ajouter la clé privée dans les secrets CI :**
```bash
# Afficher la clé PRIVÉE
cat ~/.ssh/ci_deploy
# Copiez TOUT (-----BEGIN ... -----END)
# Puis ajoutez dans les secrets CI sous le nom SSH_PRIVATE_KEY
```
### Vérification
**Tester la clé depuis votre machine :**
```bash
ssh -i ~/.ssh/ci_deploy debian@VPS
# Doit fonctionner sans mot de passe
```
---
## Déploiement multi-environnements
### Staging + Production
**.gitlab-ci.yml** :
```yaml
stages:
- build
- deploy-staging
- deploy-production
build:
stage: build
image: votre-user/kirby-ci:latest
script:
- composer install --no-dev --optimize-autoloader
artifacts:
paths:
- vendor/
- kirby/
- site/
- assets/
- .htaccess
- index.php
# Déploiement automatique sur staging (toutes les branches)
deploy_staging:
stage: deploy-staging
image: alpine:latest
only:
- branches
except:
- main
before_script:
- apk add --no-cache rsync openssh
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
script:
- rsync -avz --delete \
--exclude 'site/accounts/' \
--exclude 'site/cache/' \
--exclude 'site/sessions/' \
-e "ssh -i ~/.ssh/id_ed25519" \
./ $STAGING_USERNAME@$STAGING_HOST:$STAGING_PATH/
# Déploiement manuel sur production (branche main uniquement)
deploy_production:
stage: deploy-production
image: alpine:latest
only:
- main
when: manual # Nécessite une action manuelle
before_script:
- apk add --no-cache rsync openssh
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
script:
- rsync -avz --delete \
--exclude 'site/accounts/' \
--exclude 'site/cache/' \
--exclude 'site/sessions/' \
-e "ssh -i ~/.ssh/id_ed25519" \
./ $PROD_USERNAME@$PROD_HOST:$PROD_PATH/
```
**Variables supplémentaires :**
| Variable | Staging | Production |
|----------|---------|------------|
| `STAGING_HOST` | `staging.example.com` | - |
| `STAGING_USERNAME` | `debian` | - |
| `STAGING_PATH` | `/var/www/staging.example.com` | - |
| `PROD_HOST` | - | `example.com` |
| `PROD_USERNAME` | - | `debian` |
| `PROD_PATH` | - | `/var/www/example.com` |
---
## Optimisations
### Cache Composer
**GitLab CI :**
```yaml
build_prod:
stage: build
image: composer:2
cache:
key: composer-cache
paths:
- vendor/
script:
- composer install --no-dev --optimize-autoloader
```
**Forgejo Actions :**
```yaml
- name: Cache Composer
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
- name: Install dependencies
run: composer install --no-dev --optimize-autoloader
```
**💡 Note :** Forgejo Actions supporte la syntaxe GitHub Actions (compatibilité)
### Déploiement incrémental (rsync optimisé)
```bash
# Ne synchroniser que les fichiers modifiés
rsync -avz --delete --checksum \
--exclude 'site/accounts/' \
--exclude 'site/cache/' \
--exclude 'site/sessions/' \
--exclude 'media/' \
-e "ssh -i ~/.ssh/id_ed25519" \
./ $USERNAME@$HOST:$PROD_PATH/
```
**Options rsync importantes :**
| Option | Description |
|--------|-------------|
| `-a` | Mode archive (préserve tout) |
| `-v` | Verbeux (affiche les fichiers) |
| `-z` | Compression pendant le transfert |
| `--delete` | Supprime les fichiers distants en trop |
| `--checksum` | Compare par checksum (plus précis) |
| `--dry-run` | Simulation (ne fait rien) |
### Rollback rapide
**Script de rollback :**
```yaml
rollback:
stage: deploy
when: manual
script:
- ssh $USERNAME@$HOST "cd $PROD_PATH && git reset --hard HEAD~1"
```
---
## Notifications
### Slack
**GitLab CI :**
```yaml
after_script:
- |
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"✅ Déploiement de $CI_PROJECT_NAME réussi !\"}" \
$SLACK_WEBHOOK_URL
```
**Variables :**
- `SLACK_WEBHOOK_URL` : URL du webhook Slack
### Discord
```yaml
after_script:
- |
curl -X POST -H 'Content-Type: application/json' \
-d "{\"content\":\"✅ **$CI_PROJECT_NAME** déployé sur production !\"}" \
$DISCORD_WEBHOOK_URL
```
---
## Troubleshooting
### Erreur "Permission denied (publickey)"
**Cause :** La clé SSH n'est pas reconnue par le VPS.
**Solutions :**
1. Vérifier que la clé publique est bien dans `~/.ssh/authorized_keys` sur le VPS
2. Vérifier les permissions :
```bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
```
3. Vérifier le format de la clé privée dans les secrets (doit inclure `-----BEGIN` et `-----END`)
### Erreur "Host key verification failed"
**Cause :** Le serveur SSH demande une confirmation.
**Solution :** Désactiver la vérification dans la config SSH :
```yaml
before_script:
- |
cat > ~/.ssh/config <<EOF
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
EOF
```
### Composer install échoue
**Erreur :** `ext-gd is missing`
**Solution 1 :** Ignorer les requirements de plateforme :
```bash
composer install --no-dev --optimize-autoloader --ignore-platform-req=ext-gd
```
**Solution 2 :** Utiliser une image avec GD pré-installé (image custom)
### rsync trop lent
**Optimisations :**
```bash
# Paralléliser avec --partial-dir
rsync -avz --delete --partial-dir=.rsync-partial \
--exclude 'media/' \
./ $USERNAME@$HOST:$PROD_PATH/
# Ou exclure les gros dossiers (uploads manuels)
rsync -avz --delete \
--exclude 'media/' \
--exclude 'assets/tiles/' \
./ $USERNAME@$HOST:$PROD_PATH/
```
### FTP trop lent
**Optimisation lftp :**
```bash
mirror --reverse --verbose --parallel=20 \
--exclude-glob cache/ \
--exclude-glob sessions/ \
site site
```
**Augmenter `--parallel` (jusqu'à 20-30 connexions simultanées)**
---
## Comparaison des méthodes
| Critère | SSH/rsync | FTP/lftp |
|---------|-----------|----------|
| **Vitesse** | ⭐⭐⭐⭐⭐ Très rapide | ⭐⭐⭐ Moyen |
| **Sécurité** | ⭐⭐⭐⭐⭐ SSH chiffré | ⭐⭐ FTP non chiffré (FTPS mieux) |
| **Fiabilité** | ⭐⭐⭐⭐⭐ Très stable | ⭐⭐⭐ Dépend du serveur FTP |
| **Compatibilité** | ⭐⭐⭐ VPS/dédié | ⭐⭐⭐⭐⭐ Tous hébergements |
| **Facilité** | ⭐⭐⭐⭐ Simple avec clés SSH | ⭐⭐⭐⭐⭐ Très simple |
| **Bande passante** | ⭐⭐⭐⭐⭐ Optimisée (delta) | ⭐⭐⭐ Retransfère tout |
**Recommandation :**
- VPS/Serveur dédié → **SSH/rsync** (meilleure option)
- Hébergement mutualisé → **FTP/lftp** (seule option souvent)
---
## Exemple complet GitLab CI (production-ready)
**.gitlab-ci.yml** :
```yaml
stages:
- build
- test
- deploy
variables:
COMPOSER_ALLOW_SUPERUSER: "1"
# ===== BUILD =====
build:
stage: build
image: votre-user/kirby-ci:latest
cache:
key: composer-$CI_COMMIT_REF_SLUG
paths:
- vendor/
script:
- composer install --no-dev --optimize-autoloader
artifacts:
paths:
- vendor/
- kirby/
- site/
- assets/
- content/
- index.php
- .htaccess
expire_in: 1 hour
# ===== TEST =====
test:
stage: test
image: votre-user/kirby-ci:latest
dependencies:
- build
script:
- echo "🧪 Vérification de la structure Kirby..."
- test -d kirby || exit 1
- test -f index.php || exit 1
- test -f .htaccess || exit 1
- echo "✅ Structure OK"
# ===== DEPLOY PRODUCTION =====
deploy_production:
stage: deploy
image: alpine:latest
only:
- main
when: manual # Déploiement manuel sur prod
dependencies:
- build
before_script:
- apk add --no-cache rsync openssh
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
- chmod 600 ~/.ssh/id_ed25519
- |
cat > ~/.ssh/config <<EOF
Host *
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
BatchMode yes
IdentitiesOnly yes
EOF
- chmod 600 ~/.ssh/config
script:
- echo "🚀 Déploiement sur $PROD_HOST..."
- |
rsync -avz --delete --checksum \
--exclude 'site/accounts/' \
--exclude 'site/cache/' \
--exclude 'site/sessions/' \
--exclude '.git' \
--exclude '.gitlab-ci.yml' \
-e "ssh -p ${SSH_PORT:-22} -i ~/.ssh/id_ed25519" \
./ $USERNAME@$PROD_HOST:$PROD_PATH/
- echo "✅ Déploiement terminé !"
after_script:
- |
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"✅ $CI_PROJECT_NAME déployé en production\"}" \
$SLACK_WEBHOOK_URL || true
```
---
## Checklist déploiement CI/CD
Avant de mettre en place la CI/CD :
- [ ] VPS configuré et accessible en SSH
- [ ] Clé SSH dédiée générée pour la CI
- [ ] Clé publique ajoutée sur le VPS (`~/.ssh/authorized_keys`)
- [ ] Connexion SSH testée depuis votre machine
- [ ] Secrets CI configurés (SSH_PRIVATE_KEY, HOST, USERNAME, PROD_PATH)
- [ ] Fichier `.gitlab-ci.yml` ou `.forgejo/workflows/deploy.yml` créé
- [ ] Test de déploiement sur branche de test
- [ ] Vérification du site après déploiement
- [ ] Notifications configurées (optionnel)
- [ ] Documentation de rollback prête
---
## Pour aller plus loin
### Docker Compose pour tests locaux
**docker-compose.yml** :
```yaml
version: '3.8'
services:
kirby:
build: .
volumes:
- ./:/workspace
working_dir: /workspace
command: php -S 0.0.0.0:8000
ports:
- "8000:8000"
```
```bash
# Tester localement
docker-compose up
# Ouvrir http://localhost:8000
```
### Tests automatisés
```yaml
test:
stage: test
image: votre-user/kirby-ci:latest
script:
- composer require --dev phpunit/phpunit
- vendor/bin/phpunit tests/
```
### Monitoring post-déploiement
```yaml
after_script:
# Vérifier que le site répond
- |
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://example.com)
if [ "$STATUS" != "200" ]; then
echo "❌ Le site ne répond pas (HTTP $STATUS)"
exit 1
fi
echo "✅ Site accessible (HTTP 200)"
```
---
## Ressources
**Docker :**
- [Docker Hub](https://hub.docker.com/) - Registry d'images
- [Dockerfile reference](https://docs.docker.com/engine/reference/builder/)
**CI/CD (solutions libres) :**
- [Forgejo Actions](https://forgejo.org/docs/latest/user/actions/) - Alternative libre auto-hébergée
- [GitLab CI](https://docs.gitlab.com/ee/ci/) - Solution mature et complète
- [Woodpecker CI](https://woodpecker-ci.org/) - CI/CD minimaliste et libre
**Déploiement :**
- [rsync manual](https://linux.die.net/man/1/rsync)
- [lftp manual](https://lftp.yar.ru/lftp-man.html)
---
**Temps de mise en place :** 1-2h pour la première configuration, puis déploiements en 2-5 minutes ! 🚀