L'installateur cherchait la ligne Include des options SSL de Let's Encrypt pour savoir où poser le ProxyPass. Elle n'existe que dans les vhosts écrits par certbot : celui qu'ISPConfig génère porte ses propres directives SSLCertificate*, et le patch échouait sur sites-available. L'ancrage devient l'ouverture du bloc *:443, que les deux ont. Deux autres choses au passage : un vhost récalcitrant n'interrompt plus le script avant le rechargement d'Apache — il est signalé à la fin — et le fichier est réécrit en place plutôt que remplacé par un `mv`, qui lui aurait donné des droits neufs et lui aurait retiré son ACL. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CTvii1CYBLjD14uvuD7Kos
117 lines
5 KiB
Bash
Executable file
117 lines
5 KiB
Bash
Executable file
#!/bin/bash
|
|
# Installe la chaîne de déploiement de www.alpinux.org sur owni. À lancer en root,
|
|
# une seule fois — relancer ne casse rien, chaque étape vérifie d'abord ce qui existe.
|
|
#
|
|
# sudo bash /chemin/vers/alpinux-www/deploiement/installer.sh
|
|
#
|
|
# Ce que ça met en place : un clone du dépôt dans /opt/www-alpinux, le service d'écoute
|
|
# du webhook sur 127.0.0.1:9877, le relais Apache /deploy, et le droit d'écriture de
|
|
# l'utilisateur du service sur le DocumentRoot.
|
|
set -euo pipefail
|
|
|
|
DEPOT_URL="https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-www.git"
|
|
BASE="/opt/www-alpinux"
|
|
REPO_DIR="$BASE/repo"
|
|
UTILISATEUR="abonnelc"
|
|
CIBLE="/var/www/clients/client1/web11/web"
|
|
SECRET_FICHIER="/etc/default/www-webhook"
|
|
JOURNAL="/var/log/www-deploy.log"
|
|
UNITE="/etc/systemd/system/www-webhook.service"
|
|
|
|
[ "$(id -u)" -eq 0 ] || { echo "À lancer en root : sudo bash $0" >&2; exit 1; }
|
|
|
|
echo "==> 1/6 Dépôt dans $REPO_DIR"
|
|
install -d -o "$UTILISATEUR" -g "$UTILISATEUR" "$BASE"
|
|
if [ -d "$REPO_DIR/.git" ]; then
|
|
sudo -u "$UTILISATEUR" git -C "$REPO_DIR" pull --ff-only origin main
|
|
else
|
|
sudo -u "$UTILISATEUR" git clone "$DEPOT_URL" "$REPO_DIR"
|
|
fi
|
|
|
|
echo "==> 2/6 Scripts et journal"
|
|
install -o "$UTILISATEUR" -g "$UTILISATEUR" -m 755 "$REPO_DIR/deploiement/deploy-www.sh" "$BASE/deploy-www.sh"
|
|
install -o "$UTILISATEUR" -g "$UTILISATEUR" -m 755 "$REPO_DIR/deploiement/webhook.py" "$BASE/webhook.py"
|
|
touch "$JOURNAL" && chown "$UTILISATEUR":"$UTILISATEUR" "$JOURNAL"
|
|
|
|
echo "==> 3/6 Droit d'écriture sur $CIBLE"
|
|
# Le DocumentRoot appartient à web11 (suexec) ; 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 "==> 4/6 Secret du webhook"
|
|
if [ -f "$SECRET_FICHIER" ]; then
|
|
echo " (déjà là, inchangé)"
|
|
else
|
|
printf 'WWW_WEBHOOK_SECRET=%s\n' "$(openssl rand -hex 24)" > "$SECRET_FICHIER"
|
|
chmod 600 "$SECRET_FICHIER"
|
|
fi
|
|
|
|
echo "==> 5/6 Service systemd"
|
|
install -m 644 "$REPO_DIR/deploiement/www-webhook.service" "$UNITE"
|
|
systemctl daemon-reload
|
|
systemctl enable --now www-webhook
|
|
systemctl is-active --quiet www-webhook && echo " service actif"
|
|
|
|
echo "==> 6/6 Relais Apache /deploy"
|
|
patcher_vhost() {
|
|
local fichier="$1"
|
|
[ -f "$fichier" ] || return 0
|
|
if grep -q "127.0.0.1:9877" "$fichier"; then
|
|
echo " $fichier : déjà relayé"
|
|
return 0
|
|
fi
|
|
cp -a "$fichier" "$fichier.bak-$(date +%Y%m%d%H%M)"
|
|
# Inséré en tête du VirtualHost *:443. L'ancrage précédent — la ligne Include des
|
|
# options SSL de Let's Encrypt — n'existe que dans les vhosts écrits par certbot :
|
|
# celui qu'ISPConfig génère porte ses propres directives SSLCertificate*.
|
|
awk '
|
|
{ print }
|
|
!fait && /^[[:space:]]*<VirtualHost[^>]*:443>/ {
|
|
print "\t\tProxyPass /deploy http://127.0.0.1:9877/deploy"
|
|
print "\t\tProxyPassReverse /deploy http://127.0.0.1:9877/deploy"
|
|
fait = 1
|
|
}
|
|
' "$fichier" > "$fichier.tmp" || return 1
|
|
# Recopié dans le fichier plutôt que déplacé par-dessus : un `mv` remplacerait
|
|
# l'original par un fichier neuf, avec d'autres droits et sans son ACL.
|
|
cat "$fichier.tmp" > "$fichier" && rm -f "$fichier.tmp"
|
|
grep -q "127.0.0.1:9877" "$fichier" || { echo " ÉCHEC sur $fichier" >&2; return 1; }
|
|
echo " $fichier : relais ajouté"
|
|
}
|
|
|
|
# Sur owni, sites-enabled contient des copies et non des liens : les deux sont à traiter.
|
|
# Un vhost récalcitrant ne doit pas emporter la suite : c'est celui de sites-enabled qui
|
|
# sert, et Apache attend d'être rechargé. On note l'échec et on le dit à la fin.
|
|
manques=""
|
|
for vhost in /etc/apache2/sites-enabled/100-alpinux.org.vhost \
|
|
/etc/apache2/sites-available/alpinux.org.vhost; do
|
|
patcher_vhost "$vhost" || manques="$manques $vhost"
|
|
done
|
|
|
|
if apache2ctl configtest; then
|
|
systemctl reload apache2
|
|
else
|
|
echo "Configuration Apache invalide : rien n'a été rechargé." >&2
|
|
echo "Les sauvegardes .bak-* sont à côté des vhosts." >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$manques" ]; then
|
|
echo
|
|
echo "Relais non posé dans :$manques" >&2
|
|
echo "Le déploiement fonctionne — c'est sites-enabled qui sert — mais si ISPConfig" >&2
|
|
echo "recopie un jour le vhost par-dessus, le relais sera à remettre." >&2
|
|
fi
|
|
|
|
echo
|
|
echo "────────────────────────────────────────────────────────────"
|
|
echo "Reste à déclarer le webhook dans Gitea :"
|
|
echo " Paramètres du dépôt alpinux-www → Webhooks → Ajouter → Gitea"
|
|
echo " URL : https://alpinux.org/deploy"
|
|
echo " Méthode : POST, type de contenu : application/json"
|
|
echo " Secret : $(sed 's/^WWW_WEBHOOK_SECRET=//' "$SECRET_FICHIER")"
|
|
echo " Événement : Push seulement"
|
|
echo
|
|
echo "Puis, pour une première mise en ligne sans attendre un push :"
|
|
echo " sudo -u $UTILISATEUR $BASE/deploy-www.sh && tail -5 $JOURNAL"
|
|
echo "────────────────────────────────────────────────────────────"
|