Reconstrução do Launcher falha com Docker 19.03.0 devido ao parâmetro de rede do Docker

Com o lançamento da versão 19.03.0 do Docker, o launcher do Discourse agora falha ao iniciar a instância após a reconstrução, exibindo a seguinte mensagem:

/usr/bin/docker: --network não é um endereço MAC válido.
Veja '/usr/bin/docker run --help'.

Este é o comando executado (alguns itens alterados por segurança):

+ /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ão é um endereço MAC válido.
Veja '/usr/bin/docker run --help'.

Estou usando isso atrás de um proxy reverso (executando na rede chamada reverse-proxy). Sempre funcionou, até hoje. Parece que ele espera um valor de endereço MAC que não está sendo fornecido.

Vamos ver..

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

Acabei de executar ./launcher rebuild app e tudo correu bem:

+ /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

Note que --mac-address aparece e está preenchido, mas a linha --network é específica da sua configuração e difere de uma instalação padrão do Discourse em modo standalone.

@codinghorror Tudo bem e ótimo, mas se a instalação padrão independente for a única maneira pela qual o Discourse deveria operar, por que fornecer suporte à configuração de contêiner yml em ./containers e incluir exemplos disso em ./samples? O arquivo que usei está totalmente comentado com instruções de operação, especificamente nesta área:

# qualquer argumento extra para o Docker?
# docker_args:

A única coisa que estou usando é:

docker_args: "--network reverse-proxy"

O que, novamente, tem funcionado muito bem há um ano. Então, obviamente, algo mudou. Por favor, entenda que não estou tentando ser confrontador (seria meio bobo, já que estou pedindo ajuda), mas estou realmente tentando deixar claro que estou usando opções disponibilizadas nos exemplos do Discourse.

Talvez, se eu entendesse como esse endereço MAC está sendo gerado, isso pudesse me apontar para um problema de mudança de ambiente; é isso que estou esperando.

Vejo isso no launcher:

     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

Vou analisar e ver se consigo descobrir.

ATUALIZAÇÃO: E olhando isso, vejo que posso usar --skip-mac-address. Ao fazer isso, minha instância sobe normalmente, então parece que o processo que determina o endereço MAC é o problema.

Então, em resumo: a operação de build é bem-sucedida, independentemente do que aconteça. No entanto, ao executar a operação de build (./launcher rebuild myinstance), a última etapa, que é iniciar o container, falha porque o endereço MAC, de alguma forma, não foi definido.

Porém, posso simplesmente executar ./launcher start myinstance após isso e, então, ele inicia normalmente, e o endereço MAC também está presente. É estranho, é só isso.

Tenho o mesmo problema.
@codinghorror Aqui estão os passos para reproduzir e uma pista para corrigir essa regressão:

Passos para reproduzir:

  1. Configure no arquivo de configuração dos containers (app):
    docker_args: "--network reverse-proxy"
  2. Reconstrua:
    ./launcher rebuild app
  3. Veja o erro:
    /usr/bin/docker: --network não é um endereço MAC válido

É um bug introduzido pelo commit bfc79e7 (GitHub - discourse/discourse_docker: A Docker image for Discourse · GitHub)
merge_user_args é chamado por set_template_info, mas set_template_info é chamado duas vezes durante a reconstrução (run_run e run_bootstrap).
Portanto, em vez de user_args ser igual a $user_args $docker_args, temos $user_args $docker_args $docker_args.

O Docker não permite configurar a mesma rede várias vezes:
docker: a rede "reverse-proxy" foi especificada várias vezes

Obrigado por reverter este commit ou tornar merge_user_args idempotente.

Obrigado pelo trabalho de detetive! :male_detective: @saj, parece que você endossou esse commit junto com @deargle.

Aqui está um patch -

Com esse patch aplicado e a chave docker_args definida na definição do contêiner, o vetor de argumentos final do docker run fica mais ou menos assim:

/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

Legal! Então, feliz por não estar sonhando com isso. Obrigado, pessoal, por investigarem isso.