alpinux.presentations/deploy/installer.sh
Cédrix 9ecf1973b8 Suivre le nom réel du dépôt : alpinux.presentations
Le dépôt a été créé sur la forge sous le nom alpinux.presentations, et non
alpinux-presentations : adresses de clonage, lien de la page d'accueil et
consignes d'installation sont alignés.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M713yNBL8cssBA1Zri5QLT
2026-10-10 22:06:47 +02:00

161 lines
6.7 KiB
Bash
Executable file

#!/bin/bash
# Installe la chaîne de déploiement de presentations.alpinux.org sur owni. À lancer en
# root — relancer ne casse rien, chaque étape vérifie d'abord ce qui existe.
#
# sudo bash deploy/installer.sh
#
# Ce que ça met en place : Node.js dans /opt/presentations-alpinux/node, une clé de
# déploiement en lecture seule, un clone du dépôt, le service d'écoute du webhook sur
# 127.0.0.1:9878, le relais Apache /deploy, et le droit d'écriture de l'utilisateur du
# service sur le DocumentRoot.
#
# Le script s'arrête à l'étape 3 tant que la clé de déploiement n'est pas déclarée
# dans Gitea : la déclarer, puis relancer.
set -euo pipefail
BASE="/opt/presentations-alpinux"
REPO_DIR="$BASE/repo"
UTILISATEUR="abonnelc"
CIBLE="/var/www/clients/client1/web22/web"
VHOST="/etc/apache2/sites-available/presentations.alpinux.org.vhost"
SECRET_FICHIER="/etc/default/presentations-webhook"
JOURNAL="/var/log/presentations-deploy.log"
UNITE="/etc/systemd/system/presentations-webhook.service"
PORT="9878"
# Node.js : la version LTS, figée. Pour en changer, modifier ce numéro et relancer.
NODE_VERSION="v24.21.0"
NODE_ARCHIVE="node-$NODE_VERSION-linux-x64.tar.xz"
NODE_URL="https://nodejs.org/dist/$NODE_VERSION"
# Le dépôt est tiré par SSH, avec une clé qui ne sert qu'à lui.
CLE="/home/$UTILISATEUR/.ssh/id_ed25519_presentations_deploy"
ALIAS_SSH="gitea-presentations"
DEPOT_URL="$ALIAS_SSH:alpinux.cedrica5l/alpinux.presentations.git"
SOURCE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
[ "$(id -u)" -eq 0 ] || { echo "À lancer en root : sudo bash $0" >&2; exit 1; }
echo "==> 1/7 Node.js $NODE_VERSION dans $BASE/node"
install -d -o "$UTILISATEUR" -g "$UTILISATEUR" "$BASE"
if [ -x "$BASE/node/bin/node" ] && [ "$("$BASE/node/bin/node" --version)" = "$NODE_VERSION" ]; then
echo " (déjà là)"
else
tmp="$(mktemp -d)"
curl -fsSL -o "$tmp/$NODE_ARCHIVE" "$NODE_URL/$NODE_ARCHIVE"
curl -fsSL -o "$tmp/SHASUMS256.txt" "$NODE_URL/SHASUMS256.txt"
(cd "$tmp" && grep " $NODE_ARCHIVE\$" SHASUMS256.txt | sha256sum -c -)
rm -rf "$BASE/node"
install -d "$BASE/node"
tar -xJf "$tmp/$NODE_ARCHIVE" -C "$BASE/node" --strip-components=1 --no-same-owner
rm -rf "$tmp"
echo " $("$BASE/node/bin/node" --version) installé"
fi
echo "==> 2/7 Clé de déploiement"
if [ ! -f "$CLE" ]; then
sudo -u "$UTILISATEUR" ssh-keygen -q -t ed25519 -N "" -C "deploy@presentations.alpinux.org" -f "$CLE"
echo " clé créée"
fi
CONFIG_SSH="/home/$UTILISATEUR/.ssh/config"
if ! grep -q "^Host $ALIAS_SSH\$" "$CONFIG_SSH" 2>/dev/null; then
sudo -u "$UTILISATEUR" tee -a "$CONFIG_SSH" > /dev/null <<EOF
Host $ALIAS_SSH
HostName alpinux.org
Port 3022
User git
IdentityFile $CLE
IdentitiesOnly yes
EOF
chmod 600 "$CONFIG_SSH"
echo " alias SSH « $ALIAS_SSH » ajouté"
fi
echo "==> 3/7 Dépôt dans $REPO_DIR"
if [ -d "$REPO_DIR/.git" ]; then
sudo -u "$UTILISATEUR" git -C "$REPO_DIR" pull --ff-only origin main
elif ! sudo -u "$UTILISATEUR" git clone "$DEPOT_URL" "$REPO_DIR"; then
echo
echo "Le serveur n'a pas pu cloner le dépôt. Déclarer cette clé publique dans Gitea :" >&2
echo " dépôt alpinux.presentations → Paramètres → Clés de déploiement → Ajouter" >&2
echo " (sans cocher l'accès en écriture)" >&2
echo
cat "$CLE.pub"
echo
echo "Puis relancer : sudo bash $0" >&2
exit 1
fi
echo "==> 4/7 Scripts et journal"
# Le serveur exécute ces copies, pas les fichiers du dépôt : une modification de
# deploy/ ou de scripts/deploy-presentations.sh ne prend effet qu'en relançant
# installer.sh. Un push ne peut donc pas changer ce que le service exécute.
install -o "$UTILISATEUR" -g "$UTILISATEUR" -m 755 "$SOURCE/scripts/deploy-presentations.sh" "$BASE/deploy-presentations.sh"
install -o "$UTILISATEUR" -g "$UTILISATEUR" -m 755 "$SOURCE/deploy/webhook.py" "$BASE/webhook.py"
touch "$JOURNAL" && chown "$UTILISATEUR":"$UTILISATEUR" "$JOURNAL"
echo "==> 5/7 Droit d'écriture sur $CIBLE"
# Le DocumentRoot appartient à web22 ; une ACL suffit à y laisser écrire le service,
# sans toucher au propriétaire ni aux droits qu'attend ISPConfig.
setfacl -m "u:$UTILISATEUR:rwx" "$CIBLE"
echo "==> 6/7 Secret du webhook et service systemd"
if [ -f "$SECRET_FICHIER" ]; then
echo " (secret déjà là, inchangé)"
else
(umask 077; printf 'PRESENTATIONS_WEBHOOK_SECRET=%s\n' "$(openssl rand -hex 24)" > "$SECRET_FICHIER")
fi
chmod 600 "$SECRET_FICHIER"
install -m 644 "$SOURCE/deploy/presentations-webhook.service" "$UNITE"
systemctl daemon-reload
systemctl enable --now presentations-webhook
systemctl restart presentations-webhook
systemctl is-active --quiet presentations-webhook && echo " service actif"
echo "==> 7/7 Relais Apache /deploy"
if grep -q "127.0.0.1:$PORT" "$VHOST"; then
echo " déjà relayé"
else
cp -a "$VHOST" "$VHOST.bak-$(date +%Y%m%d%H%M)"
awk -v port="$PORT" '
{ print }
!fait && /^[[:space:]]*<VirtualHost[^>]*:443>/ {
print "\t\tProxyPass /deploy http://127.0.0.1:" port "/deploy"
print "\t\tProxyPassReverse /deploy http://127.0.0.1:" port "/deploy"
fait = 1
}
' "$VHOST" > "$VHOST.tmp"
# Recopié dans le fichier plutôt que déplacé par-dessus : un « mv » remplacerait
# l'original par un fichier neuf, avec d'autres droits.
cat "$VHOST.tmp" > "$VHOST" && rm -f "$VHOST.tmp"
grep -q "127.0.0.1:$PORT" "$VHOST" || { echo " ÉCHEC : relais non posé dans $VHOST" >&2; exit 1; }
echo " relais ajouté"
fi
if apache2ctl configtest; then
systemctl reload apache2
else
echo "Configuration Apache invalide : rien n'a été rechargé." >&2
echo "La sauvegarde .bak-* est à côté du vhost." >&2
exit 1
fi
echo
echo "────────────────────────────────────────────────────────────"
echo "Reste à faire à la main :"
echo
echo "1. Déclarer le webhook dans Gitea"
echo " dépôt alpinux.presentations → Paramètres → Webhooks → Ajouter → Gitea"
echo " URL : https://presentations.alpinux.org/deploy"
echo " Méthode : POST, type de contenu : application/json"
echo " Secret : sudo cat $SECRET_FICHIER"
echo " Événement : Push seulement, filtre de branche : main"
echo
echo "2. Recopier le relais dans ISPConfig pour qu'il survive à une régénération"
echo " du vhost : Sites → presentations.alpinux.org → Options → Directives Apache"
echo " (les deux lignes de deploy/apache-vhost.exemple.conf)"
echo
echo "Première mise en ligne, sans attendre un push :"
echo " sudo -u $UTILISATEUR $BASE/deploy-presentations.sh; tail -5 $JOURNAL"
echo "────────────────────────────────────────────────────────────"