« Organigramme d'installation » : différence entre les versions
| Ligne 58 : | Ligne 58 : | ||
Au niveau du système hôte, on ajoute le script '''/root/scripts/lxc_auto_update.sh''' avec : | Au niveau du système hôte, on ajoute le script '''/root/scripts/lxc_auto_update.sh''' avec : | ||
#!/bin/bash | |||
LOG_FILE="/var/log/lxc_update.log" | LOG_FILE="/var/log/lxc_update.log" | ||
MAX_RUNS_TO_KEEP=2 | |||
RUN_START_MARKER="--- Début de l'exécution du script ---" | |||
RUN_END_MARKER="--- Fin de l'exécution du script ---" | |||
PROXY_CONTAINER="proxy" | |||
WEB_CONTAINERS=("wp" "pmb" "wiki" "tables") # Liste de tous les conteneurs web | |||
WEB_SERVICE_NAME="apache2" # Nom du service web à vérifier (adapter si nécessaire) | |||
SLEEP_AFTER_RESTART=10 # Délai après le redémarrage des conteneurs web | |||
bavarder() { | bavarder() { | ||
<nowiki> </nowiki> local message="$1" | |||
<nowiki> </nowiki> echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> "$LOG_FILE" | |||
} | } | ||
# Récupérer la liste des noms de conteneurs Alpine | <nowiki>#</nowiki> Ajouter un marqueur de début d'exécution | ||
bavarder "$RUN_START_MARKER" | |||
<nowiki>#</nowiki> Récupérer la liste des noms de conteneurs Alpine | |||
containers=$(lxc list --format csv | tail -n +2 | cut -d',' -f1) | containers=$(lxc list --format csv | tail -n +2 | cut -d',' -f1) | ||
bavarder "Liste des conteneurs récupérée : '$containers'" | bavarder "Liste des conteneurs récupérée : '$containers'" | ||
# Séparer les noms de conteneurs en un tableau | <nowiki>#</nowiki> Séparer les noms de conteneurs en un tableau | ||
IFS=$'\n' read -r -d <nowiki>''</nowiki> -a container_array <<< "$containers" | IFS=$'\n' read -r -d <nowiki>''</nowiki> -a container_array <<< "$containers" | ||
# Boucle pour lancer les mises à jour | <nowiki>#</nowiki> Boucle pour lancer les mises à jour | ||
{ | { | ||
<nowiki> </nowiki> for container in "${container_array[@]}"; do | |||
<nowiki> </nowiki> bavarder "--- Début du traitement du conteneur : '$container' ---" | |||
<nowiki> </nowiki> config=$(lxc config show "$container") | |||
<nowiki> </nowiki> if echo "$config" | grep -iq "alpine"; then | |||
<nowiki> </nowiki> bavarder "Le conteneur '$container' semble être basé sur Alpine." | |||
<nowiki> </nowiki> is_running=$(lxc list --format csv | grep "^${container}," | grep ",RUNNING,") | |||
<nowiki> </nowiki> if [ -n "$is_running" ]; then | |||
<nowiki> </nowiki> bavarder "Le conteneur '$container' est en cours d'exécution, lancement de la mise à jour..." | |||
<nowiki> </nowiki> lxc exec "$container" -- sh -c "apk update && apk upgrade --available" | |||
<nowiki> </nowiki> result=$? | |||
<nowiki> </nowiki> if [ "$result" -ne 0 ]; then | |||
<nowiki> </nowiki> bavarder "Erreur lors de la mise à jour de '$container'." | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> else | |||
<nowiki> </nowiki> bavarder "Le conteneur '$container' n'est pas en cours d'exécution, mise à jour ignorée." | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> else | |||
<nowiki> </nowiki> bavarder "Le conteneur '$container' ne semble pas être basé sur Alpine, mise à jour ignorée." | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> bavarder "--- Fin du traitement du conteneur : '$container' ---" | |||
<nowiki> </nowiki> done | |||
} >> "$LOG_FILE" 2>&1 | } >> "$LOG_FILE" 2>&1 | ||
bavarder "Fin de la tentative de mise à jour des conteneurs." | bavarder "Fin de la tentative de mise à jour des conteneurs." | ||
# Définir l'adresse e-mail pour les notifications | <nowiki>#</nowiki> --- Début du redémarrage des conteneurs Alpine (sauf le proxy) --- | ||
EMAIL_DESTINATAIRE=" | bavarder "--- Début du redémarrage des conteneurs Alpine (sauf $PROXY_CONTAINER) ---" | ||
for container in "${container_array[@]}"; do | |||
<nowiki> </nowiki> if [ "$container" != "$PROXY_CONTAINER" ]; then | |||
<nowiki> </nowiki> config=$(lxc config show "$container") | |||
<nowiki> </nowiki> if echo "$config" | grep -iq "alpine"; then | |||
<nowiki> </nowiki> is_running=$(lxc list --format csv | grep "^${container}," | grep ",RUNNING,") | |||
<nowiki> </nowiki> if [ -n "$is_running" ]; then | |||
<nowiki> </nowiki> bavarder "Redémarrage du conteneur '$container'..." | |||
<nowiki> </nowiki> lxc restart "$container" | |||
<nowiki> </nowiki> sleep "$SLEEP_AFTER_RESTART" | |||
<nowiki> </nowiki> # Vérifier l'état du service web pour les conteneurs web | |||
<nowiki> </nowiki> is_web_container=0 | |||
<nowiki> </nowiki> for web_container in "${WEB_CONTAINERS[@]}"; do | |||
<nowiki> </nowiki> if [ "$container" == "$web_container" ]; then | |||
<nowiki> </nowiki> is_web_container=1 | |||
<nowiki> </nowiki> break | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> done | |||
if [ "$is_web_container" -eq 1 ]; then | |||
<nowiki> </nowiki> service_status=$(lxc exec "$container" -- rc-service "$WEB_SERVICE_NAME" status 2>&1) | |||
<nowiki> </nowiki> if ! echo "$service_status" | grep -q "started"; then | |||
<nowiki> </nowiki> bavarder "$WEB_SERVICE_NAME ne semble pas en cours d'exécution dans '$container', tentative de démarrage..." | |||
<nowiki> </nowiki> lxc exec "$container" -- rc-service "$WEB_SERVICE_NAME" start | |||
<nowiki> </nowiki> sleep 5 | |||
<nowiki> </nowiki> service_status_after_start=$(lxc exec "$container" -- rc-service "$WEB_SERVICE_NAME" status 2>&1) | |||
<nowiki> </nowiki> if ! echo "$service_status_after_start" | grep -q "started"; then | |||
<nowiki> </nowiki> bavarder "Échec du démarrage de $WEB_SERVICE_NAME dans '$container'." | |||
<nowiki> </nowiki> else | |||
<nowiki> </nowiki> bavarder "$WEB_SERVICE_NAME démarré avec succès dans '$container'." | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> else | |||
<nowiki> </nowiki> bavarder "$WEB_SERVICE_NAME semble être en cours d'exécution dans '$container'." | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> fi | |||
<nowiki> </nowiki> fi | |||
done | |||
bavarder "--- Fin du redémarrage des conteneurs Alpine (sauf $PROXY_CONTAINER) ---" | |||
<nowiki>#</nowiki> --- Redémarrage du conteneur proxy en dernier --- | |||
bavarder "--- Début du redémarrage du conteneur proxy ($PROXY_CONTAINER) ---" | |||
is_proxy_running=$(lxc list --format csv | grep "^${PROXY_CONTAINER}," | grep ",RUNNING,") | |||
if [ -n "$is_proxy_running" ]; then | |||
<nowiki> </nowiki> bavarder "Redémarrage du conteneur proxy '$PROXY_CONTAINER'..." | |||
<nowiki> </nowiki> lxc restart "$PROXY_CONTAINER" | |||
<nowiki> </nowiki> result=$? | |||
<nowiki> </nowiki> if [ "$result" -ne 0 ]; then | |||
<nowiki> </nowiki> bavarder "Erreur lors du redémarrage du conteneur proxy '$PROXY_CONTAINER'." | |||
<nowiki> </nowiki> fi | |||
else | |||
<nowiki> </nowiki> bavarder "Le conteneur proxy '$PROXY_CONTAINER' n'est pas en cours d'exécution, redémarrage ignoré." | |||
fi | |||
bavarder "--- Fin du redémarrage du conteneur proxy ($PROXY_CONTAINER) ---" | |||
<nowiki>#</nowiki> Ajouter un marqueur de fin d'exécution | |||
bavarder "$RUN_END_MARKER" | |||
<nowiki>#</nowiki> --- Gestion de la rotation des logs --- | |||
if [ -f "$LOG_FILE" ]; then | |||
<nowiki> </nowiki> # Récupérer toutes les occurrences du marqueur de début d'exécution | |||
<nowiki> </nowiki> start_markers=$(grep -c "^$RUN_START_MARKER" "$LOG_FILE") | |||
<nowiki> </nowiki> # Calculer le nombre d'exécutions à supprimer | |||
<nowiki> </nowiki> runs_to_remove=$((start_markers - MAX_RUNS_TO_KEEP)) | |||
<nowiki> </nowiki> if [ "$runs_to_remove" -gt 0 ]; then | |||
<nowiki> </nowiki> # Utiliser awk pour ne conserver que les N dernières exécutions | |||
<nowiki> </nowiki> awk -v n="$MAX_RUNS_TO_KEEP" -v start_marker="$RUN_START_MARKER" -v end_marker="$RUN_END_MARKER" ' | |||
<nowiki> </nowiki> BEGIN { count = 0; in_run = 0; } | |||
<nowiki> </nowiki> $0 ~ start_marker { | |||
<nowiki> </nowiki> count++; | |||
<nowiki> </nowiki> if (count > (NR - RSTART) + 1 - (n * (RLENGTH ? 1 : 0))) { | |||
<nowiki> </nowiki> in_run = 1; | |||
<nowiki> </nowiki> } else { | |||
<nowiki> </nowiki> in_run = 0; | |||
<nowiki> </nowiki> print; | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> $0 ~ end_marker { | |||
<nowiki> </nowiki> if (!in_run) { | |||
<nowiki> </nowiki> print; | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> } | |||
<nowiki> </nowiki> <nowiki>!($0 ~ start_marker) && !($0 ~ end_marker) { | |||
if (!in_run) { | |||
print; | |||
} | |||
} | |||
' "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE" | |||
fi | |||
fi | |||
#</nowiki> Définir l'adresse e-mail pour les notifications | |||
EMAIL_DESTINATAIRE="domi.drey@gmail.com" # Remplace par ton adresse e-mail | |||
# Vérifier s'il y a eu des erreurs et envoyer un e-mail si c'est le cas | <nowiki>#</nowiki> Vérifier s'il y a eu des erreurs et envoyer un e-mail si c'est le cas | ||
if grep -q "Erreur" "$LOG_FILE"; then | if grep -q "Erreur" "$LOG_FILE"; then | ||
<nowiki> </nowiki> cat "$LOG_FILE" | mail -s 'Rapport de mise à jour LXC - Erreurs détectées' "$EMAIL_DESTINATAIRE" | |||
fi | fi | ||
exit 0 | exit 0 | ||
L'envoi des mails nécessite l'installation de mailutils et ssmtp : | L'envoi des mails nécessite l'installation de mailutils et ssmtp : | ||
# apt-get install mailutils ssmtp | # apt-get install mailutils ssmtp | ||
Version du 11 mai 2025 à 11:47
Les outils
Conteneur proxy : cf nginx sur alpine léger
- Création du conteneur
- Installation et configuration de nginx
- Installation de certbot pour let's encrypt
- Voir pour installer des outils de sécurité (fail2ban,...)
Conteneur Mariadb : cf mariadb sur alpinele
- Création du conteneur
- Installation de mariadb
- Configuration
- Création d'un utilisateur
Conteneur PhpMyadmin : cf phpma sur alpineLe
- Création du conteneur
- Installation d'apache2 et de phpmyadmin
- Configuration d'apache2 et de phpmyadmin
Les applis
Conteneur tables : cf tables sur alpine léger & pmb sur alpine léger pour apache2
Conteneur pmb : cf pmb sur alpine léger (historique dans pmb sur alpine lourd)
Conteneur wiki : Cf wiki (mediawiki) sur alpine léger
- Création d'un utilisateur et d'une base de donnée vide pour le wiki
- Transfert de la base de données
- Création du conteneur
- Installation du serveur web
- Installation de la nouvelle version de mediawiki
- Initialisation de l'application
- Modification de LocalSettings.php
- Récupération du contenu sur l'ancien serveur et transfert des données
- Corrections
Conteneur wp : cf wordpress sur alpine léger
mais sauter à la fin. Mariadb et phpmyadmin dans d'autres conteneurs...
Stockage et sauvegardes
création d'un volume pour les sauvegardes :
# lxc storage volume create default sauvegarde-lxc size=50GB
Montage du volume dans chaque conteneur :
# lxc config device add <nom du conteneur> sauvegarde-mount disk source=sauvegarde-lxc pool=default path=/sauvegardes
logiciel : borg sauvegarde et rétention de données. Comte chez Kiki, à pousser en ssh.
Sécurisation
Mises à jour automatiques
Installer vim-nox (coloration syntaxique), mailutils (pour l'envoi de mails).
Au niveau du système hôte, on ajoute le script /root/scripts/lxc_auto_update.sh avec :
#!/bin/bash
LOG_FILE="/var/log/lxc_update.log"
MAX_RUNS_TO_KEEP=2
RUN_START_MARKER="--- Début de l'exécution du script ---"
RUN_END_MARKER="--- Fin de l'exécution du script ---"
PROXY_CONTAINER="proxy"
WEB_CONTAINERS=("wp" "pmb" "wiki" "tables") # Liste de tous les conteneurs web
WEB_SERVICE_NAME="apache2" # Nom du service web à vérifier (adapter si nécessaire)
SLEEP_AFTER_RESTART=10 # Délai après le redémarrage des conteneurs web
bavarder() {
local message="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >> "$LOG_FILE"
}
# Ajouter un marqueur de début d'exécution
bavarder "$RUN_START_MARKER"
# Récupérer la liste des noms de conteneurs Alpine
containers=$(lxc list --format csv | tail -n +2 | cut -d',' -f1)
bavarder "Liste des conteneurs récupérée : '$containers'"
# Séparer les noms de conteneurs en un tableau
IFS=$'\n' read -r -d '' -a container_array <<< "$containers"
# Boucle pour lancer les mises à jour
{
for container in "${container_array[@]}"; do
bavarder "--- Début du traitement du conteneur : '$container' ---"
config=$(lxc config show "$container")
if echo "$config" | grep -iq "alpine"; then
bavarder "Le conteneur '$container' semble être basé sur Alpine."
is_running=$(lxc list --format csv | grep "^${container}," | grep ",RUNNING,")
if [ -n "$is_running" ]; then
bavarder "Le conteneur '$container' est en cours d'exécution, lancement de la mise à jour..."
lxc exec "$container" -- sh -c "apk update && apk upgrade --available"
result=$?
if [ "$result" -ne 0 ]; then
bavarder "Erreur lors de la mise à jour de '$container'."
fi
else
bavarder "Le conteneur '$container' n'est pas en cours d'exécution, mise à jour ignorée."
fi
else
bavarder "Le conteneur '$container' ne semble pas être basé sur Alpine, mise à jour ignorée."
fi
bavarder "--- Fin du traitement du conteneur : '$container' ---"
done
} >> "$LOG_FILE" 2>&1
bavarder "Fin de la tentative de mise à jour des conteneurs."
# --- Début du redémarrage des conteneurs Alpine (sauf le proxy) ---
bavarder "--- Début du redémarrage des conteneurs Alpine (sauf $PROXY_CONTAINER) ---"
for container in "${container_array[@]}"; do
if [ "$container" != "$PROXY_CONTAINER" ]; then
config=$(lxc config show "$container")
if echo "$config" | grep -iq "alpine"; then
is_running=$(lxc list --format csv | grep "^${container}," | grep ",RUNNING,")
if [ -n "$is_running" ]; then
bavarder "Redémarrage du conteneur '$container'..."
lxc restart "$container"
sleep "$SLEEP_AFTER_RESTART"
# Vérifier l'état du service web pour les conteneurs web
is_web_container=0
for web_container in "${WEB_CONTAINERS[@]}"; do
if [ "$container" == "$web_container" ]; then
is_web_container=1
break
fi
done
if [ "$is_web_container" -eq 1 ]; then
service_status=$(lxc exec "$container" -- rc-service "$WEB_SERVICE_NAME" status 2>&1)
if ! echo "$service_status" | grep -q "started"; then
bavarder "$WEB_SERVICE_NAME ne semble pas en cours d'exécution dans '$container', tentative de démarrage..."
lxc exec "$container" -- rc-service "$WEB_SERVICE_NAME" start
sleep 5
service_status_after_start=$(lxc exec "$container" -- rc-service "$WEB_SERVICE_NAME" status 2>&1)
if ! echo "$service_status_after_start" | grep -q "started"; then
bavarder "Échec du démarrage de $WEB_SERVICE_NAME dans '$container'."
else
bavarder "$WEB_SERVICE_NAME démarré avec succès dans '$container'."
fi
else
bavarder "$WEB_SERVICE_NAME semble être en cours d'exécution dans '$container'."
fi
fi
fi
fi
fi
done
bavarder "--- Fin du redémarrage des conteneurs Alpine (sauf $PROXY_CONTAINER) ---"
# --- Redémarrage du conteneur proxy en dernier ---
bavarder "--- Début du redémarrage du conteneur proxy ($PROXY_CONTAINER) ---"
is_proxy_running=$(lxc list --format csv | grep "^${PROXY_CONTAINER}," | grep ",RUNNING,")
if [ -n "$is_proxy_running" ]; then
bavarder "Redémarrage du conteneur proxy '$PROXY_CONTAINER'..."
lxc restart "$PROXY_CONTAINER"
result=$?
if [ "$result" -ne 0 ]; then
bavarder "Erreur lors du redémarrage du conteneur proxy '$PROXY_CONTAINER'."
fi
else
bavarder "Le conteneur proxy '$PROXY_CONTAINER' n'est pas en cours d'exécution, redémarrage ignoré."
fi
bavarder "--- Fin du redémarrage du conteneur proxy ($PROXY_CONTAINER) ---"
# Ajouter un marqueur de fin d'exécution
bavarder "$RUN_END_MARKER"
# --- Gestion de la rotation des logs ---
if [ -f "$LOG_FILE" ]; then
# Récupérer toutes les occurrences du marqueur de début d'exécution
start_markers=$(grep -c "^$RUN_START_MARKER" "$LOG_FILE")
# Calculer le nombre d'exécutions à supprimer
runs_to_remove=$((start_markers - MAX_RUNS_TO_KEEP))
if [ "$runs_to_remove" -gt 0 ]; then
# Utiliser awk pour ne conserver que les N dernières exécutions
awk -v n="$MAX_RUNS_TO_KEEP" -v start_marker="$RUN_START_MARKER" -v end_marker="$RUN_END_MARKER" '
BEGIN { count = 0; in_run = 0; }
$0 ~ start_marker {
count++;
if (count > (NR - RSTART) + 1 - (n * (RLENGTH ? 1 : 0))) {
in_run = 1;
} else {
in_run = 0;
print;
}
}
$0 ~ end_marker {
if (!in_run) {
print;
}
}
!($0 ~ start_marker) && !($0 ~ end_marker) {
if (!in_run) {
print;
}
}
' "$LOG_FILE" > "$LOG_FILE.tmp" && mv "$LOG_FILE.tmp" "$LOG_FILE"
fi
fi
# Définir l'adresse e-mail pour les notifications
EMAIL_DESTINATAIRE="domi.drey@gmail.com" # Remplace par ton adresse e-mail
# Vérifier s'il y a eu des erreurs et envoyer un e-mail si c'est le cas
if grep -q "Erreur" "$LOG_FILE"; then
cat "$LOG_FILE" | mail -s 'Rapport de mise à jour LXC - Erreurs détectées' "$EMAIL_DESTINATAIRE"
fi
exit 0
L'envoi des mails nécessite l'installation de mailutils et ssmtp :
# apt-get install mailutils ssmtp
Configuration de ssmtp :
# vi /etc/ssmtp/ssmtp.conf
# # Config file for sSMTP sendmail # # The person who gets all mail for userids < 1000 # Make this empty to disable rewriting. root=toto@monmail.fr # The place where the mail goes. The actual machine name is required no # MX records are consulted. Commonly mailhosts are named mail.domain.com mailhub=smtp.gmail.com:587 (pour gmail) # Where will the mail seem to come from? # rewriteDomain= # The full hostname hostname=raspberrypi # Are users allowed to set their own From: address? # YES - Allow the user to specify their own From: address # NO - Use the system generated From: address FromLineOverride=YES UseTLS=YES UseSTARTTLS=YES AuthUser=toto@monfournisseur.com AuthPass=MonMotdePasseDeConnection
Remarques :
- Pour gmail, il faut créer un mot de passe d'application dans les paramètre du compte google et l'utiliser ici.
- Pour que la redirection de mails fonctionne, il faut que l'adresse de destination finale soit différente de l'adresse utilisée pour l'identification pour l'envoi des mails.
On automatise l'exécution (dimache à 2h du matin) :
# crontab -e 0 2 * * 7 /root/scripts/lxc_auto_update.sh