• Docker
  • Restart: always, avec condition ?

Salut,

J'ai besoin de m'assurer que des .services sont bien lancés (j'en ai 6 en cascade) avant de relancer certains containers en cas de crash/reboot. Je ne trouve rien dans la doc à ce sujet, des idées ?
La seule que j'ai c'est justement de me passer de restart: always et de relancer ces containers avec systemd. Je ne sais pas si c'est très propre...

Bonjour,

Par le passé @Hardware s'était écrit un script, peu être ça peut t aider
https://mondedie.fr/d/5822-Discussion-Securiser-son-serveur-avec-Ossec-et-Prelude/20

Peut être avec Docker exec (container), chercher si y a un .pid sinon relancer le container.

Par exemple pour le container mailserser

docker exec mailserver find / -name *.pid
/run/dovecot/master.pid
/run/clamav/freshclam.pid
/run/clamav/clamd.pid
/run/rsyslogd.pid
/run/crond.pid
/run/unbound.pid
/var/mail/postfix/spool/pid/master.pid

Sur que c 'est juste une piste à travailler mais bon une idee comme ca
Je viens de trouver ca

#nano /opt/find.sh
#!/bin/bash

for container in $(docker ps -q); do
  status=`docker exec $container ls /proc/$1 2>/dev/null`
  if [ ! -z "$status" ]; then
    name=`docker ps --filter ID=$container --format "{{.Names}}"`
    echo "PID: $1 found in $container ($name)"
    break;
  fi
done;

et ensuite

/opt/find.sh 1

Pour moi avec le mailserver ca me sort ca

root@mail:~# ./find.sh 1
PID: 1 found in 52ecbce0e5ad (rainloop)

Voilà, toujours adapté du script de @Hardware, testé et approuvé du coup je vais l'utiliser pour moi et tacher de forcer l'envoi d'un mail si cela se produit

#!/bin/bash

# A adapter en fonction des containers ... script de Hardware

CSI="\033["
CEND="${CSI}0m"
CGREEN="${CSI}1;32m"
CRED="${CSI}1;31m"

MAILSERVER_PID=$(docker inspect --format {{.State.Pid}} mailserver)
RAINLOOP_PID=$(docker inspect --format {{.State.Pid}} rainloop)

# Vérification du fonctionnement de Mailserver
if [[ $MAILSERVER_PID -gt 0 ]]; then
    echo -e "${CGREEN}[OK]${CEND} Mailserver est actuellement en service"
else
    echo -e "${CRED}[KO]${CEND} Mailserver n'est pas en service, demarrage imminent..."
    docker restart mailserver # ou docker-compose rm -fs mailserver && docker-compose up -d
fi
# Vérification du fonctionnement de Rainloop
if [[ $RAINLOOP_PID -gt 0 ]]; then
    echo -e "${CGREEN}[OK]${CEND} RAINLOOP est actuellement en service"
else
    echo -e "${CRED}[KO]${CEND} Rainloop n'est pas en service, demarrage imminent..."
    docker restart rainloop # ou docker-compose rm -fs rainloop && docker-compose up -d
fi
exit 0

voila ce que ca donne :

root@mail:/mnt/docker# docker-compose stop mailserver
Stopping mailserver ... done

puis

root@mail:~# ./find.sh
[KO] Mailserver n'est pas en service, demarrage imminent...
mailserver
[OK] RAINLOOP est actuellement en service
docker ps -a
22305550db47        hardware/mailserver:1.1-stable   "run.sh"                 24 hours ago        Up About a minute ..

A mettre en cron avec envoil mail

Apres tu peux faire la même chose pour tes services en cherchant s'il y a un pid

ps ax | grep nom du service | grep -v grep | awk '{ print $1 }'

et adapter le script

@laster13 il faut mieux utiliser le système d'healthcheck de docker pour faire ça.

Parce que ton conteneur peut très bien être démarré sans que le service à l'intérieur ne fonctionne correctement.

rainloop:
    restart: always
    image: hardware/rainloop
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8888"]
      interval: 30s 
      timeout: 10s 
      retries: 3
      start_period: 1m
    ...

Ensuite soit tu passes par un script pour redémarrer le conteneur :

#!/bin/bash

RAINLOOP_HEALTH=$(docker inspect -f '{{json .State.Health.Status}}' rainloop)

if [ "$RAINLOOP_HEALTH" != \""healthy"\" ]; then
  docker restart rainloop
fi

Soit tu utilises docker-autoheal

@Aerya j'ai pas compris ta problématique, peux-tu donner un exemple ?

Salut tous, merci de vos retours 🙂
C'est pas un processus qui je guette mais un service (via systemd). J'ai plusieurs services lancés de cette manière :

[Unit]
Description=UnionFS Daemon
Requires=plexdrive.service
After=multi-user.target plexdrive.service
RequiresMountsFor=/mnt/plexdrive

[Service]
Type=simple
User=0
Group=0
ExecStartPre=/bin/sleep 10
ExecStart=/usr/bin/unionfs -o cow,allow_other,nonempty /mnt/move=RW:/mnt/encrypt=RO /mnt/unionfs
ExecStop=/bin/fusermount -uz /mnt/unionfs
TimeoutStopSec=20
KillMode=process
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Et il arrive que ça saute ou que ça prenne du temps à se remonter. Dans ces cas-là, j'ai besoin de m'assurer que certains Dockers ne seront pas lancés avant l'exécution du service. Comme j'ai pas trouvé de variable pour Docker run etc, je pense à lancer les containers directement via systemd avec un truc du genre Requires=unionfs.service

    Aerya Je sais pas si ca peut t'aider mais mes scripts rclone et plexdrive ne sautent vraiment jamais et même lorsque je reboot ils se lancent sans problèmes liés les uns avec les autres et se montent instantanément. Par contre je ne fais pas appel à

    Requires=plexdrive.service
    RequiresMountsFor=/mnt/plexdrive

    Exemple :

    [Unit]
    Description=UnionFS Mount (plexdrive)
    AssertPathIsDirectory=/home/user/Union
    
    [Service]
    Type=forking
    User=root
    Group=root
    ExecStart=/bin/sh /home/user/scripts/unionfs.sh
    ExecStop=/bin/fusermount -uz /home/user/Union
    Restart=on-abort
    RestartSec=5
    StartLimitInterval=60s
    StartLimitBurst=3
    
    [Install]
    WantedBy=default.target

    Avec en script

    unionfs-fuse -o cow -o allow_other /home/user/Pre=RW:/home/user/Enc_GDB=RO /home/user/Union/

    plexdrive.service

    [Unit]
    Description=Plexdrive
    AssertPathIsDirectory=/mnt/plexdrive
    After=network-online.target
    
    [Service]
    Type=simple
    ExecStart=/usr/sbin/plexdrive mount -c /root/.plexdrive -o allow_other --chunk-check-threads=20 --chunk-load-ahead=4 --chunk-load-threads=20 --chunk-size=5M --refresh-interval=1m /mnt/plexdrive
    ExecStop=/bin/fusermount -u /mnt/plexdrive
    Restart=on-abort
    
    [Install]
    WantedBy=default.target

    Puisqu'on y est j'utilise également deux perles l'une pour scanner plex avec juste le fichier rajouté
    et l'autre pour supprimer les hidden-files et envoyer le tout sur gdrive :

    https://github.com/l3uddz/plex_autoscan
    https://github.com/l3uddz/unionfs_cleaner

    Avec webhook dans sonarr et radarr.

    Par contre le dossier rclone je le lance par cron au démarrage

    @reboot     /home/user/scripts/bootdrive.sh

    Bon cela dit je ne reponds pas à ta question 😋

    Edit : Comme ca il y a tout

    Plex_autoscan.service

    # /etc/systemd/system/plex_autoscan.service
    
    [Unit]
    Description=Plex Autoscan
    After=network-online.target
    
    [Service]
    User=root
    Group=root
    Type=simple
    WorkingDirectory=/opt/plex_autoscan/
    ExecStart=/opt/plex_autoscan/scan.py server
    Restart=always
    RestartSec=10
    
    [Install]
    WantedBy=default.target

    unionfs_cleaner.service

    # /etc/systemd/system/unionfs_cleaner.service
    
    [Unit]
    Description=UnionFS Cleaner
    After=network-online.target plexunion.service plexdrive.service
    
    [Service]
    User=root
    Group=root
    Type=simple
    WorkingDirectory=/opt/unionfs_cleaner/
    ExecStart=/opt/unionfs_cleaner/cleaner.py
    Restart=always
    RestartSec=10
    
    [Install]
    WantedBy=default.target
    Répondre…