La reconstruction du lanceur échoue avec Docker 19.03.0 en raison du paramètre réseau Docker

Avec la sortie de la version 19.03.0 de Docker, le lanceur Discourse échoue désormais au démarrage de l’instance après une reconstruction, avec le message suivant :

/usr/bin/docker: --network n'est pas une adresse MAC valide.
Voir '/usr/bin/docker run --help'.

Voici la commande exécutée (certains éléments modifiés pour des raisons de sécurité) :

+ /usr/bin/docker run --shm-size=512m -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=2 -e UNICORN_SIDEKIQS=1 -e RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 -e RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 -e RUBY_GC_HEAP_INIT_SLOTS=400000 -e RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 -e DISCOURSE_DB_SOCKET=/var/run/postgresql -e DISCOURSE_DB_HOST= -e DISCOURSE_DB_PORT= -e DISCOURSE_HOSTNAME=discourse.mydomain.com -e VIRTUAL_HOST=discourse.mydomain.com -e DISCOURSE_DEVELOPER_EMAILS=admin@mydomain.com -e DISCOURSE_SMTP_ADDRESS=mail.mydomain.com -e DISCOURSE_SMTP_PORT=587 -e DISCOURSE_SMTP_USER_NAME=discourse@mydomain.com -e DISCOURSE_SMTP_PASSWORD=MySuperDuperPass -h vps-discourse -e DOCKER_HOST_IP=172.17.0.1 --name discourse -t --expose 80 --mac-address --network reverse-proxy --network reverse-proxy local_discourse/discourse /sbin/boot
/usr/bin/docker: --network n'est pas une adresse MAC valide.
Voir '/usr/bin/docker run --help'.

Je l’utilise derrière un proxy inverse (exécuté sur le réseau nommé reverse-proxy). Cela a toujours fonctionné jusqu’à aujourd’hui. Il semble que cela attende une valeur d’adresse MAC qui n’est pas fournie.

Voyons voir…

root@endoffice-a:/var/discourse# docker --version
Docker version 19.03.0, build aeac949

Je viens d’exécuter ./launcher rebuild app et tout s’est bien passé :

+ /usr/bin/docker run --shm-size=512m -d --restart=always -e LANG=en_US.UTF-8 -e RAILS_ENV=production -e UNICORN_WORKERS=8 -e UNICORN_SIDEKIQS=1 -e RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 -e RUBY_GC_HEAP_GROWTH_MAX_SLOTS=40000 -e RUBY_GC_HEAP_INIT_SLOTS=400000 -e RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR=1.5 -e DISCOURSE_DB_SOCKET=/var/run/postgresql -e DISCOURSE_DB_HOST= -e DISCOURSE_DB_PORT= -e LETSENCRYPT_DIR=/shared/letsencrypt -e UNICORN_SIDEKIQ_MAX_RSS=1000 -e DISCOURSE_HOSTNAME=discourse.codinghorror.com -e DISCOURSE_DEVELOPER_EMAILS=jatwood@codinghorror.com -e DISCOURSE_SMTP_ADDRESS=smtp.mailgun.org -e DISCOURSE_SMTP_PORT=587 -e DISCOURSE_SMTP_USER_NAME={redacted} -e DISCOURSE_SMTP_PASSWORD={redacted} -e LETSENCRYPT_ACCOUNT_EMAIL={redacted} -e DISCOURSE_CDN_URL=https://discourse-cdn.codinghorror.com -h endoffice-a-app -e DOCKER_HOST_IP=172.17.0.1 --name app -t -p 80:80 -p 443:443 -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log --mac-address 02:72:e3:65:d5:32 local_discourse/app /sbin/boot

Notez que l’option --mac-address est bien présente et renseignée, mais que la ligne --network est spécifique à votre configuration et diffère d’une installation Discourse autonome standard.

@codinghorror Tout cela est très bien, mais si l’installation autonome standard est le seul mode de fonctionnement prévu pour Discourse, pourquoi fournir une prise en charge de la configuration de conteneur yml dans ./containers, et inclure des exemples dans ./samples ? Le fichier que j’ai utilisé est entièrement commenté avec des instructions de fonctionnement, en particulier cette section :

# any extra arguments for Docker?
# docker_args:

La seule chose que j’utilise est :

docker_args: "--network reverse-proxy"

Ce qui, encore une fois, fonctionne parfaitement depuis un an. Donc, il est évident que quelque chose a changé. Veuillez comprendre que je ne cherche pas à être conflictuel (ce serait un peu ridicule puisque je demande de l’aide), mais je tiens vraiment à souligner que j’utilise des options mises à disposition via les exemples Discourse.

Peut-être que si je comprenais comment cette adresse MAC est générée, cela pourrait m’orienter vers un problème lié à un changement d’environnement, c’est ce que j’espère.

Je vois ceci dans le lanceur :

     if [ -z "$SKIP_MAC_ADDRESS" ] ; then
      mac_address="--mac-address $($docker_path run $user_args -i --rm -a stdout -a stderr $image /bin/sh -c "echo $hostname | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'")"
     fi

Je vais analyser cela pour voir si je peux comprendre.

MISE À JOUR : En regardant cela, je vois que je peux utiliser --skip-mac-address. En faisant cela, mon instance se lance sans problème, il semble donc que le processus qui calcule l’adresse MAC soit en cause.

Donc, pour résumer. L’opération de build réussit dans tous les cas, mais lors de l’exécution de ./launcher rebuild myinstance, la dernière étape consistant à démarrer le conteneur échoue, car l’adresse MAC n’est apparemment pas définie.

Cependant, je peux simplement exécuter ./launcher start myinstance après cela, et le conteneur démarre correctement, l’adresse MAC étant alors présente. C’est étrange, c’est tout.

Je rencontre le même problème.
@codinghorror Voici les étapes pour reproduire le bug ainsi qu’une piste pour corriger cette régression :

Étapes pour reproduire :

  1. Définir dans la configuration des conteneurs (app) :
    docker_args: "--network reverse-proxy"
  2. Reconstruire
    ./launcher rebuild app
  3. Voir l’erreur
    /usr/bin/docker: --network n'est pas une adresse MAC valide

Il s’agit d’un bug introduit par le commit bfc79e7 (GitHub - discourse/discourse_docker: A Docker image for Discourse · GitHub)
merge_user_args est appelé par set_template_info, mais set_template_info est appelé deux fois lors de la reconstruction (run_run et run_bootstrap).
Ainsi, au lieu d’avoir user_args égal à $user_args $docker_args, nous avons $user_args $docker_args $docker_args.

Docker n’autorise pas la configuration du même réseau plusieurs fois.
docker: le réseau "reverse-proxy" est spécifié plusieurs fois

Merci de revenir en arrière sur ce commit ou de rendre merge_user_args idempotent.

Merci pour le travail d’enquête ! :male_detective: @saj, il semble que vous ayez cosigné ce commit avec @deargle

Voici un correctif :

Une fois ce correctif appliqué et la clé docker_args définie dans la définition du conteneur, le vecteur d’arguments final de docker run ressemble à ceci :

/usr/bin/docker run --shm-size=512m -d --restart=always -e ... -h saj-launcher-testing-app -e DOCKER_HOST_IP=172.17.0.1 --name app -t -p 80:80 -p 443:443 -v /var/discourse/shared/standalone:/shared -v /var/discourse/shared/standalone/log/var-log:/var/log --mac-address 02:07:fa:c6:c4:82 --network foonet local_discourse/app /sbin/boot

Super ! Donc, content de ne pas avoir rêvé. Merci à vous d’avoir enquêté là-dessus.